Returncode aus stp

Martinha

Fleissiger Benutzer
Beiträge
65
Hi,

ich möchte Dat Daten aus anderen Tabellen in die Tabelle Umsatz einfügen. Quelle sind Daten aus anderen Tabellen:

try
SET NOCOUNT ON;

-- Insert statements for procedure here
insert into [dbo].[umsatz] (UmsatzId
,kontoid
,betrag
,buchungstext
,umsatzdatum
,umsatzart
,newflag
,befreit)
select [udfautowert] (N'umsatz',N'umsatzid')
,leistung.kontoId
,[udfsaldo](Konto.KontoId) * -1
,N'Lastschrift vom ' + getdate() + N' AS BT'
,getdate()
,2
,1
,1
FROM Konto INNER JOIN Leistung ON Konto.KontoId = Leistung.KontoID
WHERE saldo*-1 >0 AND konto.KontoArt = 2 AND Konto.KontoStatus =1 AND Leistung.LeistungStatus=1
end try

Es gibt eine Scalar Funktion (udfautowert), die mit dynamischen SQL den nächsten pk-Wert für die Umsatztabelle berechnet (aktuller maximaler Index + 1).
Ferner gibt es eine Funktion (udfsaldo), die den aktuellen Saldo eines Kontos berechnet.

Wenn ich diese Funktion speichern will kommt die Meldung:

Msg 120, Level 15, State 1, Procedure umsatz_ausgleich, Line 25 [Batch Start Line 7]
Die Auswahlliste für die INSERT-Anweisung enthält weniger Elemente als die Einfügeliste. Die Anzahl von SELECT-Werten und die Anzahl von INSERT-Spalten müssen übereinstimmen.
Msg 102, Level 15, State 1, Procedure umsatz_ausgleich, Line 68 [Batch Start Line 7]
Falsche Syntax in der Nähe von "END".

Dann die Frage, kann ich das überhaupt so machen oder muss ich einen Cursor definieren und umsatzid für jeden neuen Satz neu berechnen?

Ich bin noch nicht so fitt in STp, aber eine spannende Sache!

ALTER FUNCTION [dbo].[udfautowert]
(
-- Add the parameters for the function here
@tabname as nvarchar(50)
,@pk_col as nvarchar(50)
)
RETURNS int
AS
BEGIN
-- Declare the return variable here
DECLARE @autowert as int;
DECLARE @Sql NVARCHAR(MAX);

-- Add the T-SQL statements to compute the return value here
set @sql = N'select @autowert = max(' + @pk_col + N') from ' + @tabname

EXECUTE sp_executesql @SQL

-- Return the result of the function
RETURN @autowert +1

END

ALTER FUNCTION [dbo].[udfsaldo]
(
-- Add the parameters for the function here
@kontoid as int
)
RETURNS money
AS
BEGIN
-- Declare the return variable here
DECLARE @saldoumsatz as money

-- Add the T-SQL statements to compute the return value here
SELECT @saldoumsatz = SUM(betrag) from umsatz where KontoId = @kontoid

-- Return the result of the function
RETURN @saldoumsatz

END


Danke für Hilfe

Martin
 
Werbung:
Probiere als erstes, ob Dein Selectstatement für sich genommen funktioniert.

Die UDFautowert wirkt sehr umständlich, vom Ablauf her, als auch aus Sicht der Performance.
So macht man das nicht, auch wenn man es kann. Es hat wahrscheinlich negative Auswirkung bei vielen Sessions und hohen Einfügefrequenzen (also z.B. genau so ein Insertstatement wie Du es durchführen willst, sofern das Select darin mehrere Ergebnisse liefert). Am Ende führt das u.U. zu Table Locks bis Deadlocks.
Du wirst jetzt wahrscheinlich sagen, Dein System ist so klein, dass es keine Rolle spielt. Dann müsste ich antworten, ja, dann sie zu, dass es klein bleibt. Ich weiß nicht, ob man das will als Entwickler.

Normalerweise definiert man PK so, dass sie ohne weiteres Zutun beim Einfügen den Wert selbst generieren.

