Enlace y transferencia de datos de valores de columnas y parámetros con valores de tabla

Los parámetros con valores de tabla, al igual que otros parámetros, deben enlazarse antes de pasarse al servidor. La aplicación enlaza los parámetros con valores de tabla del mismo modo que enlaza otros parámetros, es decir, mediante llamadas a SQLBindParameter o llamadas equivalentes a SQLSetDescField o SQLSetDescRec. El tipo de datos del servidor para un parámetro con valores de tabla es SQL_SS_TABLE. El tipo de C puede especificarse como SQL_C_DEFAULT o SQL_C_BINARY.

En SQL Server 2008 o posterior, solo se admiten parámetros con valores de tabla de entrada. Por lo tanto, cualquier intento de establecer SQL_DESC_PARAMETER_TYPE en un valor distinto de SQL_PARAM_INPUT devolverá SQL_ERROR con SQLSTATE = HY105 y el mensaje "Tipo de parámetro no válido".

Es posible asignar valores predeterminados a columnas completas de parámetros con valores de tabla mediante el atributo SQL_CA_SS_COL_HAS_DEFAULT_VALUE. Sin embargo, no es posible asignar valores predeterminados a valores individuales de columnas de parámetros con valores de tabla mediante el uso de SQL_DEFAULT_PARAM en StrLen_or_IndPtr con SQLBindParameter. Los parámetros con valores de tabla, en conjunto, no pueden establecerse en un valor predeterminado mediante el uso de SQL_DEFAULT_PARAM en StrLen_or_IndPtr con SQLBindParameter. Si no se siguen estas reglas, SQLExecute o SQLExecDirect devolverán SQL_ERROR. Se generará un registro de diagnóstico con SQLSTATE=07S01 y el mensaje "Uso no válido de parámetro predeterminado para el parámetro <p>", donde <p> es el ordinal del TVP en la instrucción de consulta.

Después de enlazar el parámetro con valores de tabla, la aplicación debe enlazar cada una de las columnas de parámetros con valores de tabla. Para ello, la aplicación llama primero a SQLSetStmtAttr a fin de establecer SQL_SOPT_SS_PARAM_FOCUS en el ordinal de un parámetro con valores de tabla. Después, la aplicación enlaza las columnas del parámetro con valores de tabla mediante llamadas a las rutinas siguientes: SQLBindParameter, SQLSetDescRec y SQLSetDescField. Al establecer SQL_SOPT_SS_PARAM_FOCUS en 0, se restaura el efecto usual de SQLBindParameter, SQLSetDescRec y SQLSetDescField sobre los parámetros normales de nivel superior.

No se envían ni se reciben datos reales para el propio parámetro con valores de tabla, sino que los datos se envían y se reciben para cada una de sus columnas constitutivas. Dado que el parámetro con valores de tabla es una pseudocolumna, los parámetros de SQLBindParameter se usan para hacer referencia a atributos que no son otros tipos de datos, como los siguientes:

Parámetro

Atributo relacionado para tipos de parámetro con valores que no son de tabla, incluidas columnas

Atributo relacionado para parámetros con valores de tabla

InputOutputType

SQL_DESC_PARAMETER_TYPE en IPD.

En el caso de las columnas de parámetros con valores de tabla, debe ser igual que el valor del propio parámetro con valores de tabla.

SQL_DESC_PARAMETER_TYPE en IPD.

Debe ser SQL_PARAM_INPUT.

ValueType

SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE en APD.

SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE en APD.

Debe ser SQL_C_DEFAULT o SQL_C_BINARY.

ParameterType

SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE en IPD.

SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE en IPD.

Debe ser SQL_SS_TABLE.

ColumnSize

SQL_DESC_LENGTH o SQL_DESC_PRECISION en IPD.

Depende del valor de ParameterType.

SQL_DESC_ARRAY_SIZE

También puede establecerse mediante el uso de SQL_ATTR_PARAM_SET_SIZE cuando el foco del parámetro está establecido en el parámetro con valores de tabla.

En el caso de un parámetro con valores de tabla, se trata del número de filas de los búferes de columna del parámetro con valores de tabla.

DecimalDigits

SQL_DESC_PRECISION o SQL_DESC_SCALE en IPD.

No se usa. Debe ser 0.

Si este parámetro no es 0, SQLBindParameter devolverá SQL_ERROR y se generará un registro de diagnóstico con SQLSTATE = HY104 y el mensaje "Valor de precisión o escala no válido".

