Привязка и передача данных возвращающих табличное значение параметров и значений столбцов

Параметры, возвращающие табличное значение, как и другие параметры, нуждаются в привязке до их передачи на сервер. Приложение выполняет привязку параметров, возвращающих табличное значение, точно так же, как и любых других параметров: для этого используется функция SQLBindParameter или эквивалентные этому вызовы функций SQLSetDescField или SQLSetDescRec. Типом данных на сервере для параметра, возвращающего табличное значение, является SQL_SS_TABLE. Тип C может иметь значение SQL_C_DEFAULT или SQL_C_BINARY.

В SQL Server 2008 поддерживаются только возвращающие табличные значения параметры. Поэтому любая попытка установить для SQL_DESC_PARAMETER_TYPE значение, отличное от SQL_PARAM_INPUT, приведет к возникновению ошибки SQL_ERROR с SQLSTATE = HY105 и появлению сообщения «Недопустимый тип параметра».

Можно назначать значение по умолчанию для целых столбцов параметров, возвращающих табличное значение, с помощью атрибута SQL_CA_SS_COL_HAS_DEFAULT_VALUE. Однако нельзя назначить значение по умолчанию для отдельных значений столбцов параметров, возвращающих табличное значение, с помощью атрибута SQL_DEFAULT_PARAM параметра StrLen_or_IndPtr, используя функцию SQLBindParameter. Нельзя назначить значение по умолчанию для целых столбцов параметров, возвращающих табличное значение, с помощью атрибута SQL_DEFAULT_PARAM параметра StrLen_or_IndPtr, используя функцию SQLBindParameter. Если эти правила нарушены, вызов функций SQLExecute и SQLExecDirect вернет значение SQL_ERROR. Будет создана диагностическая запись с параметром SQLSTATE=07S01 и сообщением «Недопустимое использование параметра по умолчанию для параметра <p>», где <p> — порядковый номер параметра, возвращающего табличное значение, в инструкции запроса.

После привязки параметра, возвращающего табличное значение, приложение должно выполнить привязку каждого столбца параметров, возвращающих табличное значение. Для привязки столбцов сначала вызывается метод SQLSetStmtAttr, присваивающий параметру SQL_SOPT_SS_PARAM_FOCUS порядковый номер параметра, возвращающего табличное значение. Затем приложение выполняет привязку столбцов параметров, возвращающих табличные значения, с помощью вызова следующих процедур: SQLBindParameter, SQLSetDescRec и SQLSetDescField. Присвоение атрибуту SQL_SOPT_SS_PARAM_FOCUS значения 0 восстанавливает обычное воздействие функций SQLBindParameter, SQLSetDescRec и SQLSetDescField на параметры верхнего уровня.

Для самого параметра, возвращающего табличное значение, никакие данные не передаются и не принимаются — передаются и принимаются данные для каждого из столбцов, составляющих этот параметр. Поскольку параметр, возвращающий табличное значение, представляет собой псевдостолбец, параметры функции SQLBindParameter используются для ссылок на другие атрибуты, а не другие типы данных, следующим образом:

Параметр

Связанные атрибуты для параметров, не возвращающих табличного значения, в том числе столбцов

Связанные атрибуты для возвращающих табличное значение параметров

InputOutputType

SQL_DESC_PARAMETER_TYPE в IPD.

Для столбцов параметров, возвращающих табличное значение, этот атрибут должен совпадать с настройкой для самого параметра, возвращающего табличное значение.

SQL_DESC_PARAMETER_TYPE в IPD.

Это должен быть атрибут SQL_PARAM_INPUT.

ValueType

SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE в APD.

SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE в APD.

Это должен быть атрибут SQL_C_DEFAULT или SQL_C_BINARY.

ParameterType

SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE в IPD.

SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE в IPD.

Это должен быть атрибут SQL_SS_TABLE.

ColumnSize

SQL_DESC_LENGTH или SQL_DESC_PRECISION в IPD.

Это зависит от значения ParameterType.

SQL_DESC_ARRAY_SIZE

Значение этого атрибута можно задать также с помощью атрибута SQL_ATTR_PARAM_SET_SIZE, когда фокус параметра установлен на параметр, возвращающий табличное значение.

Для параметра, возвращающего табличное значение, эта величина равна количеству строк в буферах столбцов данного параметра.

DecimalDigits

SQL_DESC_PRECISION или SQL_DESC_SCALE в IPD.

Не используется. Атрибут должен иметь значение 0.

