|
Программирование >> Sql: полное руководство
Если до выполнения программы число параметров неизвестно, то профамща должна передавать значения параметров с помощью области sqlda. Эта методика передачи параметров была описана ранее в настоящей главе при рассмотрении инструкции execute. В инструкции open Применяется та же методика. На рис. 18.14 изображен фрагмент программы, в котором для передачи параметров используется область sqlda. /* Программа уже сформировала и подготовила следующую инструкцию SELECT: SELECT А, В, С ... FROM SALESREPS WHERE EMPL NUM IN (?, ?, .?) с переменным числом параметров. Число параметров хранится в переменной parmcnt. SQLDA *parmda; SQLVAR *parmvar; long parm value[10] ; /* Выделить память для области SQLDA */ parmda = (SQLDA *) malloc(sizeof(SQLDA) + parmcnt * sizeof(SQLVAR)); parmda -> sqln = parmcnt; /* Запросить у пользователя значения параметров */ for (1 =0; 1 < parmcnt; i++) { printf( Введите идентификатор служащего: ); scant( %ld , &(parm value[i])); parmvar = parmda -> sqlvar + i; parmvar -> sqltype = 4 96; parmvar -> sqllen = 4; parmvar -> sqldata = &(parm value[i]); parmvar -> sqlind = 0; /* Открыть набор записей.-чтобы выполнить запрос */ exec sql open qrycursor using descriptor parmda; Рис. 18.14. Инструкция OPEN, использующая для передачи параметров область SQLDA Обратите особое внимание на то, что область sqlda, используемая в инструкции open, не имеет абсолютно ничего общего с областью sqlda, используемой в инструкциях describe и fetch: Область sqlda в инструкции open используется для передачи в СУБД значений параметров динамического запроса. Элементы массива sqlvar соответствуют маркерам параметров в тексте динамической инструкции. Область sqlda в инструкциях describe и fetch получает от СУБД описания столбцов таблицы результатов запроса и информирует СУБД о том, куда помещать извлекаемые результаты запроса. Элементы массива sqlvar соответствуют столбцам таблицы результатов запроса, создаваемой динамическим запросом. Динамическая инструкция FETCH FETCH имя набора записей USING DESCRIPTOR имя аес -риптора- Рис. 18.15 Синтаксическая диаграмма динамичеаюй инструкции FETCH Дина.мическая инструкция fetch, синтаксическая диафамма которой изображена на рис. 18.15, является разновидностью статической инстр>кции fetch. Она продвигает указатель набора записей на следующую доступную строку в таблице результатов запроса и извлекает значения ее столбцов в области данных, указанные профаммой. Вспомним (см. главу 17), что в состав статической инсфукции fetch входит предложение into со списком базовых переменных, принимающих значения столбцов. В динамической инсфукции fetch базовые переменные заменяются областью sqlda. Перед выполнением динамической инструкции fetch прикладная программа должна выделить память для приема извлекаемых данных и для переменных-индикаторов каждого столбца. Прикладная профамма должна также для каждого столбца заполнить в структуре sqlvar поля sqldata, sqlind и sqllen следующим образом: Поле sqldata должно указывать на область памяти, предназначенную для приема извлекаемых данных. Поле sqllen должно содержать размер области памяти, указанной в поле sqldata. Этот размер должен быть задан правильно, иначе СУБД будет копировать извлекаемые данные за пределы выделенной области. Поле sqlind должно указывать на переменную-индикатор столбца (двухбайтовое целое число). Если для какого-либо столбца переменная-индикатор не используется, то поле sqlind в Соответствующей сфуктуре sqlvar должно содержать ноль. Обычно прикладная профамма выделяет память для области sqlda, с помощью инструкции describe получает описание таблицы результатов запроса, выделяет память для каждого столбца таблицы и устанавливает значения полей sqldata и sqlind; все это она делает перед открытием набора записей. Та же самая область sqlda используется затем в инсфукции fetch, однако это необязательно. Необязательно также, чтобы для каждой инсфукции fetch в области sqlda указывались те Же самые области памяти. Для прикладной профаммы вполне допустимо изменять указатели в полях sqldata и sqlind (это может выполняться между двумя вызовами Инструкции fetch), извлекая две последовательные строки в разные области памяти. Динамическая инструкция CLOSE Функция, выполняемая динамической инструкцией close, и ее синтаксис идентичны функции и синтаксису статической инсфукции close, изображенной на рис. 17.28. ° обоих случаях инсфукция close прекращает доступ к таблице результатов запроса, огда профамма закрывает набор записей, созданный для динамического запроса, °на, как правило, должна также освобождать ресурсы, связанные с этим запросом. таковым относятся: область sqlda, выделенная для динамического запроса и используемая в инструкциях describe и fetch; вторая область sqlda (если она была выделена), используемая для передачи значений параметров в инструкции open; области памяти, выделенные для приема столбцов таблицы результатов запроса извлекаемых инструкцией fetch; области памяти, выделенные для переменных-индикаторов, сопровождающих столбцы таблицы результатов запроса. Эти ресурсы можно не освобождать, если программа заканчивает свою работу сразу после выполнения инструкции close. Диалекты динамического SQL в разных СУБД используются различные диалекты динамического SQL. Эти различия более серьезны, чем в случае статического SQL, так как динамический SQL в большей степени зависит от особенностей конкретной СУБД: используемых в ней типов данных, форматов данных и т.д. Вот почему невозможно написать отдельную универсальную клиентскую профамму для работы с базами данных, переносимую на различные СУБД. Такого рода профаммное обеспечение должно иметь для каждой поддерживаемой СУБД свой блок фансляции , часто называемый драйвером, с помошью которого выполняется насфойка под эту СУБД. Раньше клиентское ПО поставлялось с отдельным драйвером для каждой популярной СУБД. Появление протокола ODBC как единого профаммного интерфейса SQL упростило задачу, поскольку драйвер ODBC достаточно написать один раз для каждой СУБД, а клиентская профамма может просто вызывать функции ODBC. Однако применение такого подхода на практике означало, что профамма не могла использовать специфические особенности той или иной СУБД, что в конечном итоге приводило к снижению производительности профаммы. Поэтому современные клиентские приложения по-прежнему включают отдельные драйверы для популярных СУБД, а драйвер ODBC используется для обеспечения доступа к остальным СУБД. Подробное описание вариантов динамического SQL для всех основных типов СУБД выходит за рамки данной книги. Однако будет поучительно рассмофеть в качестве примеров диалекты динамического SQL в SQL/DS и Oracle. Динамический SQL в SQL/DS Все возможности динамического SQL, реализованные в DB2 и рассмотренные в предыдуших параграфах настояшей главы, поддерживаются и в SQL/DS, которая на протяжении многих лет была флагманской СУБД для операционной системы VM, выполнявшейся на мэйнфреймах компании IBM. Кроме того, в SQL/DS имеются дополнительные возможности, благодаря которым этот диалект получил название расширенный динамический SQL. Он позволяет писать профаммы, которые подготавливают строку инсфукции и постоянно хранят скомпилированную инсфукцию в базе данных. Скомпилированная инструкция может затем выполняться с высоким бысфодействием текушей или какой-либо другой программой без вторичной подготовки. Таким образом, расширенный динамический SQL позволяет в динамическом режиме реализовывать некоторые преимушества статического SQL. Подготовленные инструкции хранятся в модуле доступа. Он представляет собой совокупность скомпилированных инсфукций, которой присваивается имя. Пользователи SQL/DS могут иметь свои собственные наборы модулей, зашишенные привилегиями
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |