Procedimentos Armazenados - Chamar um Cliente Nativo do SQL Server

Aplica-se a:SQL ServerBase de Dados SQL do AzureInstância Gerida do Azure SQLAzure Synapse Analytics

Importante

O SQL Server Native Client (geralmente abreviado SNAC) foi removido do SQL Server 2022 (16.x) e do SQL Server Management Studio 19 (SSMS). O provedor OLE DB do SQL Server Native Client (SQLNCLI ou SQLNCLI11) e o provedor Microsoft OLE DB herdado para SQL Server (SQLOLEDB) não são recomendados para novos desenvolvimentos. Mude para o novo Microsoft OLE DB Driver (MSOLEDBSQL) para SQL Server daqui em diante.

Um procedimento armazenado pode ter parâmetros zero ou mais. Também pode devolver um valor. Ao utilizar o fornecedor OLE DB do SQL Server Native Client, os parâmetros de um procedimento armazenado podem ser passados por:

  • Codificação fixa do valor dos dados.

  • Usar um marcador de parâmetro (?) para especificar parâmetros, associar uma variável de programa ao marcador de parâmetros e depois colocar o valor dos dados na variável de programa.

Note

Ao chamar procedimentos armazenados SQL Server usando parâmetros nomeados com OLE DB, os nomes dos parâmetros devem começar com o carácter '@'. Isto é uma restrição específica do SQL Server. O fornecedor SQL Server Native Client OLE DB aplica esta restrição de forma mais rigorosa do que o MDAC.

Para suportar parâmetros, a interface ICommandWithParameters é exposta no objeto de comando. Para usar parâmetros, o consumidor descreve primeiro os parâmetros ao fornecedor chamando o método ICommandWithParameters::SetParameterInfo (ou, opcionalmente, prepara uma instrução de chamada que chama o método GetParameterInfo ). O consumidor cria então um acessório que especifica a estrutura de um buffer e coloca valores de parâmetros nesse buffer. Finalmente, passa o handle do acessor e um ponteiro para o buffer para Executar. Em chamadas posteriores para Execute, o consumidor coloca novos valores de parâmetros no buffer e chama Execute com o handler do acessor e o ponteiro do buffer.

Um comando que chama um procedimento armazenado temporário usando parâmetros deve primeiro chamar ICommandWithParameters::SetParameterInfo para definir a informação dos parâmetros, antes de o comando poder ser preparado com sucesso. Isto deve-se ao facto de o nome interno de um procedimento armazenado temporário diferir do nome externo usado por um cliente e o SQLOLEDB não conseguir consultar as tabelas do sistema para determinar a informação dos parâmetros para um procedimento armazenado temporário.

Estes são os passos no processo de ligação de parâmetros:

  1. Preencher a informação dos parâmetros num array de estruturas DBPARAMBINDINFO; ou seja, nome do parâmetro, nome específico do fornecedor para o tipo de dado do parâmetro ou um nome de tipo de dado padrão, e assim sucessivamente. Cada estrutura no array descreve um parâmetro. Este array é então passado para o método SetParameterInfo .

  2. Ligue para o método ICommandWithParameters::SetParameterInfo para descrever os parâmetros ao fornecedor. O SetParameterInfo especifica o tipo de dado nativo de cada parâmetro. Os argumentos do SetParameterInfo são:

    • O número de parâmetros para definir a informação do tipo.

    • Um array de ordinais de parâmetros para definir a informação do tipo.

    • Um conjunto de estruturas DBPARAMBINDINFO.

  3. Crie um acessório de parâmetros usando o comando IAccessor::CreateAccessor . O acessor especifica a estrutura de um buffer e coloca valores de parâmetros no buffer. O comando CreateAccessor cria um acessor a partir de um conjunto de bindings. Estas ligações são descritas pelo consumidor através de um array de estruturas DBBINDING. Cada ligação associa um único parâmetro ao buffer do consumidor e contém informações como:

    • O ordinal do parâmetro ao qual a ligação se aplica.

    • O que está limitado (o valor dos dados, o seu comprimento e o seu estado).

    • O deslocamento no buffer para cada uma destas peças.

    • O comprimento e o tipo do valor dos dados tal como existem no buffer do consumidor.

    Um acessório é identificado pela sua pega, que é do tipo HACCESSOR. Este handle é devolvido pelo método CreateAccessor . Sempre que o consumidor termina de usar um acessório, deve chamar o método ReleaseAccessor para libertar a memória que detém.

    Quando o consumidor chama um método, como ICommand::Execute, ele passa o handle para um acessor e um ponteiro para o próprio buffer. O fornecedor utiliza este acessório para determinar como transferir os dados contidos no buffer.

  4. Preenche a estrutura DBPARAMS. As variáveis de consumo a partir das quais são retirados os valores dos parâmetros de entrada e para os quais são escritos os valores dos parâmetros de saída são passadas em tempo de execução para ICommand::Execute na estrutura DBPARAMS. A estrutura DBPARAMS inclui três elementos:

    • Um ponteiro para o buffer do qual o fornecedor recupera dados dos parâmetros de entrada e para o qual o fornecedor retorna dados dos parâmetros de saída, de acordo com as ligações especificadas pelo handler do acessório.

    • O número de conjuntos de parâmetros no buffer.

    • O handler do acessório criado no Passo 3.

  5. Execute o comando usando ICommand::Execute.