Если этот параметр не равен 0, функция SQLBindParameter вернет значение SQL_ERROR и будет создана диагностическая запись с параметром SQLSTATE= HY104 и сообщением «Недопустимая точность или масштаб».

ParameterValuePtr

SQL_DESC_DATA_PTR в APD.

SQL_CA_SS_TYPE_NAME.

Необязательный атрибут для вызова хранимых процедур. Если значение не нужно, можно задать NULL. Для инструкций SQL, не являющихся вызовами процедур, атрибут должен быть задан.

Этот параметр также служит уникальным значением, по которому приложение может узнать конкретный параметр, возвращающий табличное значение, при использовании привязки переменной к строке. Дополнительные сведения см. в подразделе «Переменная строковая привязка параметров, возвращающих табличное значение» далее в этом разделе.

Если во время вызова SQLBindParameter указано имя типа возвращающего табличное значение параметра, это имя следует всегда задавать в Юникоде, даже в тех приложениях, которые рассчитаны на работу с кодировкой ANSI. Параметр StrLen_or_IndPtr должен содержать или строковую длину имени, умноженную на sizeof(WCHAR), или значение SQL_NTS.

BufferLength

SQL_DESC_OCTET_LENGTH в APD.

Длина имени типа параметра, возвращающего табличное значение, в байтах.

Значение может быть равно SQL_NTS, если имя типа представляет собой строку, завершающуюся нулем, или 0, если имя типа параметра, возвращающего табличное значение, не требуется.

StrLen_or_IndPtr

SQL_DESC_OCTET_LENGTH_PTR в APD.

SQL_DESC_OCTET_LENGTH_PTR в APD.

Для параметра, возвращающего табличное значение, этот атрибут хранит не длину данных, а количество строк.

Для параметров, возвращающих табличное значение, поддерживаются два режима передачи данных: фиксированная и переменная привязка строк.

Фиксированная привязка строк возвращающего табличное значение параметра

Для фиксированной привязки строк приложение выделяет буферы (или буферные массивы), достаточно большие для всех возможных значений входных столбцов. Приложение выполняет следующие действия.

  1. Выполняет привязку всех параметров с помощью функций SQLBindParameter, SQLSetDescRec или SQLSetDescField.

    1. Присваивает атрибуту SQL_DESC_ARRAY_SIZE значение максимально возможного числа рядов, которые можно передать для каждого параметра, возвращающего табличное значение. Это можно делать с помощью вызова функции SQLBindParameter.
  2. Вызывает функцию SQLSetStmtAttr для присвоения параметру SQL_SOPT_SS_PARAM_FOCUS порядкового номера каждого возвращающего табличное значение параметра.

    1. Выполняет привязку всех столбцов параметров, возвращающих табличное значение, с помощью функций SQLBindParameter, SQLSetDescRec или SQLSetDescField.

    2. Для каждого возвращающего табличное значение параметра, для которого предусмотрены значения по умолчанию, вызывает функцию SQLSetDescField, чтобы присвоить атрибуту SQL_CA_SS_COL_HAS_DEFAULT_VALUE значение 1.

  3. Вызывает функцию SQLSetStmtAttr, чтобы присвоить атрибуту SQL_SOPT_SS_PARAM_FOCUS значение 0. Это нужно сделать до того, как будет вызвана функция SQLExecute или SQLExecDirect. В противном случае функция вернет значение SQL_ERROR и будет создана диагностическая запись с параметром SQLSTATE=HY024 и сообщением «Недопустимое значение атрибута SQL_SOPT_SS_PARAM_FOCUS (атрибут должен быть равен нулю во время выполнения)».

  4. Устанавливает для атрибута StrLen_or_IndPtr или SQL_DESC_OCTET_LENGTH_PTR значение SQL_DEFAULT_PARAM, если параметр, возвращающий табличное значение, не имеет строк, а в противном случае — количество строк, которое будет передано при следующем вызове функции SQLExecute или SQLExecDirect. Нельзя присвоить параметрам StrLen_or_IndPtr и SQL_DESC_OCTET_LENGTH_PTR значение SQL_NULL_DATA для параметра, возвращающего табличное значение, так как такие параметры не допускают значения NULL (хотя столбцы, составляющие параметр с табличным значением, могут допускать значение NULL). Если этому параметру присвоено недопустимое значение, функции SQLExecute и SQLExecDirect возвращают значение SQL_ERROR и будет создана диагностическая запись с параметром SQLSTATE=HY090 и сообщением «Недопустимая длина строки или буфера для параметра <p>», где p — порядковый номер параметра.

  5. Вызывает SQLExecute или SQLExecDirect.