Generell kann man mit Cursorn in Funktionen Werte bestimmen, die die Funktion zurückliefert. Es sollte m.E. aus Performance / Ressourcengründen vermieden werden (letzte Wahl). Nach Möglichkeit ist ein komplexeres Select Statement oft besser, das alle Werte selbst holt. Gibt es ein solches Statement nicht, muss man eine Funktion nehmen oder ein anderes Verfahren/ Workaround finden.
 
Hi,

die Tabelle kommt aus ACCESS, ich kann, wenn ich richtig informiert bin, keinen Indetity PK nicht im nachhinein ändern bzw. setzen
Deshalb die Berechnung des Autowerts (wie es in Access heißt).

Meine Frage ist ja, ob ich den Insert mit einer Do While Schleife programmieren muss, oder ob das Select Statement für jeden neuen Datensatz den PK neu berechhet.

Also ist ein Cuirsor notwendig oder nicht-

Martin
 
Hallo Martin,
deine Daten liegen aber jetzt auf dem SQL (muss eine verknüpfte Tabelle sein) - anders würde deine Abfrage keinen Sinn ergeben.
die Tabelle kommt aus ACCESS, ich kann, wenn ich richtig informiert bin, keinen Identity PK nicht im nachhinein ändern bzw. setzen
Deshalb die Berechnung des Autowerts (wie es in Access heißt).
In SQL kannst du sehr wohl nachträglich eine Spalte auf Identity umstellen.
Dann benötigst du weder Trigger noch UDF's.
Gruß MDD
 
Hi,

ich hatte diesen Artikel gelesen


Wenn ich das richtig verstanden habe, geht das eben nicht direkt sondern über den Umweg einer neuen Tabelle.

Die Daten sind alle auf SQL.

Hier steht auch was, werde ich mir ansehen:


und das in meiner Entwicklungsumgebung testen.

Swingin' on and on!

Gruß

Martin
 
ja schon, aber das ist dann etwas unsauber...und die Indixes müssten dann auch angepasst werden...

Der Prozess wäre dann so:

Löschen alle FK und PK von Umsatz
Anlegen einer Tmp_umsatz Tabelle mit umsatzid als identity
Kopieren der Datensätze aus Umsatz (aller Spalten ohne umsatzid) in die Tmp-Tab.
(in der Tmp-Tab sollten jetzt alle Daten aus Umsatz sein. Die ID-Werte können aber abweichen, das ist aber nicht schlimm, Hauptsache, die Kontoid und der Umsatz-Betrag passt)
Löschen von Umsatz
Rename von Tmp_umsatz nach Umsatz
Anlegen von PK und FK. Ich werde den Prozess aber in mehrere Schritte aufteilen

Ich versuche es mal und werde berichten.
 
Hallo,

die Umstellung der PK-Col auf identity hat geklappt, wie beschrieben mit dem Umweg über eine TMP-Tabelle.
Das Script lief allerdings nicht so ohne weiteres, aber ich habe es dann vor allem mit der GUI im SSMS hinbekommen.

Dann widme ich mich jetzt wieder der ersten Fragestellung, allerdings ohne der Autowert-Funktion. Da habe ich aber jetzt keine Bedenken mehr.

Danke und Gruß!

Martin
 
Diese Umstellung war im Prinziop ziemlich einfach, weil die umsatzid nirgends verwendet wird.
Anders sähe das schon aus bei dem PK der PersonenDB, Personid.
Dies ist in n Beziehungen, Abfragen und FK drin.
Da werde ich mal ganz in Ruhe drüber nachdenken müssen.
 
So könnte es laufen:

der aktulle keineste Indexwert der Tabelle Person ist n.
Ich füge Dummy datensätze von 1 bis n-1 in eine Tabelle ein.
Dann kommendie echten Datan aus Person in diese Tabelle.
Dabei werden bei gaps in der Personid Dummy Personen eingefügt
Die Dummy Datensätze werden dann gelöscht.

Der Rest ist dann
 
Werbung:
Hallo,

die Umstellung der PK-Col auf identity hat geklappt, wie beschrieben mit dem Umweg über eine TMP-Tabelle.
Das Script lief allerdings nicht so ohne weiteres, aber ich habe es dann vor allem mit der GUI im SSMS hinbekommen.
Das SSMS ist die GUI und ist genau dafür gemacht: Zum Managen bzw. T-SQL Scripte zu schreiben. Alles andere ist da fehl am Platz. ADS ginge gerade noch so.
 
Zurück
Oben