Merge Anweisung

SQLSchnecke

Benutzer
Beiträge
8
Hallo Zusammen,

ich habe ein Problem und weis langsam nicht mehr weiter.
Ich habe eine Merge Anweisung, die eine Tabelle aktualisieren soll.
Also wenn der Datensatz vorhanden ist, dann aktualisieren, wenn er nicht vorhanden ist soll er erstellt werden oder wenn er in der Source Tabelle nicht vorhanden ist, soll der DS gelöscht werden.

Ich habe die Anweisungen einzeln ausprobiert. Dies funktionieren.
Wenn ich allerdings alles zusammen laufen lasse, dann funktioniert die Update Funktion nur bei ersten DS die anderen werden neu angelegt.

Hier die SQL Anweisung:

upload_2016-6-21_16-27-20.png

Kann mir zufällig jemand helfen?

Vielen Dank

Die SQLSchnecke


PS: ich habe das Gefühl, dass die Update Anweisung noch nicht ganz fertig ist mit dem durchlaufen aller DS und meint dann, diese sind nicht vorhanden und legt sie neu an.
 
Werbung:
Also bei MSSQL ist das so das ein Trigger pro INSERT / UPDATE / DELETE immer nur einmal feuert. Das heißt das der Trigger sich immer auf alle betroffenen Datensätze beziehen muss, sonst wird eben ggf. nur einer verarbeitet.

Leider nutze ich MERGE nicht, ich könnte mir aber denken das der Code oben vereinfacht dargestellt ist und du z.B. erstmal eine Variable mit einer ID aus Insterted füllst oder dergleichen. Dann beziehst du dich nämlich nur auf einen Datensatz.
 
Hier ein Beispiel (so in etwa liefen früher mal meine Log Trigger):
Code:
CREATE TABLE tbl_test(
   pk UNIQUEIDENTIFIER,
   wert INT
   );

CREATE TABLE tbl_test_log(
   fk UNIQUEIDENTIFIER,
   datum DATETIME,
   wert INT
   );
Code:
CREATE TRIGGER   [dbo].[trigger_test_log]
   ON       [dbo].[tbl_test]
   FOR INSERT, UPDATE, DELETE
AS

BEGIN
   SET NOCOUNT ON;

   DECLARE   @pk UNIQUEIDENTIFIER,
       @wert INT

   SELECT   @pk = pk,
       @wert = wert
   FROM   INSERTED

   INSERT INTO tbl_test_log(fk,datum,wert) VALUES(@pk,getdate(),@wert)
END;
Durch den Zwischenschritt Variablen befüllen hole ich nur einen Wert aus der Tabelle INSERTED, solange nur eine Zeile durch den Insert oder Update betroffen ist, ist das auch kein Problem.
Code:
INSERT INTO tbl_test(pk,wert) VALUES(newid(),1);
INSERT INTO tbl_test(pk,wert) VALUES(newid(),2);
INSERT INTO tbl_test(pk,wert) VALUES(newid(),3),(newid(),4);
Im letzten Befehl füge ich mit einem Insert zwei Zeilen ein, der Trigger feuert nur einmal und ich habe dann zwei Zeilen in INSERTED. Funktionieren tut es, es "verschluckt" nur eine Aktion.

tbl_test
494413EB-9FEA-49C1-8694-CE668116917F 1
8D52D1B1-EB96-473D-BBDA-F704943BBDC9 2
5D8E3513-B03E-4B6D-9E58-CBD79454AA58 3
11B42519-277E-4FA0-B54E-158A87209766 4

tbl_test_log
494413EB-9FEA-49C1-8694-CE668116917F 2016-06-22 12:02:48.953 1
8D52D1B1-EB96-473D-BBDA-F704943BBDC9 2016-06-22 12:02:48.953 2
5D8E3513-B03E-4B6D-9E58-CBD79454AA58 2016-06-22 12:13:16.753 3
 
