2009-08-08 25 views
31

Ich benutze SQL Server 2008 Enterprise. Ich lerne OUTPUT-Parameter der gespeicherten SQL Server-Prozedur. Zum Beispiel hat die gespeicherte Prozedur sp_add_jobschedule einen OUTPUT-Parameter namens schedule_id.SQL Server Ausgabe Parameter Problem

http://msdn.microsoft.com/en-us/library/ms366342.aspx

Meine Verwirrung ist, sieht aus wie OUTPUT-Parameter einen Eingangswert zur Verfügung gestellt werden könnte, und gibt auch einen Wert, sieht aus wie es das Verhalten von Ein- und Ausgabe-Parameter hat? Darf man für OUTPUT-Parameter keine INPUT-Werte angeben (damit es wie reines Output-Parameter-Verhalten aussieht)?

Antwort

60

Die Verwirrung ist zu einem gewissen Grad gerechtfertigt - und andere RDBMS wie Oracle haben gespeicherte Prozedur-Parameter, die vom Typ IN (nur Eingabe), OUT (nur Ausgabe) sein können oder INOUT (beide Wege - Parametertyp "Referenz").

SQL Server ist ein bisschen hier schlampig, da es den Parameter als OUTPUT Etiketten, aber wirklich bedeutet dies INPUT/OUTPUT - es ist im Grunde bedeutet nur, dass die gespeicherte Prozedur in diesem Parameter eine Chance, dass Ihr einen Wert von seinem Anruf hat.

Also ja - auch wenn es OUTPUT Parameter genannt, es ist wirklich eher ein INPUT/OUTPUT Parameter, und diejenigen IN, INOUT, wie OUT in Oracle ist nicht in SQL Server (in T-SQL).

+0

Dank Marc, „Die Verwirrung ist zu einem gewissen Grad gerechtfertigt - und andere RDBMS wie Oracle tun habe gespeicherte Prozedurparameter "- das ist nur der Grund, warum ich verwirrt bin. Ich migriere von DB2 zu SQL Server. Viele Konzepte sind anders. :-( – George2

+1

Eine weitere Frage, wir könnten den OUTPUT-Parameter als optionalen Parameter definieren, dh wir konnten seinen Eingabewert nicht angeben und nur als Ausgabe verwenden? – George2

+3

Ja natürlich - Sie könnten INPUT-Wert angeben oder lassen Sie es leer - Wenn Sie es nicht in Ihrer gespeicherten Prozedur verwenden, ist es völlig sinnlos, was Sie weitergeben. Es liegt an Ihnen und dem Code, den Sie in Ihrer Prozedur schreiben, ob Sie überhaupt den übergebenen Wert ansehen. Die "OUTPUT" -Klausel bedeutet nur, dass die gespeicherte Prozedur die Möglichkeit hat, einen Wert in diesem Parameter ZURÜCKZUFÜHREN - das ist alles. –

19

Ich kann Ihnen ein kurzes Beispiel zum Erstellen einer gespeicherten Prozedur mit Ausgabeparameter geben.

CREATE PROCEDURE test_proc 

@intInput int, 
@intOutput int OUTPUT 

AS 
set @intOutput = @intInput + 1 

go 

Und diese Prozedur aufrufen und dann Ausgabeparameter tun wie folgt verwendet werden:

declare @intResult int 
exec test_proc 3 ,@intResult OUT 
select @intResult 

Sie sehen, dass Sie zuerst ouput Variable zu erklären. Und nach dem Ausführen der gespeicherten Prozedur wird der Ausgabewert in Ihrer Variablen enthalten sein. Sie können einen beliebigen Wert für Ihre Ausgabevariable festlegen. Nach dem Ausführen der gespeicherten Prozedur enthält sie jedoch genau die zurückgegebene gespeicherte Prozedur (unabhängig davon, welcher Wert in der Ausgabevariablen enthalten war).

Zum Beispiel:

declare @intResult int 
exec test_proc 3 ,@intResult OUT 
select @intResult 

Es zurückkehren 4. Und:

declare @intResult int 
set @intResult = 8 
exec test_proc 3 ,@intResult OUT 
select @intResult 

Auch zurückkehren 4.

+1

Dank, so OUTPUT-Parameter sowohl Eingangsparameter und Ausgangsparameter Verhalten? – George2

+3

@ George2: Ja, der Parameter OUTPUT fungiert sowohl als Eingabe- als auch als Ausgabeparameter. – shahkalpesh

2

Die Frage ist - warum tun, um Ihnen verbieten wollen Eingang? Das macht überhaupt keinen Sinn. Betrachten Sie dieses einfache Beispiel:

CREATE PROCEDURE test (@param AS INT OUTPUT) AS 
BEGIN 
    SET @param = 100 
END 
GO 

DECLARE @i INT 
SET @i = 0 

EXECUTE test @i OUTPUT 
PRINT @i 

DROP PROCEDURE test 

Dieser druckt

100 

See - wie Sie einen Wert aus bekommen sollen, wenn Sie keine Variable in an erster Stelle tun?

+0

Danke Tomalak, ich bin mir nicht sicher, ob ich auf diese Weise eine Speicherprozedur mit Ausgabeparametern erstellen kann. Ich kann Ausgabeparameter sowohl als optionalen Eingabeparameter (weil der Ausgabeparameter es uns erlaubt keine Werte einzugeben) als auch als Rückgabewert behandeln. – George2

+1

Ich bin mir nicht sicher, was daran so schwer zu verstehen ist. :) Was ist das eigentliche Problem? – Tomalak

+0

Ich verwende OUTPUT Parameter als Option Eingabeparameter, ich bin nicht sicher, ob es richtige Verwendung ist? Ich verwende auf diese Weise, in der Speicherprozedur, werde ich überprüfen, ob der Aufrufer irgendwelche Werte für den OUTPUT-Parameter eingegeben hat, wenn ja, werde ich etwas tun, wenn kein Eingabewert für den OUTPUT-Parameter, werde ich etwas anderes tun. – George2

2

