Московский государственный университет имени М.В.Ломоносова
Опубликован: 20.12.2005 | Доступ: свободный | Студентов: 3142 / 371 | Оценка: 4.22 / 3.86 | Длительность: 12:03:00
ISBN: 978-5-9556-0068-0
Лекция 5:

Параметрические запросы

< Лекция 4 || Лекция 5: 123 || Лекция 6 >

Передача параметров

Если перед выполнением функции SQLExecDirect значения параметров, используемых в запросе, не переданы на сервер, то функция возвращает код ответа SQL_NEED_DATA. Для передачи параметров в приложении могут использоваться функции SQLParamData и SQLPutData. Функция SQLParamData используется совместно с функцией SQLPutData для передачи значений параметров во время выполнения. Если функция SQLParamData возвращает значение SQL_NEED_DATA, то она также возвращает и номер параметра, для которого следует ввести значение. Передача значения параметра выполняется функцией SQLPutData.

Функция SQLParamData имеет следующее формальное описание:

SQLRETURN SQLParamData(
     SQLHSTMT     StatementHandle,
     SQLPOINTER *     ValuePtrPtr);

Параметр StatementHandle ([Input]) указывает дескриптор оператора, а параметр ValuePtrPtr ([Output]) указывает буфер, который был предназначен для хранения параметра функцией SQLBindParameter (указывается как значение параметра ParameterValuePtr ).

Функция SQLPutData позволяет приложению передавать данные параметра или столбца во время выполнения. При этом данные могут передаваться по частям.

Функция SQLPutData имеет следующее формальное описание:

SQLRETURN SQLPutData(
     SQLHSTMT     StatementHandle,
     SQLPOINTER     DataPtr,
     SQLINTEGER     StrLen_or_Ind);

Параметр StatementHandle ([Input]) указывает дескриптор оператора, параметр DataPtr ([Input]) определяет указатель буфера, в котором размещается значение параметра или столбец (значение соответствующего C-типа, указанного параметром ValueType функции SQLBindParameter или параметром TargetType функции SQLBindCol ), а параметр StrLen_or_Ind ([Input]) определяет длину передаваемых данных *DataPtr.

Следующий пример иллюстрирует применение функций OBDC API для передачи параметров, используемых оператором INSERT. Этот оператор содержит два параметра - для полей F1_ID и F2_PIC. Для каждого параметра приложение вызывает метод SQLBindParameter, определяющий С-тип данных и SQL-тип поля.

#define MAX_DATA_LEN 1024
SQLINTEGER     cbF1_ID = 0, cbF2_PICParam, cbData;
SQLUINTEGER    sF1_ID;
               szPhotoFile;
SQLPOINTER     pToken, InitValue;
SQLCHAR        Data[MAX_DATA_LEN];
SQLRETURN      retcode;
SQLHSTMT       hstmt;
     // Компиляция параметрического запроса
retcode = SQLPrepare(hstmt,
         "INSERT INTO TBL1 (F1_ID, F2_PIC) 
                    VALUES (?, ?)", SQL_NTS);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {

   // Выполнение связывания параметров. 
   // Для 2 параметра передаем в ParameterValuePtr 
   // вместо адреса буфера номер параметра 
   SQLBindParameter(hstmt, 1,    // Для 1 параметра
                    SQL_PARAM_INPUT, 
                    SQL_C_ULONG, 
                    SQL_INTEGER, 
                    0, 0, 
                    &sF1_ID, 
                    0, 
                    &cbF1_ID);
   SQLBindParameter(hstmt, 2,    // Для 2 параметра
                    SQL_PARAM_INPUT,
                    SQL_C_BINARY, 
                    SQL_LONGVARBINARY,
                    0, 0, 
                    (SQLPOINTER) 2, // Передаваемый номер
                    0, 
                    &cbF2_PICParam);

   // Значения второго параметра будут передаваться
   // во время выполнения.
   // Длина параметра в макросе SQL_LEN_DATA_AT_EXEC 
   // равна 0. Это предполагает, что драйвер вернет 
   // значение "N" для типа SQL_NEED_LONG_DATA_LEN, 
   // указанного в функции SQLGetInfo. 

   cbF2_PICParam = SQL_LEN_DATA_AT_EXEC(0);

   sF1_ID = MyGetNextID();   /* Запрос следующего значения поля  F1_ID таблицы TBL1 */

   retcode = SQLExecute(hstmt);

   /* Для параметров времени выполнения (data-at-execution parameters) вызывается 
      функция SQLParamData для получения номера параметра, установленного функцией  
      SQLBindParameter. */
   /* Вспомогательные функции  MyInitData и MyGetData формируют значение параметра*/
   /* Функция SQLParamData завершает процесс обработки параметра */

   while (retcode == SQL_NEED_DATA) {
     retcode = SQLParamData(hstmt, &pToken); // Запрос
            // значений параметров во время выполнения
      if (retcode == SQL_NEED_DATA) {         
         MyInitData((SQLSMALLINT)pToken, InitValue);
         while (MyGetData(InitValue, 
               (SQLSMALLINT)pToken, Data, &cbData))
            SQLPutData(hstmt, Data, cbData);
      }
   }
}

VOID MyInitData (sParam, InitValue)
SQLPOINTER InitValue;
{
   SQLCHAR szPhotoFile[MAX_FILE_NAME_LEN];

   /* Запрос у пользователя имени используемого BMP-файла, открытие этого файла и 
       возвращения дескриптора файла */

   MyPromptPhotoFileName(szPhotoFile);
   MyOpenBMPFile(szPhotoFile, (FILE *)InitValue);
   break;
   }

BOOL MyGetData (InitValue, sParam, Data, cbData)
SQLPOINTER     InitValue;
SQLCHAR *      Data;
SQLINTEGER *   cbData;
BOOL           Done;

{
   /* Функция MyGetNextBMPData возвращает следующую часть данных и количество 
       передаваемых байтов (не более, чем MAX_DATA_LEN). */
   Done = MyGetNextBMPData((FILE *)InitValue, Data,
         MAX_DATA_LEN, &cbData);
   if (Done) { MyCloseBMPFile((FILE *)InitValue);
              return (TRUE); }
   return (FALSE);
   }

Массивы параметров

Если значение атрибута дескриптора оператора SQL_ATTR_PARAMSET_SIZE больше 1 и SQL-оператор имеет хотя бы один маркер параметра, то функция SQLExecDirect будет выполняться последовательно для каждого значения параметра из массива, указанного параметром ParameterValuePointer функции SQLBindParameter.

< Лекция 4 || Лекция 5: 123 || Лекция 6 >