2013-11-20 5 views
24

Ich habe eine gespeicherte Prozedur, die einen Eingabeparameter @CategoryKeys varchar verwendet, und analysiert ihren Inhalt in eine temporäre Tabelle, #CategoryKeys.So übergeben Sie eine temporäre Tabelle als Parameter an eine separate gespeicherte Prozedur

 -- 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 

Wenn die temporären Tabellenzeilen haben, würde Ich mag die Tabelle in eine separate gespeicherte Prozedur zu übergeben. Wie würde ich einen Parameter in der separaten Prozedur erstellen, um die temporäre Tabelle zu halten?

+0

Statt eine durch Kommata getrennte Liste an erster Stelle zugeben, haben Sie darüber nachgedacht, mit [Tabellenwertparameter] (http://technet.microsoft.com /en-us/library/bb510489.aspx)? Haben Sie auch [diesen Artikel] (http://www.sommarskog.se/share_data.html) gelesen? –

+0

Oder XML, wie SQL Server bietet Unterstützung für XML-Datentyp ... –

Antwort

11

Wenn Sie eine #TEMP Tabelle zu erstellen, ist der "Umfang" größer als nur das Verfahren in der sie erstellt wird

Im Folgenden wird eine Probe.

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 

Having said that, BITTE NICHT MEHR ALS CODE. ES IST DAS SQL-ÄQUIVALENT EINER GLOBALEN VARIABLEN UND ES IST SCHWER ZUR BEIBEHALTUNG UND SCHULDIGUNG.

16

Während das Verständnis von Scoping das direkte Bedürfnis anspricht, könnte es sinnvoll sein, dem Mix einige weitere Optionen hinzuzufügen, um die Vorschläge aus den Kommentaren zu erläutern.

  1. Pass XML in die gespeicherte Prozedur
  2. Übergeben Sie einen Tabellenwertparameter in die gespeicherte Prozedur

1. Pass XML in die gespeicherte Prozedur

Mit XML in eine bestandene Parameter können Sie das XML direkt in Ihren SQL-Abfragen verwenden und anderen Tabellen beitreten/anwenden:

CREATE PROC sp_PassXml 
    @Xml XML 
AS 
BEGIN 
    SET NOCOUNT ON 
    SELECT T.Node.value('.', 'int') AS [Key] 
    FROM @Xml.nodes('/keys/key') T (Node) 
END 
GO 

ein Aufruf der gespeicherten Prozedur für die Prüfung dann:

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

Beispiel für die Ausgabe einer einfachen Abfrage.

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

2. Pass ein Tabellenwertparameter in die gespeicherte Prozedur

Zuerst müssen Sie den Benutzer definierten Art für die Tabelle Variable definieren, indem die gespeicherte Prozedur verwendet werden.

CREATE TYPE KeyTable AS TABLE ([Key] INT) 

Dann Sie diese Art als Parameter für die gespeicherte Prozedur verwenden können (die READONLY erforderlich, da nur IN unterstützt wird und die Tabelle kann nicht geändert werden)

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

Die gespeicherte Prozedur kann dann mit einer Tabellenvariablen direkt aus SQL aufgerufen werden.

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

Hinweis: Wenn Sie .NET verwenden, dann können Sie die SQL-Parameter von einem Datatable-Typ übergeben Sie den benutzerdefinierten Typ entsprechen.

Beispielausgabe aus der Abfrage:

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

Während ich die akzeptierte Antwort auf die Frage habe, bin ich upvoting dies, weil "nur weil der Umfang funktioniert" ..... bedeutet nicht, es ist ein gute Lösung. Das Behandeln von #tempTables wie eine globale Variable ist eine schlechte Routineübung. Und ich mache genau das, ich übergebe xml die ganze Zeit, um Set-basierte Operationen zu fördern, um Cursor und RBAR zu vermeiden. – granadaCoder

Verwandte Themen