ParameterValuePtr

SQL_DESC_DATA_PTR en APD.

SQL_CA_SS_TYPE_NAME.

Es opcional para las llamadas a procedimientos almacenados y puede especificarse NULL si no se requiere. Debe especificarse para las instrucciones SQL que no sean llamadas a procedimientos.

Este parámetro también actúa como un valor único que la aplicación puede usar para identificar este parámetro con valores de tabla cuando se usa el enlace de filas variable. Para obtener más información, consulte la sección "Enlace de filas variable de parámetros con valores de tabla" más adelante en este mismo tema.

Cuando se especifica un nombre de tipo de parámetro con valores de tabla en una llamada a SQLBindParameter, debe especificarse como un valor Unicode, incluso en aplicaciones generadas como aplicaciones ANSI. El valor utilizado para el parámetro StrLen_or_IndPtr debe ser SQL_NTS o la longitud de cadena del nombre multiplicada por sizeof(WCHAR).

BufferLength

SQL_DESC_OCTET_LENGTH en APD.

Longitud en bytes del nombre de tipo de parámetro con valores de tabla.

Puede ser SQL_NTS si el nombre de tipo termina en NULL, o 0 si no se requiere el nombre de tipo de parámetro con valores de tabla.

StrLen_or_IndPtr

SQL_DESC_OCTET_LENGTH_PTR en APD.

SQL_DESC_OCTET_LENGTH_PTR en APD.

En el caso de los parámetros con valores de tabla, es un recuento de filas en lugar de una longitud de datos.

Se admiten dos modos de transferencia de datos para los parámetros con valores de tabla: enlace de filas fijo y enlace de filas variable.

Enlace de filas fijo de parámetros con valores de tabla

En el caso del enlace de filas fijo, una aplicación asigna búferes (o matrices de búferes) suficientemente grandes para todos los valores posibles de columnas de entrada. La aplicación hace lo siguiente:

  1. Enlaza todos los parámetros mediante llamadas a SQLBindParameter, SQLSetDescRec o SQLSetDescField.

    1. Establece SQL_DESC_ARRAY_SIZE en el número máximo de filas que pueden transferirse para cada parámetro con valores de tabla. Esto puede realizarse en la llamada a SQLBindParameter.
  2. Llama a SQLSetStmtAttr para establecer SQL_SOPT_SS_PARAM_FOCUS en el ordinal de cada parámetro con valores de tabla.

    1. Para cada parámetro con valores de tabla, enlaza las columnas de parámetros con valores de tabla mediante llamadas a SQLBindParameter, SQLSetDescRec o SQLSetDescField.

    2. Para cada una de las columnas de parámetros con valores de tabla que vayan a tener valores predeterminados, llama a SQLSetDescField para establecer SQL_CA_SS_COL_HAS_DEFAULT_VALUE en 1.

  3. Llama a SQLSetStmtAttr para establecer SQL_SOPT_SS_PARAM_FOCUS en 0. Esto debe hacerse antes de llamar a SQLExecute o SQLExecDirect. De lo contrario, se devuelve SQL_ERROR y se genera un registro de diagnóstico con SQLSTATE=HY024 y el mensaje "Valor de atributo no válido, SQL_SOPT_SS_PARAM_FOCUS (debe ser cero en el tiempo de ejecución)".

  4. Establece StrLen_or_IndPtr o SQL_DESC_OCTET_LENGTH_PTR en SQL_DEFAULT_PARAM para un parámetro con valores de tabla sin filas, o el número de filas que va a transferirse en la siguiente llamada a SQLExecute o SQLExecDirect si el parámetro con valores de tabla tiene filas. StrLen_or_IndPtr o SQL_DESC_OCTET_LENGTH_PTR no pueden establecerse en SQL_NULL_DATA para un parámetro con valores de tabla ya que los parámetros con valores de tabla no admiten valores NULL (aunque las columnas constitutivas de los parámetros con valores de tabla pueden admitir valores NULL). Si se establece en un valor no válido, SQLExecute o SQLExecDirect devuelven SQL_ERROR y se genera un registro de diagnóstico con SQLSTATE=HY090 y el mensaje "Longitud de búfer o cadena no válida para el parámetro <p>", donde p es el número de parámetro.

  5. Llama a SQLExecute o SQLExecDirect.