Vielen Dank für dein Beispiel.
Leider komm ich da auch nicht weiter.

Hast du zufällig noch eine Idee, wie man zwei Tabellen abgleicht und dann auf die Haupttabelle ein Insert, Update und Delete macht?
 
Naja du kannst das natürlich in einzelne Statements packen, MERGE ist ja nur eine Abkürzung um sich Inserts, Updates, und Delete mit viel Schreibarbeit zu ersparen. Dennoch würde ich eher die Ursache für das Problem suchen.

Wenn ich das richtig sehe funktioniert dein Merge auserhalb des Triggers? Kannst du vielleicht mal den gesammten Trigger Code posten?
 
ALTER TRIGGER [dbo].[ImportinterneKunden] ON [dbo].[TemporreInterneKunden]

AFTER INSERT,Update,Delete

AS

merge into customer

using (select * from TemporreInterneKunden) Temp

on (temp.samaccountname = customer.samaccountname)

when matched and(temp.samaccountname = customer.samaccountname) then update set

customer.Nachname = Temp.Nachname,

customer.abteilung = Temp.abteilung,

customer.abteilungsnr = Temp.abteilungsnr,

customer.Teamname = Temp.Teamname,

customer.teamnr = Temp.teamnr,

customer.BusinessFunktion = Temp.BusinessFunktion,

customer.Faxnummer = Temp.OfficeFaxNummer,

customer.Organisationseinheit = Temp.Organisationseinheit,

customer.OrganisationseinheitNr = Temp.OrganisationseinheitNr,

customer.OfficeTelefon = Temp.OfficeTelefon,

customer.OfficeMobilTelefon = Temp.OfficeMobilTelefon,

customer.Officeemail = Temp.Officeemail,

customer.vollername = temp.vollername,


when not matched by Target then

insert (recid,vorname,nachname,SAMAccountName,OfficeTelefon,OfficeMobilTelefon,OfficeFaxNummer,Officeemail,BusinessFunktion,Organisationseinheit,OrganisationseinheitNr,Abteilung,Abteilungsnr,TeamName,Teamnr,Stellennr,KundenTypName,KundenTypID)

values (temp.recid,temp.vorname,temp.nachname,temp.SAMAccountName,temp.OfficeTelefon,temp.OfficeMobilTelefon,temp.OfficeFaxNummer,temp.Officeemail,temp.BusinessFunktion,temp.Organisationseinheit,temp.OrganisationseinheitNr,temp.Abteilung,temp.Abteilungsnr,temp.TeamName,temp.Teamnr,temp.Stellennr,'Interner Kunde','93dd10617f3f73bc7e41fd4a1ea4b9e0cce022eb0f')

WHEN NOT MATCHED BY SOURCE then Delete

;
 
Hm das bezieht sich ja nicht auf Inserted oder Deleted Tabellen, sollte also einfach plump ausgeführt werden. Wenn du es außerhalb des Triggers ausführst läuft es auch?

Wenn ich mir MERGE so angucke scheint es diverse Probleme zu geben. Vielleicht fährst du mit eigenen Update-, Insert- und Delete-Statements besser. Ideen habe ich eigentlich keine mehr woran es liegen könnte.
https://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/
 
Ja außerhalb des Triggers laufen die Sachen. Ich benötige den Trigger deswegen, weil die Merge Anweisung immer nach einem Import laufen soll. Leider weis ich mir nicht anders zu helfen, als den Trigger als ,,Anstoß" zu verwenden.
 
Das habe ich auch schon versucht. Leider ohne Erfolg. Es wird wieder nur der erste DS bearbeitet. Alle anderen werden gelöscht und neu angelegt.

Ich habe auch versucht nur das Delete in eine Procedur zu stecken auch das hat nichts gebracht.

Trotzdem vielen Dank für deine Hilfe.

weist du zufällig, wie man eine Prodecur über ein cmd aufruft?
 
Werbung:
Zurück
Oben