Usos de parámetros con valores de tabla de ODBC
En este tema se describen los principales escenarios de usuario para usar parámetros con valores de tabla con ODBC:
Parámetro con valores de tabla con búferes con varias filas completamente enlazados (enviar datos como un TVP con todos los valores de la memoria)
Parámetro con valores de tabla con transmisión de filas por secuencias (enviar datos como un TVP usando datos en ejecución)
Recuperar metadatos de parámetros con valores de tabla desde el catálogo del sistema
Recuperar metadatos de parámetros con valores de tabla para una instrucción preparada
Parámetro con valores de tabla con búferes con varias filas completamente enlazados (enviar datos como un TVP con todos los valores de la memoria)
Cuando se utilizan con búferes con varias filas completamente enlazados, todos los valores de parámetro están disponibles en la memoria. Esto es típico, por ejemplo, de una transacción OLTP, en la que los parámetros con valores de tabla pueden empaquetarse en un único procedimiento almacenado. Sin parámetros con valores de tabla, esto implicaría generar dinámicamente un lote complejo de varias instrucciones o realizar varias llamadas al servidor.
El propio parámetro con valores de tabla se enlaza usando SQLBindParameter junto con los demás parámetros. Una vez enlazados todos los parámetros, la aplicación establece el atributo de foco del parámetro, SQL_SOPT_SS_PARAM_FOCUS, en cada parámetro con valores de tabla y llama a SQLBindParameter para las columnas del parámetro con valores de tabla.
El tipo de servidor de un parámetro con valores de tabla es un tipo nuevo específico de SQL Server, SQL_SS_TABLE. El tipo C de enlace para SQL_SS_TABLE debe ser siempre SQL_C_DEFAULT. No se transfiere ningún dato para el parámetro enlazado al parámetro con valores de tabla; se usa para pasar metadatos de tabla y controlar la forma de pasar datos en las columnas constituyentes del parámetro con valores de tabla.
La longitud del parámetro con valores de tabla se establece en el número de filas que se envían al servidor. El parámetro ColumnSize de SQLBindParameter para un parámetro con valores de tabla especifica el número máximo de filas que pueden enviarse; es el tamaño de matriz de los búferes de columna. ParameterValuePtr es el búfer de parámetro para un parámetro con valores de tabla de SQLBindParameter. ParameterValuePtr y su BufferLength asociada se usan para pasar el nombre de tipo del parámetro con valores de tabla cuando es necesario. El nombre de tipo no es necesario para las llamadas a procedimientos almacenados, pero sí para las instrucciones SQL.
Cuando se especifica un nombre de tipo de parámetro con valores de tabla en una llamada a SQLBindParameter, siempre debe especificarse como un valor Unicode, incluso en aplicaciones generadas como aplicaciones ANSI. Cuando especifique un nombre de tipo de parámetro con valores de tabla utilizando SQLSetDescField, puede usar un literal que se ajuste al modo de generación de la aplicación. El administrador de controladores ODBC realizará cualquier conversión Unicode que sea necesaria.
Los metadatos para los parámetros con valores de tabla y las columnas de parámetro con valores de tabla pueden manipularse individual y explícitamente utilizando SQLGetDescRec, SQLSetDescRec, SQLGetDescField y SQLSetDescField. Sin embargo, sobrecargar SQLBindParameter suele resultar más conveniente y no requiere un acceso explícito al descriptor en la mayoría de los casos. Este enfoque es coherente con la definición de SQLBindParameter para otros tipos de datos, salvo por el hecho de que para un parámetro con valores de tabla los campos descriptores afectados son ligeramente distintos.
A veces, una aplicación usa un parámetro con valores de tabla con SQL dinámico y debe proporcionarse el nombre de tipo del parámetro con valores de tabla. Si éste es el caso y el parámetro con valores de tabla no está definido en el esquema predeterminado actual para la conexión, SQL_CA_SS_TYPE_CATALOG_NAME y SQL_CA_SS_TYPE_SCHEMA_NAME deben establecerse utilizando SQLSetDescField. Dado que las definiciones de tipo de tabla y los parámetros con valores de tabla deben estar en la misma base de datos, no debe establecerse SQL_CA_SS_TYPE_CATALOG_NAME si la aplicación utiliza parámetros con valores de tabla. De lo contrario, SQLSetDescField notificará un error.
El código de ejemplo de este escenario se encuentra en el procedimiento demo_fixed_TVP_binding de Usar parámetros con valores de tabla (ODBC).
Parámetro con valores de tabla con transmisión de filas por secuencias (enviar datos como un TVP usando datos en ejecución)
En este escenario, la aplicación proporciona filas al controlador a medida que éste las solicita y se transmiten por secuencias al servidor. Esto evita tener que almacenar en el búfer todas las filas de la memoria. Es representativo de los escenarios de inserción/actualización masiva. Los parámetros con valores de tabla proporcionan un punto de rendimiento en algún lugar entre las matrices de parámetros y la copia masiva. Es decir, los parámetros con valores de tabla son casi tan fáciles de programar como las matrices de parámetros, pero proporcionan mayor flexibilidad en el servidor.
El parámetro con valores de tabla y sus columnas se enlazan tal y como se explicó en la sección anterior, Parámetro con valores de tabla con búferes con varias filas completamente enlazados, pero el indicador de longitud del propio parámetro con valores de tabla se establece en SQL_DATA_AT_EXEC. El controlador responde a SQLExecute o SQLExecuteDirect del modo habitual para parámetros de datos en ejecución, es decir, devolviendo SQL_NEED_DATA. Cuando el controlador está listo para aceptar los datos de un parámetro con valores de tabla, SQLParamData devuelve el valor de ParameterValuePtr en SQLBindParameter.
Una aplicación usa SQLPutData para que un parámetro con valores de tabla indique la disponibilidad de datos para las columnas constituyentes del parámetro con valores de tabla. Cuando se llama a SQLPutData para un parámetro con valores de tabla, DataPtr siempre debe ser NULL y StrLen_or_Ind debe ser 0 o un número menor o igual que el tamaño de matriz especificado para los búferes de parámetros con valores de tabla (el parámetro ColumnSize de SQLBindParameter). 0 significa que no hay más filas para el parámetro con valores de tabla y que el controlador pasará a procesar el siguiente parámetro de procedimiento real. Cuando el valor de StrLen_or_Ind sea distinto 0, el controlador procesará las columnas constituyentes del parámetro con valores de tabla del mismo modo que los parámetros no enlazados con parámetros con valores de tabla: cada columna de parámetro con valores de tabla puede especificar su longitud de datos real, SQL_NULL_DATA o puede especificar los datos en ejecución a través de su búfer de longitud/indicador. Es posible pasar valores de columna de parámetro con valores de tabla realizando repetidas llamadas a SQLPutData, como es habitual cuando va a pasarse un valor de carácter o binario por partes.
Cuando se han procesado todas las columnas de parámetro con valores de tabla, el controlador regresa al parámetro con valores de tabla para procesar más filas de datos de parámetro con valores de tabla. Por lo tanto, para los parámetros con valores de tabla de datos en ejecución, el controlador no sigue el examen secuencial habitual de los parámetros enlazados. Un parámetro con valores de tabla enlazado se sondeará hasta que se llame a SQLPutData con StrLen_Or_IndPtr igual a 0, momento en el cuál el controlador omitirá las columnas de parámetro con valores de tabla y pasará al siguiente parámetro real de procedimiento almacenado. Cuando SQLPutData pasa un valor de indicador mayor o igual que 1, el controlador procesa las filas y las columnas de parámetro con valores de tabla secuencialmente hasta tener valores para todas las filas y columnas enlazadas. A continuación, el controlador regresa al parámetro con valores de tabla. Entre la recepción del token para el parámetro con valores de tabla de SQLParamData y la llamada a SQLPutData(hstmt, NULL, n) para un parámetro con valores de tabla, la aplicación debe establecer los datos de las columnas constituyentes del parámetro con valores de tabla y el contenido del búfer de indicador para la fila o las filas siguientes que vayan a pasarse al servidor.
El código de ejemplo de este escenario se encuentra en la rutina demo_variable_TVP_binding de Usar parámetros con valores de tabla (ODBC).
Recuperar metadatos de parámetros con valores de tabla desde el catálogo del sistema
Cuando una aplicación llama a SQLProcedureColumns para un procedimiento que tiene parámetros de parámetro con valores de tabla, DATA_TYPE se devuelve como SQL_SS_TABLE, y TYPE_NAME es el nombre del tipo de tabla para el parámetro con valores de tabla. Se agregan dos columnas adicionales al conjunto de resultados devuelto por SQLProcedureColumns: SS_TYPE_CATALOG_NAME devuelve el nombre del catálogo donde se define el tipo de tabla del parámetro con valores de tabla y SS_TYPE_SCHEMA_NAME devuelve el nombre del esquema donde se define el tipo de tabla del parámetro con valores de tabla. De acuerdo con la especificación ODBC, SS_TYPE_CATALOG_NAME y SS_TYPE_SCHEMA_NAME aparecen antes que todas las columnas específicas del controlador agregadas en versiones anteriores de SQL Server y después de todas las columnas asignadas por el propio ODBC.
Las nuevas columnas no solo se rellenarán para los parámetros con valores de tabla, sino también para los parámetros de tipo definidos por el usuario CLR. El esquema y las columnas de catálogo existentes de los parámetros UDT también se rellenarán, pero al tener un esquema y columnas de catálogo comunes para los tipos de datos que los requieren, se simplificará el desarrollo futuro de aplicaciones. (Tenga en cuenta que las colecciones de esquemas XML son algo diferentes y no se incluyen en este cambio.)
Una aplicación usa SQLTables para determinar los nombres de los tipos de tabla de la misma manera que lo hace para las tablas persistentes, las tablas del sistema y las vistas. Se ha introducido un nuevo tipo de tabla, TABLE TYPE, para permitir que una aplicación identifique los tipos de tabla asociados a parámetros con valores de tabla. Los tipos de tabla y las tablas normales usan espacios de nombres diferentes. Esto significa que puede utilizarse el mismo nombre tanto para un tipo de tabla como para una tabla real. Para administrar esto, se ha introducido un nuevo atributo de instrucción, SQL_SOPT_SS_NAME_SCOPE. Este atributo especifica si SQLTables y otras funciones de catálogo que toman un nombre de tabla como parámetro deben interpretar el nombre de tabla como el nombre de una tabla real o como el nombre de un tipo de tabla.
Una aplicación usa SQLColumns para determinar las columnas de un tipo de tabla del mismo modo que lo hace para las tablas persistentes, pero es necesario establecer primero SQL_SOPT_SS_NAME_SCOPE para indicar que se está trabajando con tipos de tabla en lugar de con tablas reales. SQLPrimaryKeys también puede utilizarse con tipos de tabla, utilizando de nuevo SQL_SOPT_SS_NAME_SCOPE.
El código de ejemplo de este escenario se encuentra en la rutina demo_metadata_from_catalog_APIs de Usar parámetros con valores de tabla (ODBC).
Recuperar metadatos de parámetros con valores de tabla para una instrucción preparada
En este escenario, una aplicación usa SQLNumParameters y SQLDescribeParam a fin de recuperar metadatos para parámetros con valores de tabla.
El campo IPD SQL_CA_SS_TYPE_NAME se usa para recuperar el nombre de tipo del parámetro con valores de tabla. Los campos IPD SQL_CA_SS_TYPE_SCHEMA_NAME y SQL_CA_SS_TYPE_CATALOG_NAME se usan para recuperar su catálogo y su esquema, respectivamente.
Las definiciones de tipo de tabla y los parámetros con valores de tabla deben estar en la misma base de datos. SQLSetDescField notificará un error si una aplicación establece SQL_CA_SS_TYPE_CATALOG_NAME cuando se utilizan parámetros con valores de tabla.
SQL_CA_SS_TYPE_CATALOG_NAME y SQL_CA_SS_TYPE_SCHEMA_NAME también pueden utilizarse para recuperar el catálogo y el esquema asociados a parámetros de tipo definidos por el usuario CLR. SQL_CA_SS_TYPE_CATALOG_NAME y SQL_CA_SS_TYPE_SCHEMA_NAME son alternativas a los atributos existentes de esquema de catálogo específicos del tipo para tipos UDT CLR.
Una aplicación también usa SQLColumns en este escenario para recuperar metadatos de columna para un parámetro con valores de tabla porque SQLDescribeParam no devuelve metadatos para las columnas de una columna de parámetro con valores de tabla.
El código de ejemplo de este caso de uso se encuentra en la rutina demo_metadata_from_prepared_statement de Usar parámetros con valores de tabla (ODBC).