Los valores de columna del parámetro con valores de tabla de entrada pueden pasarse por partes si StrLen_or_IndPtr está establecido en SQL_LEN_DATA_AT_EXEC(length) o SQL_DATA_AT_EXEC para la columna. Es similar a pasar valores por partes cuando se utilizan matrices de parámetros. Al igual que ocurre con todos los parámetros de datos en ejecución, SQLParamData no indica para qué fila de la matriz está solicitando datos el controlador; la aplicación debe tener cuidado con esto. La aplicación no puede hacer ninguna suposición sobre el orden en que el controlador solicitará los valores.

Enlace de filas variable de parámetros con valores de tabla

En el caso del enlace de filas variable, las filas se transfieren en lotes en tiempo de ejecución y la aplicación pasa las filas al controlador a petición. Es similar a los datos en ejecución para los valores de parámetro individuales. En el caso del enlace de filas variable, la aplicación hace lo siguiente:

  1. Enlaza parámetros y columnas de parámetros con valores de tabla tal y como se ha descrito en la sección anterior, "Enlace de filas fijo de parámetros con valores de tabla", en los pasos del 1 al 3.

  2. Establece StrLen_or_IndPtr o SQL_DESC_OCTET_LENGTH_PTR en SQL_DATA_AT_EXEC para cualquier parámetro con valores de tabla que vaya a pasarse en tiempo de ejecución. Si no se establece ninguno de estos valores, el parámetro se procesará tal y como se describe en la sección anterior.

  3. Llama a SQLExecute o SQLExecDirect. Esto devolverá SQL_NEED_DATA si hay algún parámetro SQL_PARAM_INPUT_OUTPUT o SQL_PARAM_INPUT que deba controlarse como parámetro de datos en ejecución. En este caso, la aplicación hace lo siguiente:

    • Llama a SQLParamData. De esta forma, se devuelve el valor de ParameterValuePtr para un parámetro de datos en ejecución y el código de retorno SQL_NEED_DATA. Cuando todos los datos del parámetro se han pasado al controlador, SQLParamData devuelve SQL_SUCCESS, SQL_SUCCESS_WITH_INFO o SQL_ERROR. En el caso de los parámetros de datos en ejecución, ParameterValuePtr, que es igual que el campo descriptor SQL_DESC_DATA_PTR, puede considerarse como un token para identificar de forma única un parámetro para el que se requiere un valor. Este "token" se pasa de la aplicación al controlador en el momento del enlace y, después, vuelve a pasarse a la aplicación en tiempo de ejecución.
  4. Para enviar datos de filas de parámetros con valores de tabla a parámetros con valores de tabla nulos, si el parámetro con valores de tabla no tiene ninguna fila, una aplicación llama a SQLPutData con StrLen_or_Ind establecido en SQL_DEFAULT_PARAM.

    Para los TVP que no son NULL, una aplicación hace lo siguiente:

    • Establece Str_Len_or_Ind para todas las columnas de parámetros con valores de tabla en los valores correspondientes y rellena los búferes de datos para las columnas de parámetros con valores de tabla que no van a ser parámetros de datos en ejecución. Puede usar los datos en ejecución para las columnas de parámetros con valores de tabla de forma similar al modo en que los parámetros ordinarios pueden pasarse por partes al controlador.

    • Llama a SQLPutData con Str_Len_or_Ind establecido en el número de filas que van a enviarse al servidor. Cualquier valor que se encuentre fuera del intervalo de 0 a SQL_DESC_ARRAY_SIZE o SQL_DEFAULT_PARAM es un error y devolverá SQLSTATE HY090 con el mensaje "Longitud de búfer o cadena no válida". 0 indica que todas las filas se han enviado y que no hay más datos para un parámetro con valores de tabla (tal y como se indica en el segundo elemento de viñeta de esta lista). SQL_DEFAULT_PARAM solamente puede utilizarse la primera vez que el controlador solicita datos para un parámetro con valores de tabla (tal y como se describe en el primer elemento de viñeta de esta lista).

  5. Cuando se han enviado todas las filas, llama a SQLPutData para el parámetro con valores de tabla con el valor de Str_Len_or_Ind establecido en 0 y continúa en el paso 3a anterior.

  6. Vuelve a llamar a SQLParamData. Si hay algún parámetro de datos en ejecución entre las columnas de parámetro con valores de tabla, el valor ValuePtrPtr devuelto por SQLParamData lo identificará. Cuando todos los valores de columna estén disponibles, SQLParamData devolverá de nuevo el valor de ParameterValuePtr para el parámetro con valores de tabla y la aplicación comenzará de nuevo.