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???
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
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
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;
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:
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