webentwicklung-frage-antwort-db.com.de

So geben Sie eine temporäre Tabelle aus der gespeicherten Prozedur zurück

CREATE PROCEDURE [test].[proc]
@ConfiguredContentId int,
@NumberOfGames int
AS
BEGIN
 SET NOCOUNT ON
 RETURN 
 @WunNumbers TABLE (WinNumb int)

    INSERT INTO @WunNumbers (WinNumb)
 SELECT TOP (@NumberOfGames) WinningNumber
 FROM [Game].[Game] g
 JOIN [Game].[RouletteResult] AS rr ON g.[Id] = rr.[gameId]
 WHERE g.[ConfiguredContentId] = @ConfiguredContentId
 ORDER BY g.[Stoptime] DESC

 SELECT WinNumb, COUNT (WinNumb) AS "Count"
 FROM @WunNumbers wn
 GROUP BY wn.[WinNumb]
END
GO

Diese gespeicherte Prozedur gibt Werte aus der ersten Auswahlanweisung zurück, aber ich möchte, dass Werte aus der zweiten Auswahlanweisung zurückgegeben werden. Tabelle @WunNumbers ist eine temporäre Tabelle.

Irgendwelche Ideen???

15
dani

Welche Version von SQL Server verwenden Sie? In SQL Server 2008 können Sie Table-Parameter und Tabellentypen verwenden.

Ein alternativer Ansatz besteht darin, eine Tabellenvariable aus einer benutzerdefinierten Funktion zurückzugeben, aber ich bin kein großer Fan dieser Methode.

Ein Beispiel finden Sie hier

6
John Sansom

Schauen Sie sich diesen Code an,

CREATE PROCEDURE Test

AS
    DECLARE @tab table (no int, name varchar(30))

    insert @tab  select eno,ename from emp  

    select * from @tab
RETURN
27
adatapost

Im Anrufer kann eine temporäre Tabelle erstellt und dann vom aufgerufenen SP aus gefüllt werden. 

  create table #GetValuesOutputTable(
     ...   
  );

  exec GetValues; -- populates #GetValuesOutputTable

  select * from #GetValuesOutputTable;

Einige Vorteile dieses Ansatzes gegenüber dem "insert exec" sind, dass er verschachtelt werden kann und als Eingabe oder Ausgabe verwendet werden kann. 

Einige Nachteile bestehen darin, dass das "Argument" nicht öffentlich ist, die Tabellenerstellung in jedem Aufrufer vorhanden ist und der Name der Tabelle mit anderen temporären Objekten kollidieren könnte. Dies ist hilfreich, wenn der Name der temporären Tabelle eng mit dem Namen SP übereinstimmt und einigen Konventionen folgt.

Etwas weiter entfernt, für die Ausgabe von nur Temp-Tabellen können der Insert-Exec-Ansatz und der Temp-Table-Ansatz gleichzeitig vom aufgerufenen SP unterstützt werden. Dies hilft nicht viel bei der Verkettung von SPs, da die Tabelle noch im Aufrufer definiert werden muss. Dies kann jedoch dazu beitragen, das Testen von der cmd-Zeile oder beim externen Aufruf zu vereinfachen.

  -- The "called" SP
  declare
      @returnAsSelect bit = 0;

  if object_id('tempdb..#GetValuesOutputTable') is null
  begin
      set @returnAsSelect = 1;
      create table #GetValuesOutputTable(
         ...   
      );
  end

  -- populate the table

  if @returnAsSelect = 1
      select * from #GetValuesOutputTable;
3
crokusek

Der Rückgabetyp einer Prozedur ist int.

Sie können auch Ergebnissätze zurückgeben (wie es derzeit Ihr Code tut) (okay, Sie können auch Nachrichten senden, die Zeichenfolgen sind).

Dies sind die einzigen "Renditen", die Sie machen können. Während Sie einer Prozedur Tabellenwertparameter hinzufügen können (siehe BOL), werden diese nur eingegeben.

Bearbeiten:

(Oder wie in einem anderen Poster erwähnt, können Sie anstelle einer Prozedur auch eine Tabellenwertfunktion verwenden.)

Erstellen Sie zuerst eine echte, permanente Tabelle als Vorlage mit dem erforderlichen Layout für die zurückgegebene temporäre Tabelle. Verwenden Sie dazu eine Namenskonvention, die sie als Vorlage identifiziert und symbolisch mit dem SP verknüpft, z. B. tmp_SPName_Output . Diese Tabelle enthält niemals Daten.

Mit INSERT können Sie im SP Daten in eine temporäre Tabelle laden, die der gleichen Namenskonvention entspricht, z. #SPName_Output der angenommen wird. Sie können das Vorhandensein testen und einen Fehler zurückgeben, wenn dies nicht der Fall ist.

Vor dem Aufruf von sp verwenden Sie diese einfache Auswahl, um die temporäre Tabelle zu erstellen:

SELECT TOP(0) * INTO #SPName_Output FROM tmp_SPName_Output;
EXEC SPName;
-- Now process records in #SPName_Output;

Dies hat folgende Vorteile:

  • Die temporäre Tabelle ist im Gegensatz zu ## lokal für die aktuelle Sitzung. Sie stößt daher nicht mit gleichzeitigen Aufrufen der SP von verschiedenen Sitzungen an. Es wird auch automatisch gelöscht, wenn es außerhalb des Gültigkeitsbereichs liegt.
  • Die Vorlagetabelle wird neben dem SP verwaltet. Wenn also Änderungen an der Ausgabe vorgenommen werden (z. B. um neue Spalten), werden die vorhandenen -Aufrufer von SP nicht unterbrochen. Der Anrufer muss nicht geändert werden.
  • Sie können eine beliebige Anzahl von Ausgabetabellen mit unterschiedlicher Benennung für One SP definieren und sie alle füllen. Sie können auch alternative Ausgaben Mit unterschiedlicher Benennung definieren. Lassen Sie das Vorhandensein der temporären -Tabellen mit SP überprüfen, um festzustellen, welche Felder gefüllt werden müssen.
  • Wenn größere Änderungen vorgenommen werden, Sie jedoch die Rückwärtskompatibilität beibehalten möchten, können Sie eine neue Vorlagetabelle und einen neuen Namen für die spätere Version, aber die frühere Version unterstützen, indem Sie prüfen, in welcher temporären Tabelle der Aufrufer angezeigt wird hat erschaffen.
0
JohnRC

JA, DU KANNST.

In Ihrer gespeicherten Prozedur füllen Sie die Tabelle @tbRetour.

Ganz am Ende Ihrer gespeicherten Prozedur schreiben Sie: 

SELECT * FROM @tbRetour 

Um die gespeicherte Prozedur auszuführen, schreiben Sie:

USE [...]
GO

DECLARE @return_value int

EXEC @return_value = [dbo].[getEnregistrementWithDetails]
@id_enregistrement_entete = '(guid)'

GO
0
André Millaire