Denken Sie an OUTPUT-PARAMETER, wie durch Referenz in Programmiersprachen übergeben, es ist das gleiche. Das beste Beispiel, das ich gerade denken kann, ist der Fehlercode. Sie wollen etwas einfügen ... wenn Sie den Return-Code aus dem SP wählen, müssen Sie es zurück in Ihren Code holen, mit OUTPUT-Parameter, die Sie nicht haben, wird es bereits in Ihrem Parameter sein (ich meine mit C# -Befehle, PHP init gespeicherte proc-methoden oder etwas anderes als konstruieren strings)

+0

Danke Svetlio, sieht so aus, als ob es Verhaltensweisen von beiden INPUT und OUTPUT-Parameter hat? Darf man für OUTPUT-Parameter keine INPUT-Werte angeben (damit es wie reines Output-Parameter-Verhalten aussieht)? – George2

+2

@ George2: "Ist es erlaubt, keine INPUT-Werte für den OUTPUT-Parameter anzugeben (damit es wie ein reines Ausgabeparameterverhalten aussieht)" - Ist das nicht das, was Sergey im Code für Beispiel 1 gezeigt hat? – shahkalpesh

+0

Sie meinen diesen? erklären @intResult int exec test_proc 3 @ intResult OUT wählen @intResult – George2

5

Ja, Sie können einen OUTPUT-Parameter sowohl für das Eingeben als auch für das Abrufen von Werten verwenden (obwohl mir im Moment kein guter Grund dafür bekannt ist).

Hier ist ein einfaches Beispiel, das dies zeigt:

10 

----------- 
10 

(1 row(s) affected) 

15 

EDIT: wie folgt aussehen

-- The stored procedure 
CREATE PROCEDURE OutParamExample 
    @pNum int OUTPUT 
AS 
BEGIN 
    select @pNum 
    set @pNum = @pNum + 5 
END 
GO 

-- use a local variable to retrieve your output param value 
declare @TheNumber int 
set @TheNumber = 10 

print @TheNumber 
exec OutParamExample @TheNumber OUTPUT 
print @TheNumber 

Die Ergebnisse Ich denke, dass ich ein "nicht" in der zweiten verpassten OK, Absatz und möglicherweise die von Ihnen gestellte Frage nicht beantwortet. Wenn Sie einen strikten Ausgabeparameter (zB einen Rückgabecode) möchten, müssen Sie der lokalen Variablen, die als Ausgabeparameter übergeben wurde, keinen Wert angeben, aber Sie müssen diese lokale Variable trotzdem deklarieren Ich habe eine Möglichkeit, auf den zurückgegebenen Wert zuzugreifen, der außerhalb des Bereichs der Prozedur selbst liegt.

Zum Beispiel:

declare @LocalNumber int 
-- I don't have to assign a value to @LocalNumber to pass it as a parameter 
exex OutParamExample @LocalNumber OUTPUT 
-- (assume SP has been altered to assign some reasonable value) 

-- but I do have to declare it as a local variable so I can get to 
-- the return value after the stored procedure has been called 
print @LocalNumber 
3

Hinzufügen von weiteren zu dem, was andere über gesagt haben, können Ausgabeparameter als INPUT wirken sowie OUTPUT. Es hängt jedoch von der gespeicherten Prozedur ab, den an sie übergebenen Wert zu verwenden.

Wenn die gespeicherten Prozeduren den übergebenen Wert für den OUTPUT-Parameter ignorieren (was normalerweise der Fall ist), wird der INPUT-Wert trotzdem ignoriert.

Sergeys Code verwenden, kann ich den Wert Benutzer für @intOutput weitergegeben verwenden (wenn es sein muss)

create PROCEDURE test_proc 

@intInput int, 
@intOutput int OUTPUT 

AS 
set @intOutput = @intOutput + 1 

go 

Aber, dass der Zweck des OUTPUT-Parameter besiegt.
Um eine andere Ansicht zu geben, zwingt der C# -Compiler Sie, den Wert des out-Parameters durch Zuweisung zu überschreiben (ohne den Ausgabeparameter zu verwenden).

z.B. Ich kann das nicht in C# machen. Hierbei handelt es sich nur als out-Parameter (dh den Wert Benutzer ignorieren diese Funktion übergeben)

static void dosomething(out int i) 
{ 
    //i = 0; 
    i = i + 1; 
} 
1

Ein zusätzlicher Hinweis bezüglich Teil der ursprünglichen Frage:

„Ist es ein INPUT nicht zu schaffen erlaubt Werte für OUTPUT-Parameter (..)? "

In SQLServer ist es möglich, einen Standardwert für einen OUTPUT-Parameter anzugeben (der wie andere tatsächlich INOUT angegeben haben). Betrachten Sie das folgende Beispiel, in dem Sie einen expliziten Wert angeben oder die Funktion selbst eine ID generieren lassen könnte.

CREATE PROCEDURE test (@id uniqueidentifier = NULL OUTPUT) AS 
BEGIN 
    IF @id IS NULL SET @id = NEWID() 
    -- INSERT INTO xyz (...) VALUES (@id, ...) 
    PRINT 'Insert with id: ' + CAST (@id as nvarchar(36)) 
END 
GO 

DECLARE @insertedId uniqueidentifier 
EXECUTE test '00000000-0000-0000-0000-000000000000' 
EXECUTE test @insertedId OUTPUT 
PRINT @insertedId 

DROP PROCEDURE test 

Dieser druckt

Insert with id: 00000000-0000-0000-0000-000000000000 
Insert with id: 67AE3D27-8EAB-4301-B384-30EEA1488440 
67AE3D27-8EAB-4301-B384-30EEA1488440