2013-11-20 15 views
24

Ho una stored procedure che accetta un parametro di input @CategoryKeys varchar e ne analizza il contenuto in una tabella temporanea, #CategoryKeys.Come passare una tabella temporanea come parametro in una stored procedure separata

 -- create the needed temp table. 
     CREATE TABLE #CategoryKeys 
      (
      CategoryKey SMALLINT 
     ); 

     -- fill the temp table if necessary 
     IF Len(rtrim(ltrim(@CategoryKeys))) > 0 
      BEGIN 
       INSERT INTO #CategoryKeys 
          (CategoryKey) 
       SELECT value 
       FROM dbo.String_To_SmallInt_Table(@CategoryKeys, ','); 
      END 

Se la tabella temporanea contiene righe, vorrei passare la tabella in una stored procedure separata. Come andrei sulla creazione di un parametro nella procedura separata per tenere la tabella temporanea?

+0

Invece di passare un elenco separato da virgole, in primo luogo, hai pensato di usare [parametri con valori di tabella] (http://technet.microsoft.com /en-us/library/bb510489.aspx)? Hai anche letto [questo articolo] (http://www.sommarskog.se/share_data.html)? –

+0

Oppure XML, in quanto SQL Server offre supporto per il tipo di dati XML ... –

risposta

11

Quando si crea una tabella #temp, lo "scopo" è più grande di una semplice procedura che viene creato in

Qui di seguito è un esempio:.

IF EXISTS 
    (
    SELECT * FROM INFORMATION_SCHEMA.ROUTINES 
    WHERE ROUTINE_TYPE = N'PROCEDURE' and ROUTINE_SCHEMA = N'dbo' and ROUTINE_NAME = N'uspProc002' 
    ) 
BEGIN 
    DROP PROCEDURE [dbo].[uspProc002] 
END 


GO 

CREATE Procedure dbo.uspProc002 
AS 

BEGIN 

    /* Note, I did not Create #TableOne in this procedure. It "pre-existed". An if check will ensure that it is there. */ 
    IF OBJECT_ID('tempdb..#TableOne') IS NOT NULL 
    begin 
     Insert into #TableOne (SurrogateKey , NameOf) select 2001, 'uspProc002' 
    end 

END 


GO 



IF EXISTS 
    (
    SELECT * FROM INFORMATION_SCHEMA.ROUTINES 
    WHERE ROUTINE_TYPE = N'PROCEDURE' and ROUTINE_SCHEMA = N'dbo' and ROUTINE_NAME = N'uspProc001' 
    ) 
BEGIN 
    DROP PROCEDURE [dbo].[uspProc001] 
END 


GO 

CREATE Procedure dbo.uspProc001 (
@Param1 int 
) 
AS 

BEGIN 


    IF OBJECT_ID('tempdb..#TableOne') IS NOT NULL 
    begin 
      drop table #TableOne 
    end 


    CREATE TABLE #TableOne 
    ( 
    SurrogateKey int , 
    NameOf varchar(12) 
    ) 

    Insert into #TableOne (SurrogateKey , NameOf) select 1001, 'uspProc001' 

    Select * from #TableOne 

    EXEC dbo.uspProc002 

    Select * from #TableOne 

    IF OBJECT_ID('tempdb..#TableOne') IS NOT NULL 
    begin 
      drop table #TableOne 
    end 


END 


GO 




exec dbo.uspProc001 0 

Detto questo, si prega di NON CODIFICARE MOLTO DI QUESTI. È l'EQUIVALENTE SQL DI UNA VARIABILE GLOBALE E È DIFFICILE DA MANTENERE E INSERIRE PRATO.

16

Mentre la comprensione dell'ambito risponde all'esigenza diretta, è possibile che sia utile aggiungere alcune ulteriori opzioni al mix per elaborare i suggerimenti dei commenti.

  1. Passo XML nella stored procedure
  2. passare un parametro con valori di tabella nella stored procedure

1. Passo XML nella stored procedure

Con XML passato in un parametro, è possibile utilizzare l'XML direttamente nelle query SQL e partecipare/applicare ad altre tabelle:

Poi una chiamata alla procedura immagazzinata per il test:

DECLARE @Text XML = '<keys><key>1</key><key>2</key></keys>' 
EXEC sp_PassXml @Text 

Esempio di output di una query semplice.

Key 
----------- 
1 
2 

2. passare un parametro con valori di tabella nella stored procedure

In primo luogo, è necessario definire il tipo definito dall'utente per la variabile di tabella per essere utilizzato dalla stored procedure.

CREATE TYPE KeyTable AS TABLE ([Key] INT) 

Quindi, è possibile utilizzare tale tipo come parametro per la stored procedure (la READONLY è richiesto in quanto è supportato solo IN e la tabella non può essere modificato)

CREATE PROC sp_PassTable 
    @Keys KeyTable READONLY 
AS 
BEGIN 
    SET NOCOUNT ON 
    SELECT * FROM @Keys 
END 
GO 

Il proc memorizzato può allora essere chiamato con una variabile di tabella direttamente da SQL.

DECLARE @Keys KeyTable 
INSERT @Keys VALUES (1), (2) 
EXEC sp_PassTable @Keys 

Nota: Se si utilizza .NET, allora si può passare il parametro SQL da un tipo DataTable che corrisponde al tipo definito dall'utente.

uscita del campione dalla query:

Key 
----------- 
1 
2 
+0

Mentre ho la risposta accettata alla domanda, sto inviando questo perché "solo perché lo scope funziona" ..... non significa che sia un buona soluzione. Trattare #tempTables come una variabile globale è una cattiva pratica di routine. E faccio esattamente questo, passo xml tutto il tempo a promuovere operazioni basate su set per evitare cursori e RBAR. – granadaCoder

Problemi correlati