Métodos de Chamar um Procedimento Armazenado

Ao executar um procedimento armazenado no SQL Server, o fornecedor OLE DB do SQL Server Native Client suporta o:

  • Sequência de escape ODBC CALL.

  • Sequência de escape de chamada remota de procedimento (RPC).

  • Transact-SQL declaração EXECUTAR.

Sequência de Escape ODBC CALL

Se souber informações de parâmetros, ligue para o método ICommandWithParameters::SetParameterInfo para descrever os parâmetros ao fornecedor. Caso contrário, quando a sintaxe ODBC CALL é usada para chamar um procedimento armazenado, o fornecedor chama uma função auxiliar para encontrar a informação dos parâmetros do procedimento armazenado.

Se não tiver a certeza da informação dos parâmetros (metadados dos parâmetros), recomenda-se a sintaxe ODBC CALL.

A sintaxe geral para chamar um procedimento usando a sequência de escape ODBC CALL é:

{[?=]chamarprocedure_name[([parâmetro][,[parâmetro]]... )]}

Por exemplo:

{call SalesByCategory('Produce', '1995')}  

Sequência de Fuga RPC

A sequência de escape RPC é semelhante à sintaxe ODBC CALL, que chama um procedimento armazenado. Se chamar o procedimento várias vezes, a sequência de escape RPC oferece o desempenho mais ótimo entre os três métodos de chamada a um procedimento armazenado.

Quando a sequência de escape RPC é usada para executar um procedimento armazenado, o fornecedor não chama nenhuma função auxiliar para determinar a informação do parâmetro (como acontece no caso da sintaxe ODBC CALL). A sintaxe RPC é mais simples do que a sintaxe ODBC CALL, pelo que o comando é analisado mais rapidamente, melhorando o desempenho. Neste caso, precisa de fornecer a informação dos parâmetros executando ICommandWithParameters::SetParameterInfo.

A sequência de escape RPC exige que tenhas um valor de retorno. Se o procedimento armazenado não devolver um valor, o servidor devolve um 0 por defeito. Além disso, não pode abrir um cursor do SQL Server sobre o procedimento armazenado. O procedimento armazenado é preparado implicitamente e a chamada para ICommandPrepare::P repare falhará. Devido à incapacidade de preparar uma chamada RPC, não é possível consultar metadados das colunas; IColumnsInfo::GetColumnInfo e IColumnsRowset::GetColumnsRowset vão devolver DB_E_NOTPREPARED.

Se souber todos os metadados dos parâmetros, a sequência de escape RPC é a forma recomendada de executar procedimentos armazenados.

Este é um exemplo de sequência de escape RPC para chamar um procedimento armazenado:

{rpc SalesByCategory}  

Para uma aplicação de exemplo que demonstra uma sequência de escape RPC, veja Executar um Procedimento Armazenado (Usando Sintaxe RPC) e Códigos de Retorno de Processos e Parâmetros de Saída (OLE DB).

Transact-SQL Instrução EXECUTE

A sequência de escape ODBC CALL e a sequência de escape RPC são os métodos preferidos para chamar um procedimento armazenado em vez da instrução EXECUT . O fornecedor do SQL Server Native Client OLE DB utiliza o mecanismo RPC do SQL Server para otimizar o processamento de comandos. Este protocolo RPC aumenta o desempenho ao eliminar grande parte do processamento de parâmetros e análise de instruções realizado no servidor.

Este é um exemplo da instrução EXECUTE Transact-SQL:

EXECUTE SalesByCategory 'Produce', '1995'