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

Se aplica a:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)

Los parámetros con valores de tabla (TVP), al igual que otros parámetros, deben enlazarse antes de que se pasen al servidor. La aplicación enlaza parámetros con valores de tabla de la misma manera que enlaza otros parámetros: mediante 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 (10.0.x) 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 devuelve 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 se pueden asignar valores predeterminados individuales de parámetros con valores de tabla mediante SQL_DEFAULT_PARAM en StrLen_or_IndPtr con SQLBindParameter. Los parámetros con valores de tabla en conjunto no se pueden establecer en un valor predeterminado mediante SQL_DEFAULT_PARAM en StrLen_or_IndPtr con SQLBindParameter. Si no se siguen estas reglas, SQLExecute o SQLExecDirect devuelven SQL_ERROR. Se genera un registro de diagnóstico con SQLSTATE=07S01 y el mensaje "Uso no válido del parámetro predeterminado para el parámetro <p>", donde <p> es el ordinal del TVP en la instrucción de consulta.

Nota:

Los parámetros con valores de tabla no tienen un valor predeterminado que se puede establecer, ya que SQL_DEFAULT_PARAM indica que no hay filas. Por lo tanto, si no hay ninguna fila, no hay columnas que enlazar.

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 para establecer SQL_SOPT_SS_PARAM_FOCUS en el ordinal de un parámetro con valores de tabla. La aplicación enlaza las columnas del parámetro con valores de tabla mediante llamadas a las siguientes rutinas: SQLBindParameter, SQLSetDescRec y SQLSetDescField. Al establecer SQL_SOPT_SS_PARAM_FOCUS en 0, se restaura el efecto habitual de SQLBindParameter, SQLSetDescRec y SQLSetDescField en funcionamiento en parámetros normales de nivel superior.

Nota:

Para los controladores ODBC de Linux y Mac con unixODBC 2.3.1 a 2.3.4, al establecer el nombre de TVP a través de SQLSetDescField con el campo descriptor de SQL_CA_SS_TYPE_NAME, unixODBC no convierte automáticamente entre cadenas ANSI y Unicode según la función exacta denominada (SQLSetDescFieldA / SQLSetDescFieldW). Es necesario usar siempre SQLBindParameter o SQLSetDescFieldW con una cadena Unicode (UTF-16) para establecer el nombre de TVP.

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 pseudo columna, los parámetros de SQLBindParameter hacen referencia a atributos diferentes que otros tipos de datos, como se indica a continuación:

Parámetro Atributo relacionado para los tipos de parámetros no con valores de tabla, incluidas las 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.

Esto 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. Sin usar. Debe ser 0.

Si este parámetro no es 0, SQLBindParameter devuelve SQL_ERROR y se genera un registro de diagnóstico con SQLSTATE= HY104 y el mensaje "Precisión o escala no válidos".
ParameterValuePtr SQL_DESC_DATA_PTR en APD. SQL_CA_SS_TYPE_NAME.

Esto es opcional para las llamadas a procedimientos almacenados y se puede especificar NULL si no es necesario. Debe especificarse para las instrucciones SQL que no son llamadas a procedimiento.

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 las aplicaciones compiladas como aplicaciones ANSI. El valor usado para el parámetro StrLen_or_IndPtr debe ser SQL_NTS o la longitud de cadena del nombre multiplicada por el tamaño de (WCHAR).
BufferLength SQL_DESC_OCTET_LENGTH en APD. Longitud en bytes del nombre de tipo de parámetro con valores de tabla.

Esto puede ser SQL_NTS si el nombre del tipo termina en null o 0 si el nombre del tipo de parámetro con valores de tabla no es necesario.
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 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 se puede hacer en la llamada 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 columnas de parámetro con valores de tabla mediante llamadas SQLBindParameter, SQLSetDescRec o SQLSetDescField.

    2. Para cada columna de parámetro con valores de tabla que tenga 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 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 se van a transferir en la siguiente llamada de SQLExecute o SQLExecDirect si el parámetro con valores de tabla tiene filas. StrLen_or_IndPtr o SQL_DESC_OCTET_LENGTH_PTR no se pueden establecer en SQL_NULL_DATA para un parámetro con valores de tabla, ya que los parámetros con valores de tabla no aceptan valores NULL (aunque las columnas constituyentes de parámetros con valores de tabla pueden ser nullables). Si se establece en un valor no válido, SQLExecute o SQLExecDirect devuelve SQL_ERROR, y se genera un registro de diagnóstico con SQLSTATE=HY090 y el mensaje "Longitud de cadena o búfer no válidas para el parámetro <p>", donde p es el número de parámetro.

  5. Llama a SQLExecute o SQLExecDirect.

    Los valores de columna de parámetro con valores de tabla de entrada se pueden pasar en partes si StrLen_or_IndPtr está establecido en SQL_LEN_DATA_AT_EXEC(longitud) 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 con todos los parámetros de datos en ejecución, SQLParamData no indica la fila de la matriz para la que el controlador solicita datos; la aplicación debe encargarse de esto. La aplicación no puede realizar ninguna suposición sobre el orden en que el controlador solicita valores.

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

En el caso del enlace de fila variable, las filas se transfieren en lotes en tiempo de ejecución y la aplicación pasa 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, como se describe en los pasos 1 a 3 de la sección anterior, "Fixed Table-Valued Parameter Row Binding".

  2. Establece StrLen_or_IndPtr o SQL_DESC_OCTET_LENGTH_PTR para que los parámetros con valores de tabla se pasen en tiempo de ejecución a SQL_DATA_AT_EXEC. Si no se establece ninguno, el parámetro se procesa como se describe en la sección anterior.

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

    • Llama a SQLParamData. Esto devuelve el valor ParameterValuePtr de un parámetro data-at-execution y un código devuelto de SQL_NEED_DATA. Cuando se han pasado todos los datos de parámetros al controlador, SQLParamData devuelve SQL_SUCCESS, SQL_SUCCESS_WITH_INFO o SQL_ERROR. Para los parámetros de datos en ejecución, ParameterValuePtr, que es el mismo que el campo descriptor SQL_DESC_DATA_PTR, se puede considerar un token para identificar un parámetro para el que se requiere un valor de forma única. 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 fila de parámetros con valores de tabla para parámetros con valores de tabla null, si el parámetro con valores de tabla no tiene filas, 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 adecuados 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 se van a enviar al servidor. Cualquier valor fuera del intervalo de 0 a SQL_DESC_ARRAY_SIZE o SQL_DEFAULT_PARAM es un error y devuelve SQLSTATE HY090, con el mensaje "Cadena o longitud de búfer no válidas". 0 indica que se han enviado todas las filas y que no hay más datos para un parámetro con valores de tabla (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 un valor de Str_Len_or_Ind de 0 y, a continuación, continúa con el paso 3a anterior.

  6. Llama a SQLParamData de nuevo. Si hay algún parámetro de datos en ejecución entre las columnas de parámetros con valores de tabla, estos se identifican mediante el valor ValuePtrPtr devuelto por SQLParamData. Cuando todos los valores de columna están disponibles, SQLParamData devuelve el valor ParameterValuePtr para el parámetro con valores de tabla y la aplicación comienza de nuevo.

Pasos siguientes

Parámetros con valores de tabla ODBC