2013-11-20 15 views
24

Mam procedurę składowaną, która pobiera parametr wejściowy @CategoryKeys varchar i analizuje jej zawartość w tabeli tymczasowej, #CategoryKeys.Jak przekazać tabelę tymczasową jako parametr do oddzielnej procedury składowanej

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

Jeśli tabela tymczasowa ma wiersze, chciałbym przekazać tabelę do osobnej procedury składowanej. W jaki sposób chciałbym utworzyć parametr w oddzielnej procedurze przechowywania tabeli tymczasowej?

+0

Zamiast przekazując listę oddzielonych przecinkami w pierwszej kolejności, czy pomyślałeś o używaniu [parametry wycenione tabela] (http://technet.microsoft.com /en-us/library/bb510489.aspx)? Czy też przeczytałeś [ten artykuł] (http://www.sommarskog.se/share_data.html)? –

+0

Lub XML, ponieważ SQL Server oferuje wsparcie dla typu danych XML ... –

Odpowiedz

11

Po utworzeniu tabeli #temp, w „zakres” jest większy niż tylko procedury jest utworzony w

Poniżej próbka.

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 

powiedział, że należy wykonać NOT CODE UP ALOT Z TYCH. JEST TO RÓWNOWARTOŚĆ EKWIWENENTOWĄ GLOBALNEJ ZMIENNEJ I JEST TO TRUDNE DO UTRZYMANIA I BŁĘDU PRONE.

16

Podczas gdy rozumienie określania adresów odnosi się do bezpośredniej potrzeby, można pomyśleć, że warto dodać kilka dodatkowych opcji do miksu, aby rozwinąć sugestie z komentarzy.

  1. Przełęcz XML do procedury przechowywanej
  2. przedostać się parametr tabeli wartościach do procedury przechowywanej

1. Przełęcz XML do procedury przechowywanej

XML wprowadza się do parametr, możesz użyć XML bezpośrednio w zapytaniach SQL i dołączyć/zastosować do innych tabel:

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 

Następnie wywołanie procedury składowanej do testowania:

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

Przykładowe wyjście prostego zapytania.

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

2. przekazać parametr wycenione tabela w procedurze przechowywanej

Po pierwsze, trzeba określić typ zdefiniowany przez użytkownika w zmiennej dla tabeli mają być używane przez procedury przechowywanej.

CREATE TYPE KeyTable AS TABLE ([Key] INT) 

Następnie można użyć tego typu jako parametr do przechowywanej obrady (the READONLY jest wymagane, ponieważ tylko IN jest obsługiwany, a tabela nie może zostać zmieniona)

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

Przechowywane proc mogą następnie wywoływane za pomocą zmiennej tabeli bezpośrednio z SQL.

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

Uwaga: Jeśli korzystasz z .NET, możesz przekazać parametr SQL z typu DataTable odpowiadającego typowi zdefiniowanemu przez użytkownika.

Przykładowe wyjście z kwerendy:

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

Podczas gdy mam zaakceptowaną odpowiedź na to pytanie, działam nad tym, ponieważ "tylko dlatego, że zakres działa" ..... nie oznacza, że ​​jest to dobre rozwiązanie. Traktowanie #tempTables jako zmiennej globalnej jest złą rutynową praktyką. I robię dokładnie to, I przechodzą xml cały czas, aby promować operacje oparte na zestawie, aby uniknąć kursorów i RBAR. – granadaCoder