Значения столбцов входного параметра, возвращающего табличное значение, можно передавать по частям, если для атрибута StrLen_or_IndPtr этого столбца задано значение SQL_LEN_DATA_AT_EXEC(length) или SQL_DATA_AT_EXEC. Это похоже на передачу значений по частям при использовании массивов параметров. Как в случае с любыми параметрами типа «данные при выполнении», функция SQLParamData не указывает, для какой строки массива драйвер запрашивает данные; об этом должно заботиться приложение. Приложение не может делать никаких предположений о порядке, в котором драйвер будет запрашивать данные.

Переменная привязка строк возвращающего табличное значение параметра

Для переменной привязки строки передаются пакетами во время выполнения, и приложение передает их драйверу по запросу. Это похоже на передачу данных типа «данные при выполнении» для параметров с индивидуальными значениями. Для переменной привязки строк приложение выполняет следующие действия.

  1. Привязывает параметры и столбцы параметров, возвращающих табличное значение, как описано в шагах с 1 по 3 предыдущего раздела, «Фиксированная привязка строк возвращающего табличное значение параметра».

  2. Устанавливает для атрибута StrLen_or_IndPtr или SQL_DESC_OCTET_LENGTH_PTR значение SQL_DATA_AT_EXEC для всех возвращающих табличное значение параметров, передаваемых во время выполнения. Если ни один из указанных атрибутов не установлен, параметр будет обрабатываться, как описано в предыдущем разделе.

  3. Вызывает SQLExecute или SQLExecDirect. При наличии любых параметров типа SQL_PARAM_INPUT или SQL_PARAM_INPUT_OUTPUT, которые должны быть обработаны как «данные при выполнении», этот вызов функции вернет значение SQL_NEED_DATA. В этом случае приложение выполняет следующие действия.

    • Вызывает SQLParamData. Этот вызов вернет значение ParameterValuePtr для параметра типа «данные при выполнении» и код возврата SQL_NEED_DATA. После того как драйверу переданы все параметры, вызов SQLParamData возвращает одно из следующих значений: SQL_SUCCESS, SQL_SUCCESS_WITH_INFO или SQL_ERROR. Для параметров типа «данные при выполнении» атрибут ParameterValuePtr, совпадающий с полем дескриптора SQL_DESC_DATA_PTR, можно рассматривать как уникальный идентификатор параметра, для которого требуется значение. Этот идентификатор передается приложением драйверу во время привязки, а затем передается обратно приложению во время выполнения.
  4. Для посылки данных строк параметров, возвращающих табличное значение, если строки у параметра отсутствуют, приложение вызывает функцию SQLPutData с параметром StrLen_or_Ind, для которого задано значение SQL_DEFAULT_PARAM.

    Для параметров с табличными значениями, отличных от NULL, приложение выполняет следующие действия.

    • Устанавливает соответствующие значения для атрибутов Str_Len_or_Ind всех столбцов параметров, возвращающих табличное значение, и заполняет буферы данных тех столбцов параметров, возвращающих табличное значение, которые не относятся к типу «данные при выполнении». Тип «данные при выполнении» можно использовать для столбцов параметров, возвращающих табличное значение, подобно тому, как обычные параметры могут передаваться драйверу по частям.

    • Вызывает функцию SQLPutData с параметром Str_Len_or_Ind, содержащим количество строк, которые должны быть переданы на сервер. Любое значение, которое меньше 0 или больше SQL_DESC_ARRAY_SIZE или SQL_DEFAULT_PARAM, является ошибкой, и в этом случае вызов вернет состояние SQLSTATE HY090 с сообщением «Недопустимая длина строки или буфера». 0 означает, что все строки уже были переданы и в данном параметре, возвращающем табличное значение, данных больше нет (как указано во втором пункте данного списка). SQL_DEFAULT_PARAM можно использовать только в случае, если драйвер запрашивает данные возвращающего табличное значение параметра впервые (как описано в первом пункте данного списка).

  5. Когда все строки уже переданы, приложение вызывает для параметра, возвращающего табличное значение, функцию SQLPutData с параметром Str_Len_or_Ind, равным 0, после чего переходит к шагу 3а, описанному выше.

  6. Снова вызывает SQLParamData. Если среди столбцов параметра, возвращающего табличное значение, присутствуют параметры типа «данные при выполнении», они будут опознаны по значению ValuePtrPtr, возвращаемому функцией SQLParamData. Когда все значения столбцов будут доступны, вызов функции SQLParamData снова вернет значение ParameterValuePtr для возвращающего табличное значение параметра и приложение начнет весь процесс заново.