Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Este tópico discute os principais cenários de usuário para usar parâmetros com valor de tabela com ODBC:
parâmetro Table-Valued com buffers de várias linhas totalmente associados (enviar dados como um TVP com todos os valores na memória)
parâmetro Table-Valued com streaming de linha (enviar dados como um TVP usandoAt-Executionde dados)
Recuperando metadados de parâmetro Table-Valued do catálogo do sistema
Recuperando metadados de parâmetro Table-Valued para uma instrução preparada
parâmetro Table-Valued com buffers de várias linhas totalmente associados (enviar dados como um TVP com todos os valores na memória)
Quando usados com buffers de várias linhas totalmente associados, todos os valores de parâmetro estão disponíveis na memória. Isso é típico, por exemplo, de uma transação OLTP, na qual parâmetros com valor de tabela podem ser empacotados em um único procedimento armazenado. Sem parâmetros com valor de tabela, isso envolveria gerar um lote complexo de várias instruções dinamicamente ou fazer várias chamadas para o servidor.
O parâmetro com valor de tabela em si é associado usando SQLBindParameter juntamente com os outros parâmetros. Depois que todos os parâmetros tiverem sido associados, o aplicativo define o atributo de foco do parâmetro, SQL_SOPT_SS_PARAM_FOCUS, em cada parâmetro com valor de tabela e chama SQLBindParameter para as colunas do parâmetro com valor de tabela.
O tipo de servidor para um parâmetro com valor de tabela é um novo tipo específico do SQL Server, SQL_SS_TABLE. O tipo C de associação para SQL_SS_TABLE sempre deve ser SQL_C_DEFAULT. Nenhum dado é transferido para o parâmetro associado de parâmetro com valor de tabela; ele é usado para passar metadados de tabela e para controlar como passar dados nas colunas constituintes do parâmetro com valor de tabela.
O comprimento do parâmetro com valor de tabela é definido como o número de linhas que estão sendo enviadas para o servidor. O parâmetro ColumnSize de SQLBindParameter para um parâmetro com valor de tabela especifica o número máximo de linhas que podem ser enviadas; esse é o tamanho da matriz dos buffers de coluna. ParameterValuePtr é o buffer de parâmetro para um parâmetro com valor de tabela no SQLBindParameter. ParameterValuePtr e seu BufferLength associados são usados para passar o nome do tipo do parâmetro com valor de tabela quando necessário. O nome do tipo não é necessário para chamadas de procedimento armazenado, mas é necessário para instruções SQL.
Quando um nome de tipo de parâmetro com valor de tabela é especificado em uma chamada para SQLBindParameter, ele sempre deve ser especificado como um valor Unicode, mesmo em aplicativos criados como aplicativos ANSI. Ao especificar um nome de tipo de parâmetro com valor de tabela usando SQLSetDescField, você pode usar um literal que esteja em conformidade com a forma como o aplicativo é criado. O Gerenciador do Driver ODBC executará todas as conversões de Unicode necessárias.
Metadados para parâmetros com valor de tabela e colunas de parâmetro com valor de tabela podem ser manipulados individual e explicitamente usando SQLGetDescRec, SQLSetDescRec, SQLGetDescField e SQLSetDescField. No entanto, sobrecarregar SQLBindParameter geralmente é mais conveniente e não requer acesso explícito ao descritor na maioria dos casos. Essa abordagem é consistente com a definição de SQLBindParameter para outros tipos de dados, exceto que, para um parâmetro com valor de tabela, os campos de descritor afetados são ligeiramente diferentes.
Às vezes, um aplicativo usa um parâmetro com valor de tabela com SQL dinâmico e o nome do tipo do parâmetro com valor de tabela deve ser fornecido. Se esse for o caso e o parâmetro com valor de tabela não estiver definido no esquema padrão atual para a conexão, SQL_CA_SS_TYPE_CATALOG_NAME e SQL_CA_SS_TYPE_SCHEMA_NAME deverão ser definidos usando SQLSetDescField. Como definições de tipo de tabela e parâmetros com valor de tabela devem estar no mesmo banco de dados, SQL_CA_SS_TYPE_CATALOG_NAME não deve ser definido se o aplicativo usa parâmetros com valor de tabela. Caso contrário, SQLSetDescField relatará um erro.
O código de exemplo para esse cenário está no procedimento demo_fixed_TVP_binding em Usar parâmetros de Table-Valued (ODBC).
parâmetro Table-Valued com streaming de linha (enviar dados como um TVP usandoAt-Executionde dados)
Nesse cenário, o aplicativo fornece linhas para o driver conforme ele as solicita e elas são transmitidas para o servidor. Isso evita ter que armazenar em buffer todas as linhas na memória. Isso representa cenários de inserção/atualização em massa. Parâmetros com valor de tabela fornecem um ponto de desempenho em algum lugar entre matrizes de parâmetros e cópia em massa. Ou seja, os parâmetros com valor de tabela são tão fáceis de programar quanto matrizes de parâmetros, mas fornecem maior flexibilidade no servidor.
O parâmetro com valor de tabela e suas colunas são associados conforme discutido na seção anterior, parâmetro Table-Valued com buffers de multilinha totalmente associados, mas o indicador de comprimento do próprio parâmetro com valor de tabela está definido como SQL_DATA_AT_EXEC. O driver responde a SQLExecute ou SQLExecuteDirect da maneira usual para parâmetros de dados em execução, ou seja, retornando SQL_NEED_DATA. Quando o driver estiver pronto para aceitar dados para um parâmetro com valor de tabela, SQLParamData retornará o valor de ParameterValuePtr em SQLBindParameter.
Um aplicativo usa SQLPutData para um parâmetro com valor de tabela para indicar a disponibilidade de dados para colunas constituintes de parâmetro com valor de tabela. Quando SQLPutData é chamado para um parâmetro com valor de tabela, DataPtr sempre deve ser nulo e StrLen_or_Ind deve ser 0 ou um número menor ou igual ao tamanho da matriz especificado para buffers de parâmetro com valor de tabela (o parâmetro ColumnSize de SQLBindParameter). 0 significa que não há mais linhas para o parâmetro com valor de tabela e o driver continuará a processar para o próximo parâmetro de procedimento real. Quando StrLen_or_Ind não for 0, o driver processará as colunas constituintes de parâmetro com valor de tabela da mesma forma que os parâmetros associados a parâmetros com valor de tabela: cada coluna de parâmetro com valor de tabela pode especificar seu comprimento de dados real, SQL_NULL_DATA ou pode especificar dados em execução por meio de seu buffer de comprimento/indicador. Valores de coluna de parâmetro com valor de tabela podem ser passados por chamadas repetidas para SQLPutData, como de costume, quando um valor binário ou caractere deve ser passado em partes.
Quando todas as colunas de parâmetro com valor de tabela tiverem sido processadas, o driver retornará ao parâmetro com valor de tabela para processar outras linhas de dados de parâmetro com valor de tabela. Portanto, para parâmetros com valor de tabela de dados em execução, o driver não segue a verificação sequencial usual de parâmetros associados. Um parâmetro com valor de tabela associado será sondado até que SQLPutData seja chamado com StrLen_Or_IndPtr igual a 0, momento em que o driver ignora colunas de parâmetro com valor de tabela e passa para o próximo parâmetro de procedimento armazenado real. Quando SQLPutData passa um valor de indicador maior ou igual a 1, o driver processa colunas e linhas de parâmetro com valor de tabela sequencialmente até que ele tenha valores para todas as linhas e colunas associadas. Em seguida, o driver retorna ao parâmetro com valor de tabela. Entre receber o token para o parâmetro com valor de tabela do SQLParamData e chamar SQLPutData(hstmt, NULL, n) para um parâmetro com valor de tabela, o aplicativo deve definir dados de coluna constituinte de parâmetro com valor de tabela e conteúdo de buffer indicador para a próxima linha ou linhas a serem passadas para o servidor.
O código de exemplo para esse cenário está na rotina demo_variable_TVP_binding em Usar parâmetros de Table-Valued (ODBC).
Recuperando metadados de parâmetro Table-Valued do catálogo do sistema
Quando um aplicativo chama SQLProcedureColumns para um procedimento que tem parâmetros de parâmetro com valor de tabela, DATA_TYPE é retornado como SQL_SS_TABLE e TYPE_NAME é o nome do tipo de tabela para o parâmetro com valor de tabela. Duas colunas adicionais são adicionadas ao conjunto de resultados retornado por SQLProcedureColumns: SS_TYPE_CATALOG_NAME retorna o nome do catálogo em que o tipo de tabela do parâmetro de valor de tabela é definido e SS_TYPE_SCHEMA_NAME retorna o nome do esquema em que o tipo de tabela do parâmetro de valor de tabela é definido. Em conformidade com a especificação ODBC, SS_TYPE_CATALOG_NAME e SS_TYPE_SCHEMA_NAME aparecem antes de todas as colunas específicas do driver que foram adicionadas em versões anteriores do SQL Server e depois de todas as colunas exigidas pelo próprio ODBC.
As novas colunas serão preenchidas não apenas para parâmetros com valor de tabela, mas também para parâmetros de tipo clr definidos pelo usuário. As colunas de esquema e catálogo existentes de parâmetros UDT ainda serão preenchidas, mas ter colunas comuns de esquema e catálogo para tipos de dados que os exigem simplificará o desenvolvimento de aplicativos no futuro. (Observe que as coleções de esquema XML são um pouco diferentes e não estão incluídas nesta alteração.)
Um aplicativo usa SQLTables para determinar os nomes de tipos de tabela da mesma forma que faz para tabelas persistentes, tabelas do sistema e exibições. Um novo tipo de tabela, TABLE TYPE, é introduzido para permitir que um aplicativo identifique tipos de tabela associados a parâmetros com valor de tabela. Tipos de tabela e tabelas regulares usam namespaces diferentes. Isso significa que você pode usar o mesmo nome para um tipo de tabela e uma tabela real. Para lidar com isso, um novo atributo de instrução, SQL_SOPT_SS_NAME_SCOPE, foi introduzido. Esse atributo especifica se SQLTables e outras funções de catálogo que tomam um nome de tabela como um parâmetro devem interpretar o nome da tabela como o nome de uma tabela real ou o nome de um tipo de tabela.
Um aplicativo usa SQLColumns para determinar as colunas de um tipo de tabela da mesma forma que faz para tabelas persistentes, mas deve primeiro definir SQL_SOPT_SS_NAME_SCOPE para indicar que está trabalhando com tipos de tabela em vez de tabelas reais. SQLPrimaryKeys também pode ser usado com tipos de tabela, novamente usando SQL_SOPT_SS_NAME_SCOPE.
O código de exemplo para esse cenário está na rotina demo_metadata_from_catalog_APIs em Usar parâmetros de Table-Valued (ODBC).
Recuperando metadados de parâmetro Table-Valued para uma instrução preparada
Nesse cenário, um aplicativo usa SQLNumParameters e SQLDescribeParam para recuperar metadados para parâmetros com valor de tabela.
O campo IPD SQL_CA_SS_TYPE_NAME é usado para recuperar o nome do tipo para o parâmetro com valor de tabela. Os campos IPD SQL_CA_SS_TYPE_SCHEMA_NAME e SQL_CA_SS_TYPE_CATALOG_NAME são usados para recuperar seu catálogo e esquema, respectivamente.
Definições de tipo de tabela e parâmetros com valor de tabela devem estar no mesmo banco de dados. SQLSetDescField relatará um erro se um aplicativo definir SQL_CA_SS_TYPE_CATALOG_NAME ao usar parâmetros com valor de tabela.
Também é possível usar SQL_CA_SS_TYPE_CATALOG_NAME e SQL_CA_SS_TYPE_SCHEMA_NAME para recuperar o catálogo e o esquema associados com parâmetros de tipo definido pelo usuário CLR. SQL_CA_SS_TYPE_CATALOG_NAME e SQL_CA_SS_TYPE_SCHEMA_NAME são alternativas aos atributos de esquema de catálogo específicos do tipo existente para tipos UDT clr.
Um aplicativo usa SQLColumns para recuperar metadados de coluna para um parâmetro com valor de tabela nesse cenário também, porque SQLDescribeParam não retorna metadados para as colunas de uma coluna de parâmetro com valor de tabela.
O código de exemplo para esse caso de uso está na rotina demo_metadata_from_prepared_statement em Usar parâmetros de Table-Valued (ODBC).