O acesso a conjuntos de resultados a partir de procedimentos Armazenados Transact-SQL do SQL Server

StackOverflow https://stackoverflow.com/questions/58940

  •  09-06-2019
  •  | 
  •  

Pergunta

Eu estou usando o SQL Server 2005, e gostaria de saber como acessar diferentes conjuntos de resultados a partir de dentro de transact-sql.O seguinte procedimento armazenado retorna dois conjuntos de resultados, como faço para acessá-los a partir de, por exemplo, de outro procedimento armazenado?

CREATE PROCEDURE getOrder (@orderId as numeric) AS
BEGIN   
    select order_address, order_number from order_table where order_id = @orderId
    select item, number_of_items, cost from order_line where order_id = @orderId
END

Eu preciso ser capaz de iterar através de dois conjuntos de resultados individualmente.

EDITAR:Só para esclarecer a questão, eu quero testar os procedimentos armazenados.Eu tenho um conjunto de procedimentos armazenados que são utilizados a partir de um VB.NET cliente, que retornar vários conjuntos de resultados.Estes não vão ser alterado para uma função com valor de tabela, não pode de fato mudar os procedimentos em todos os.Alterar o procedimento não é uma opção.

Os conjuntos de resultados retornados por procedimentos não são os mesmos tipos de dados ou o número de colunas.

Foi útil?

Solução

A resposta curta é:você não pode fazer isso.

A partir de T-SQL não há nenhuma maneira de aceder a vários resultados de uma chamada de procedimento armazenado aninhado, sem alterar o procedimento armazenado como outros têm sugerido.

Para ser completa, se o procedimento estavam retornando de um único resultado, você pode inseri-lo em uma tabela temporária ou variável de tabela com a seguinte sintaxe:

INSERT INTO #Table (...columns...)
EXEC MySproc ...parameters...

Você pode usar a mesma sintaxe para um procedimento que retorna vários resultados, mas só o processo o primeiro resultado, o resto vai ser descartados.

Outras dicas

Eu era facilmente capaz de fazer isso criando um SQL2005 procedimento CLR armazenado que contém um conjunto de dados interno.

Você vê, um novo SqlDataAdapter vai .Preenchimento de um múltiplo conjunto de resultados sproc em uma tabela de conjunto de dados por padrão.Os dados dessas tabelas podem ser inseridos em #Temp tabelas de chamar a sproc você deseja escrever. conjunto de dados.ReadXmlSchema vai mostrar o esquema de cada conjunto de resultados.

Passo 1:Comece a escrever a sproc que irá ler os dados do multi-conjunto de resultados sproc

um.Criar uma tabela separada para cada conjunto de resultados de acordo com o esquema.

CREATE PROCEDURE [dbo].[usp_SF_Read] AS
SET NOCOUNT ON;
CREATE TABLE #Table01 (Document_ID VARCHAR(100)
  , Document_status_definition_uid INT
  , Document_status_Code VARCHAR(100) 
  , Attachment_count INT
  , PRIMARY KEY (Document_ID));

b.Neste ponto, você pode precisar declarar um cursor repetidamente chamar a CLR sproc você vai criar aqui:

Passo 2:Fazer o CLR Sproc

Partial Public Class StoredProcedures
    <Microsoft.SqlServer.Server.SqlProcedure()> _
    Public Shared Sub usp_SF_ReadSFIntoTables()

    End Sub
End Class

um.Conectar usando New SqlConnection("context connection=true").

b.Configurar um objeto de comando (cmd) para conter várias conjunto de resultados sproc.

c.Obter todos os dados usando o seguinte:

    Dim dataset As DataSet = New DataSet
    With New SqlDataAdapter(cmd)
        .Fill(dataset) ' get all the data.
    End With
'you can use dataset.ReadXmlSchema at this point...

d.Iterar sobre cada tabela e inserir cada linha apropriada da tabela temporária (que você criou no passo acima).

Observação Final: Na minha experiência, você pode querer impor algumas relações entre as tabelas, assim você sabe qual lote cada registro veio.

Era tudo o que havia para ele!

~ Shaun, Perto De Seattle

Há um kludge que você pode fazer bem.Adicionar um parâmetro opcional N int para seu sproc.Padrão o valor de N-1.Se o valor de N é igual a -1, então a fazer a cada um de seus seleciona.Caso contrário, faça o n-Ésimo selecionar e apenas o n-Ésimo escolha.

Por exemplo,

if (N = -1 or N = 0)
    select ...

if (N = -1 or N = 1)
    select ...

Os chamadores de seu sproc que não especificar N vai obter um resultado conjunto com mais do que um tabelas.Se você precisa extrair uma ou mais dessas tabelas a partir de outro sproc, basta ligar para o seu sproc especificar um valor para N.Você vai ter que chamar o sproc uma vez para cada tabela que você deseja extrair.Ineficiente, se você precisar de mais de uma tabela a partir do conjunto de resultados, mas, ela não funciona em puro TSQL.

Note-se que há um extra, não documentado limitação para a INSERÇÃO EM ...Instrução EXEC:ele não pode ser aninhados.Isto é, o procedimento armazenado que o EXEC chamadas (ou qualquer que ele chama de volta) não pode-se fazer um INSERT INTO ...EXEC.Parece que não há um único bloco de rascunho por processo que acumula o resultado, e se eles estão aninhados, você obterá um erro quando o chamador abre isso e, em seguida, o receptor tenta abri-lo novamente.

Matthieu, você precisa manter separadas temp tabelas para cada "tipo" de resultado.Também, se você estiver executando o mesmo várias vezes, você pode precisar adicionar uma coluna extra para que o resultado para indicar que chamá-lo resultou.

Infelizmente é impossível fazer isso.O problema é que, é claro, que não há Sintaxe SQL para permitir isso.Ele acontece "debaixo do capô" do curso, mas você não pode obter esses resultados, em TSQL, só a partir da aplicação via ODBC ou o que seja.

Há um caminho de volta, como com a maioria das coisas.O truque é usar automação ole em TSQL para criar um objeto ADODB que abre cada conjunto de resultados no turn e gravar os resultados em tabelas que você indicar (ou fazer o que quiser com o conjunto de resultados).você também pode fazê-lo na DMO se você gosta de dor.

Há duas maneiras de fazer isso facilmente.Tanto ficar os resultados em uma tabela temporária e, em seguida, fazer referência a tabela temporária do seu sproc.A outra alternativa é colocar os resultados em uma variável XML que é usado como uma variável de SAÍDA.

No entanto, existem prós e contras de ambas as opções.Com uma tabela temporária, você precisará adicionar o código para o script que cria o procedimento de chamada para criar a tabela temporária antes de modificar o procedimento.Além disso, você deve limpar a tabela temporária no final do procedimento.

Com o XML, ele pode ser a memória de forma intensa e lenta.

Você pode selecioná-los em tabelas temporárias ou escrita com valor de tabela de funções para retornar conjuntos de resultados.Estão perguntando como para iterar através de conjuntos de resultados?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top