Benutzer mit den meisten Antworten
Stored Procedure und Rückgabewerte

Frage
-
Hallo,
Ich habe eine Tabelle [Sprachen], in welcher als Spalten nur die [Id] und die [Sprache] erfasst werden. Jetzt bin ich dabei eine Gespeicherte Prozedur zu erstellen, über diese sollen neue Sprachen hinzugefügt werden.
Falls die neu einzufügende Sprache nicht existiert wird eine neue [Sprache] erstellt, auf jeden Fall möchte ich aber diesen neuen Eintrag als Rückgabewert der Prozedur haben. Zusätzlich als Outputparameter die Id übergeben.
Ziel der Aktion ist es in anderen Prozeduren und auch später über mein C# Programm damit zu arbeiten, also wahlweise nur die [ID] zu verarbeiten und/oder den Tabellendatentyp Sprache im C# Programm.
Anbei mein Lösungsvorschlag, besonders unsicher bin ich mir bei der letzten Zeile: "SELECT @Id AS ID, @Sprache AS Sprache"
ALTER PROCEDURE InsertSprachen
@Sprache NVARCHAR(256)
, @Id INT OUTPUT
ASBEGIN
IF EXISTS (SELECT TOP (1) * FROM Sprachen WHERE Sprache = @Sprache) BEGIN SET @Id = @@IDENTITY END ELSE BEGIN INSERT INTO Sprachen([Sprache]) VALUES(@Sprache) SET @Id = SCOPE_IDENTITY() END
SELECT @Id AS ID, @Sprache AS SpracheEND
Antworten
-
Hallo,
beim erste Fall, wenn die Sprache vorhanden ist, verwendest Du @@IDENTITY, das liefert den zuletzt, in irgendeine Tabelle eingefügte Identity, also hier eher nicht das gewünschte Ergebnis.
Das SELECT am Ende kannst Du eigentlich einsparen, den der Output Parameter soll ja den Wert liefern, wenn ich Dich richtig verstanden habe. Oder willst Du das Ergebnis immer geliefert werden, z.B. um es von Entity Framework als Objekt zu erhalten?
Eigentlich reicht es aus, zunächst die ID zu selektieren und wenn das Ergebnis NULL, die Sprache als neue einzufügen:
REATE TABLE dbo.Sprachen (ID int IDENTITY(1, 1) PRIMARY KEY ,Sprache NVARCHAR(256)); GO CREATE PROCEDURE dbo.InsertSprachen @Sprache NVARCHAR(256) , @Id INT OUTPUT AS BEGIN SET NOCOUNT ON; -- Ermitteln, ob vorhanden SET @Id = (SELECT ID FROM dbo.Sprachen WHERE Sprache = @Sprache) IF @ID IS NULL BEGIN INSERT INTO Sprachen([Sprache]) VALUES(@Sprache) SET @Id = SCOPE_IDENTITY() END END GO -- Test: DECLARE @ID int; EXEC dbo.InsertSprachen @Sprache = N'Deutsch', @Id = @ID OUTPUT; SELECT @ID; EXEC dbo.InsertSprachen @Sprache = N'Englisch', @Id = @ID OUTPUT; SELECT @ID; -- Soll wieder 1 liefern, da bereits vorhanden EXEC dbo.InsertSprachen @Sprache = N'Deutsch', @Id = @ID OUTPUT; SELECT @ID;
Olaf Helper
[ Blog] [ Xing] [ MVP]- Als Antwort vorgeschlagen Aleksander Chalabashiev Dienstag, 21. Oktober 2014 14:09
- Als Antwort markiert Aleksander Chalabashiev Montag, 27. Oktober 2014 14:32
-
Die ursprüngliche Frage war bezüglich einem Output Parameter, den erhältst Du auch in ADO.NET zurück. Die Sprache übergibst Du ja, also sind alle Daten bekannt.
Aber Du kannst auch wieder Dein ursprüngliches SELECT einbauen, dann kannst Du Dir den OUTPUT Parameter einsparen.
Olaf Helper
[ Blog] [ Xing] [ MVP]- Als Antwort vorgeschlagen Aleksander Chalabashiev Montag, 27. Oktober 2014 09:06
- Als Antwort markiert Aleksander Chalabashiev Montag, 27. Oktober 2014 14:32
Alle Antworten
-
Hallo,
beim erste Fall, wenn die Sprache vorhanden ist, verwendest Du @@IDENTITY, das liefert den zuletzt, in irgendeine Tabelle eingefügte Identity, also hier eher nicht das gewünschte Ergebnis.
Das SELECT am Ende kannst Du eigentlich einsparen, den der Output Parameter soll ja den Wert liefern, wenn ich Dich richtig verstanden habe. Oder willst Du das Ergebnis immer geliefert werden, z.B. um es von Entity Framework als Objekt zu erhalten?
Eigentlich reicht es aus, zunächst die ID zu selektieren und wenn das Ergebnis NULL, die Sprache als neue einzufügen:
REATE TABLE dbo.Sprachen (ID int IDENTITY(1, 1) PRIMARY KEY ,Sprache NVARCHAR(256)); GO CREATE PROCEDURE dbo.InsertSprachen @Sprache NVARCHAR(256) , @Id INT OUTPUT AS BEGIN SET NOCOUNT ON; -- Ermitteln, ob vorhanden SET @Id = (SELECT ID FROM dbo.Sprachen WHERE Sprache = @Sprache) IF @ID IS NULL BEGIN INSERT INTO Sprachen([Sprache]) VALUES(@Sprache) SET @Id = SCOPE_IDENTITY() END END GO -- Test: DECLARE @ID int; EXEC dbo.InsertSprachen @Sprache = N'Deutsch', @Id = @ID OUTPUT; SELECT @ID; EXEC dbo.InsertSprachen @Sprache = N'Englisch', @Id = @ID OUTPUT; SELECT @ID; -- Soll wieder 1 liefern, da bereits vorhanden EXEC dbo.InsertSprachen @Sprache = N'Deutsch', @Id = @ID OUTPUT; SELECT @ID;
Olaf Helper
[ Blog] [ Xing] [ MVP]- Als Antwort vorgeschlagen Aleksander Chalabashiev Dienstag, 21. Oktober 2014 14:09
- Als Antwort markiert Aleksander Chalabashiev Montag, 27. Oktober 2014 14:32
-
Die ursprüngliche Frage war bezüglich einem Output Parameter, den erhältst Du auch in ADO.NET zurück. Die Sprache übergibst Du ja, also sind alle Daten bekannt.
Aber Du kannst auch wieder Dein ursprüngliches SELECT einbauen, dann kannst Du Dir den OUTPUT Parameter einsparen.
Olaf Helper
[ Blog] [ Xing] [ MVP]- Als Antwort vorgeschlagen Aleksander Chalabashiev Montag, 27. Oktober 2014 09:06
- Als Antwort markiert Aleksander Chalabashiev Montag, 27. Oktober 2014 14:32