it-frosch
Goto Top

MSSQL Daten ändern mit Rückgabewerten - wie richtig?

Hallo Kollegen,

ich will eine Funktion schreiben der ich Kundennummer und Kontonummer mitgebe.
Von der Funktion soll ein Status und eine Beschreibung zurückgebeben werden,
abhängig davon ob die Änderungen durchgeführt wurden. (Ja, ich weiß, dass das Abfangen nicht sauber gelöst ist. face-wink )

Die Rückgabewerte sollen dann sein:
Beschreibung = 'Die eingegebene Kundennummer existiert nicht' + Status='FEHLER'
Beschreibung = 'Die Kontonummer konnte nicht eingetragen werden' + Status='FEHLER'
Beschreibung = 'Die Kontonummer wurde korrigiert' + Status='INFO'

Nachdem ich die Funktion fertig hatte durfte ich lernen, dass in Funktionen UPDATE Befehle nicht erlaubt sind.
Super face-smile

Dann habe ich den UPDATE Befehl durch ein procedure ersetzt.
Ihr werdet es schon wissen - ist auch nicht erlaubt.
Msg 557, Level 16, State 2, Line 1
Nur Funktionen und einige erweiterte gespeicherte Prozeduren können innerhalb einer Funktion ausgeführt werden.

Jetzt also die Frage an die Profis, wie macht man so etwas richtig?
Damit ihr einen Eindruckt habt was ich machen will, hier die nicht funktionsfähige Funktion.
CREATE FUNCTION [dbo].[FUNC_KONTONR_Korrektur](
@INT_1 int,			-- Kundennummer
@INT_2 int			-- neue Debitorenkontonummer
)
RETURNS @INFO Table (
status varchar(6),
beschreibung VARCHAR(100))
AS

BEGIN
	DECLARE @STATUS varchar(6);
	DECLARE @BESCHREIBUNG VARCHAR(100);
	DECLARE @KUNDEEXIST int;
	DECLARE @Kontrolle_DEBKONTO int;	

-- Prüfungen
SET @KUNDEEXIST = (select count(kundennr) from kunden where kundennr=@INT_1)

-- Kundennummer existiert nicht
IF (@KUNDEEXIST=0)  
	BEGIN
		SET @BESCHREIBUNG = 'Die eingegebe Kundennummer existiert nicht';  
		SET @STATUS = 'FEHLER';  
	END
	
-- Kundennummer existiert	
IF (@KUNDEEXIST=1)  
	BEGIN
		update kunden set kontonr=@INT_2 where kundennr=@INT_1;
		set @KONTROLLE_DEBKONTO = (select kontonr from kunden where kundennr=@INT_1);
		IF (@KONTROLLE_DEBKONTO = @INT_2)  
			BEGIN
				SET @BESCHREIBUNG = 'Es wurde beim Kunden:'+CAST(@INT_1 as VARCHAR(9))+' die Kontonummer: '+CAST(@INT_2 as VARCHAR(9))+' hinterlegt'  
				SET @STATUS = 'INFO'  
			END
		ELSE
			BEGIN
				SET @BESCHREIBUNG = 'Es ist ein Fehler beim Schreiben der Debitorenkontonummer aufgetreten.'  
				SET @STATUS = 'FEHLER'  
			END
	END
	
IF @INT_2 is not null
 BEGIN
	INSERT @INFO
	Select @STATUS, @BESCHREIBUNG
 END

RETURN;
END;
GO

Content-Key: 34127193082

Url: https://administrator.de/contentid/34127193082

Printed on: April 27, 2024 at 10:04 o'clock

Member: it-frosch
it-frosch Sep 24, 2023 at 14:21:18 (UTC)
Goto Top
Ich hätte jetzt nur die Idee, den Update und die Fehlerbehandlung in eine Procedure zu packen, die dann
verschiedene Rückgabewerte (0,1,2,3) zurückgibt, denen ich dann anschließend die Beschreibungstexte zuordne.

Das kommt mir alles furchtbar umständlich vor.

Ich habe für jede Aufgabe (es gibt momentan 9 Stück) eine Funktion vorgesehen die dann in den Powershellcode den Beschreibungstext quasi als Status für den User ausgeben soll.
Deshalb ist mir der Beschreibungstext so wichtig.

Wenn es denn gar nicht hinzubekommen ist, müsste ich mir im Powershell Code eine Rückgabewerte zu Beschreibungstext Übersetzung einbauen, damit der richtige Text ausgegeben wird.

Grüße vom it-frosch
Member: Crusher79
Solution Crusher79 Sep 24, 2023 at 16:34:08 (UTC)
Goto Top
Hallo,

naja ich vestehe zwar dein Anliegen. Aber auch bei Update Fehler bekommt man vom SQL Server eine Fehlermeldung zurück. Nochmal die Nummer sofort zu prüfen macht eigentlich keinen Sinn.

https://www.sqlshack.com/how-to-implement-error-handling-in-sql-server/

https://www.sqlservertutorial.net/sql-server-stored-procedures/sql-serve ...

Auch in Prozeduren kann man mit try-catch arbeiten.
Member: ukulele-7
Solution ukulele-7 Sep 25, 2023 at 08:25:59 (UTC)
Goto Top
Also eine function kannst du grundsätzlich in jedem Select oder Update benutzen um Daten passend aufzubereiten. Du kannst aber kein Update während eines Selects ausführen, das ist nicht zulässig/möglich. Ich weiß wovon ich rede weil ich neulich eine ähnliche Idee hatte um Daten im Hintergrund abzurufen, funktioniert leider nicht.

Es gibt einen Weg über stored procedures sowohl Updates zu machen als auch im Anschluss eine Tabelle zurück zu geben. Dann muss man aber die SP aufrufen und kann nicht einen normalen Select oder eine View abfragen. Eine SP kann aber genau das, was du suchst, nämlich einen Vorgang zusammen fassen und Werte zurück geben (bei Erfolg oder Misserfolg).

Alternativ wenn du eine Kontonummer ändern willst, wiso machst du dann nicht einfach ein Update auf die Tabelle in der die Kontonummer steht und das fängst du dann mit einem Trigger ab? Innerhalb des Triggers kannst du weitere Tabellen vorher anpassen, die Änderung einfach verwerfen oder z.B. mit RAISEERROR eine Fehlermeldung zurück geben. Meldungen bei erfolgreichen Änderungen ist allerdings eher nicht so gedacht. Es kommt drauf an wo man hin will.