Partilhar via


Chamando um procedimento armazenado (OLE DB)

Um procedimento armazenado pode ter zero ou mais parâmetros. Também pode retornar um valor. Ao usar o provedor OLE DB do SQL Server Native Client, os parâmetros para um procedimento armazenado podem ser transmitidos da seguinte forma:

  • Hard-coding o valor de dados.

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

ObservaçãoObservação

Ao chamar procedimentos armazenados do SQL Server que usam parâmetros denominados com o OLE DB, os nomes de parâmetros devem começar com o caractere '@'. Esta é uma restrição específica do SQL Server. O provedor OLE DB do SQL Server Native Client impõe esta restrição mais estritamente que o MDAC.

Para dar suporte aos parâmetros, a interface ICommandWithParameters é exposta no objeto de comando. Para usar parâmetros, o consumidor primeiro descreve os parâmetros para o provedor, chamando o método ICommandWithParameters::SetParameterInfo (ou, como opção, prepara uma instrução de chamada que chama o método GetParameterInfo). O consumidor cria um acessador que especifica a estrutura de um buffer e coloca os valores dos parâmetros nesse buffer. Finalmente, ele transmite o identificador do acessador e um ponteiro ao buffer para Executar. Em chamadas posteriores para Executar, o consumidor coloca novos valores de parâmetros no buffer e chama Executar com o identificador do acessador e o ponteiro do buffer.

Um comando que chama um procedimento armazenado temporário usando parâmetros deve primeiro chamar ICommandWithParameters::SetParameterInfo para definir as informações do parâmetro, para que o comando possa ser preparado com êxito. Isto ocorre porque o nome interno de um procedimento armazenado temporário difere do nome externo usado por um cliente e SQLOLEDB não pode consultar as tabelas do sistema para determinar as informações dos parâmetros para um procedimento armazenado temporário.

Estas são as etapas no processo de associação de parâmetros:

  1. Preencha as informações dos parâmetros em uma matriz de estruturas DBPARAMBINDINFO; isto é, nome do parâmetro, nome específico do provedor para o tipo de dados do parâmetro ou um nome de tipo de dados padrão, e assim por diante. Cada estrutura na matriz descreve um parâmetro. Em seguida, essa matriz é transmitida ao método SetParameterInfo.

  2. Chame o método ICommandWithParameters::SetParameterInfo para descrever parâmetros ao provedor. SetParameterInfo especifica o tipo de dados nativo de cada parâmetro. Os argumentos de SetParameterInfo são:

    • O número de parâmetros para o qual definir informações de tipo.

    • Uma matriz de ordinais de parâmetro para a qual definir informações de tipo.

    • Uma matriz de estruturas DBPARAMBINDINFO.

  3. Crie um acessador de parâmetro usando o comando IAccessor::CreateAccessor. O acessador especifica a estrutura de um buffer e coloca valores dos parâmetros no buffer. O comando CreateAccessor cria um acessador de um conjunto de associações. Essas associações são descritas pelo consumidor usando uma matriz de estruturas DBBINDING. Cada associação liga um único parâmetro ao buffer do consumidor e contém informações como:

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

    • O que é associado (o valor de dados, seu comprimento e seu status).

    • O deslocamento no buffer para cada uma destas partes.

    • O comprimento e o tipo do valor de dados, como existe no buffer do consumidor.

    Um acessador é reconhecido por seu identificador, que é do tipo HACCESSOR. Esse identificador é retornado pelo método CreateAccessor. Sempre que o consumidor termina de usar um acessador, o consumidor deve chamar o método ReleaseAccessor para liberar a memória que ele detém.

    Quando o consumidor chama um método, como ICommand::Execute, transmite o identificador a um acessador e um ponteiro para um buffer propriamente dito. O provedor usa esse acessador para determinar como transferir os dados contidos no buffer.

  4. Preencha a estrutura DBPARAMS. As variáveis do consumidor das quais os valores dos parâmetros são obtidos e nas quais os valores dos parâmetros de saída são gravados são transmitidas 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 provedor recupera dados de parâmetro de entrada e para o qual o provedor retorna dados de parâmetro de saída, de acordo com as associações especificadas pelo identificador do acessador.

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

    • O identificador do acessador criado na Etapa 3.

  5. Execute o comando usando ICommand::Execute.

Métodos de chamar um procedimento armazenado

Ao executar um procedimento armazenado no SQL Server, o provedor OLE DB do SQL Server Native Client oferece suporte para:

  • Seqüência de escape CALL do ODBC.

  • Seqüência de escape RPC (Chamada de Procedimento Remoto).

  • Instrução Transact-SQL EXECUTE.

Seqüência de escape ODBC CALL

Se você souber informações de parâmetro, chame o método ICommandWithParameters::SetParameterInfo para descrever os parâmetros ao provedor. Caso contrário, quando a sintaxe ODBC CALL for usada na chamada de um procedimento armazenado, o provedor chamará uma função auxiliar para localizar as informações de parâmetros do procedimento armazenado.

Se você não tiver certeza sobre as informações de parâmetro (metadados de parâmetro), a sintaxe do ODBC CALL será recomendada.

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

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

Por exemplo:

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

Seqüência de escape RPC

A seqüência de escape RPC é semelhante à sintaxe ODBC CALL de chamar um procedimento armazenado. Se você for chamar o procedimento várias vezes, a seqüência de escape RPC proporcionará o melhor desempenho possível entre os três métodos de chamada de um procedimento armazenado.

Quando a seqüência de escape RPC é usada para executar um procedimento armazenado, o provedor não chama nenhuma função auxiliar para determinar as informações dos parâmetros (como ela faz no caso da sintaxe de ODBC CALL). A sintaxe de RPC é mais simples que a sintaxe de ODBC CALL, assim o comando é analisado mais rápido, melhorando o desempenho. Neste caso, você precisa fornecer as informações de parâmetro executando ICommandWithParameters::SetParameterInfo.

A seqüência de escape RPC exige que você tenha um valor de retorno. Se o procedimento armazenado não retornar um valor, o servidor retornará um 0 por padrão. Além disso, você não pode abrir um cursor do SQL Server no procedimento armazenado. O procedimento armazenado é implicitamente preparado e a chamada a ICommandPrepare::Prepare falhará. Devido à impossibilidade de preparar uma chamada RPC, você não pode consultar metadados de coluna; IColumnsInfo::GetColumnInfo e IColumnsRowset::GetColumnsRowset retornarão DB_E_NOTPREPARED.

Se você souber todos os metadados de parâmetro, a seqüência de escape RPC será o modo recomendado para executar procedimentos armazenados.

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

{rpc SalesByCategory}

O CodePlex possui um aplicativo de exemplo que demonstra uma sequência de escape RPC; consulte Exemplos do Mecanismo de Banco de Dados do SQL Server para obter mais informações.

Instrução Transact-SQL EXECUTE

A seqüência de escape ODBC CALL e a seqüência de escape RPC são os métodos preferidos para chamar um procedimento armazenado no lugar da instrução EXECUTE. O provedor OLE DB do SQL Server Native Client usa o mecanismo de RPC do SQL Server para otimizar o processamento de comandos. Este protocolo de RPC aumenta o desempenho, eliminando grande parte do processamento de parâmetros e da análise da instrução feita no servidor.

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

EXECUTE SalesByCategory 'Produce', '1995'

Consulte também

Outros recursos

Histórico de alterações

Conteúdo atualizado

Link atualizado para exemplo.