Alphaman 10 Geschrieben 17. Februar 2012 Melden Teilen Geschrieben 17. Februar 2012 Hi Leute, ich habe ein mittelgroßes Problem mit unseren INSERT/UPDATE/DELETE Triggern die in eine andere Datenbank die Änderung von einer Tabelle mit schreibt. Ich habe den Trigger bereits auf das minimum reduziert so das er beim Update nur noch "Print 'Hello'" ausgeben soll. Das dies natuerlich keine Sinn macht ist mir natürlich klar, aber dies ist nur zum testen. Der Fehler der bei dem Programm ausgegeben wird bzw. was der SQL Connection liefert lautet: Ein Trigger hat ein Resultset zurückgegeben und/oder wurd mit SET NOCOUNT OFF ausgeführt, während ein anderes ausstehendes Resultset aktiv war. USE [MyDatabase] GO /****** Object: Trigger [dbo].[TRG_MyTable_Update] Script Date: 02/17/2012 15:13:49 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER TRIGGER [dbo].[TRG_MyTable_Update] ON [dbo].[MyTable] FOR UPDATE AS BEGIN Print 'Hallo' END In C# greifen wir mittels MARS Connection und einen DataReader auf die Tabellendaten zu. Innerhalb einer Schleife werden die Daten ausgelesen uns mittels eines Update Befehls Felder aktualisiert. Dabei knallt es wenn auf der Tabelle ein Trigger ist. Hier ein Auszug des Programmcodes: using (SqlConnection con2 = new SqlConnection(TriggerTest.Properties.Settings.Default.con2String)) { con2.Open(); using (SqlTransaction tran = con2.BeginTransaction()) { using (SqlCommand cmdR4 = con2.CreateCommand()) { cmdR4.Transaction = tran; cmdR4.CommandType = System.Data.CommandType.Text; cmdR4.CommandText = " SELECT tbl1.ID1, tbl1.ID2 " + " FROM [db1].[dbo].tbl1 " + " INNER JOIN [db2].[dbo].tbl2 " + " ON tbl1.ID1 = tbl2.ID1 " + " WHERE (((tbl1.Status) = '1') " + " AND ((tbl1.Spalten_ID) < " + this.SpaltenWert + " ) " + " AND ((tbl1.DatumVon) >= '2011-12-01') " + " AND ((tbl1.DatumBis) <= '2011-12-31') " + " AND ((tbl2.Erledigt) = 1)) " + " GROUP BY tbl1.ID1, tbl1.ID2 "; using (SqlDataReader drR4 = cmdR4.ExecuteReader()) { // System.Threading.Thread.Sleep(20000); while (drR4.Read()) { ID15 = drR4["ID1"].ToString(); ID25 = drR4["ID2"].ToString(); this.strQuery = string.Empty; this.strQuery = " UPDATE [db2].[dbo].tbl2 set " + " Erledigt = 0, " + " Datum = '2011-12-31' " + " where ID1 = '" + ID15 + "' " + " AND ID2 = '" + ID25 + "' "; using (SqlCommand cmdRr4 = con2.CreateCommand()) { cmdRr4.Transaction = tran; cmdRr4.CommandType = System.Data.CommandType.Text; cmdRr4.CommandText = this.strQuery; cmdRr4.ExecuteNonQuery(); } label2.Text = "Anzahl: " + counterR4.ToString(); Application.DoEvents(); counterR4++; } } } tran.Commit(); } } Der SQL Connectionstring lautet: Data Source=LOCALHOST\SQLEXPRESS; Initial Catalog =db1; Integrated security=sspi; Application Name = TriggerTest;MultipleActiveResultSets=True; Ich hoffe das mir jemand helfen kann. Ich habe wirklich schon mehrere Tage danach gegoogled und getestet aber ich bekomme es nicht zum laufen und wir bräuchten die Trigger schon sehr um die Änderungen die an der Daten nachvollziehen zu können bzw. Änderungen wieder rückgängig zu machen. Dickes Dickes Danke schon mal für Eure Hilfe. Gruß, Alpha Zitieren Link zu diesem Kommentar
phoenixcp 10 Geschrieben 21. Februar 2012 Melden Teilen Geschrieben 21. Februar 2012 Mahlzeit Wenn ihr schon SQL Server der neueren Versionen verwendet, warum dann nicht auch deren Features? Change Tracking Wozu was eigenes bauen, wenn man auch oob-Features verwenden kann? Vielleicht einfach nur als Anregung. Gruß Carsten Zitieren Link zu diesem Kommentar
Alphaman 10 Geschrieben 22. Februar 2012 Autor Melden Teilen Geschrieben 22. Februar 2012 Hi, erstmal danke für die Antwort. Dies ist natürlich auch eine Möglichkeit die zu loggen. Einige Probleme habe ich trotzdem noch: 1. Habe ich keine Info genau was geändert wurde. Dies kann man schon bei einem Trigger machen mittels before und after Update wenn man beides in eine Tabelle schreibt. 2. Ich sehe keine Möglichkeit dies zeitlich einzuschränken bzw. sehr einfach einzusehen wann welche Daten geändert wurden (Datum / Uhrzeit). Soweit ich gesehen habe gibt es die ÄnderungsID die sich immer um einen Wert nach oben zählt, aber man kann nicht sehen wann welche ID usw. gewesen ist. Evtl. habe ich etwas übersehen. Evtl. hast Du/Ihr auch Tipps wie man dies lösen könnte. Dickes Danke schon mal. Gruß, Alpha Zitieren Link zu diesem Kommentar
tobee 10 Geschrieben 24. Februar 2012 Melden Teilen Geschrieben 24. Februar 2012 Ich hab mal versucht, das nachzubauen, bei mir gings sofort (SQL 2008 R2 Enterprise) Zitieren Link zu diesem Kommentar
Alphaman 10 Geschrieben 24. Februar 2012 Autor Melden Teilen Geschrieben 24. Februar 2012 H tobee, Ich hab mal versucht, das nachzubauen, bei mir gings sofort (SQL 2008 R2 Enterprise) Wieviel Testzeilen wolltest du denn auf einmal verändern? Der Fehler bei > 4000 Zeilen aufgetreten. Als SQL Server nehmen wir derzeit 2008 R2 Express (Standard soll demnächst aber folgen). Wäre nett wenn du das selbe nochmal mit mehr Daten probieren könntest und kurze Info zurück gibt. Danke. Gruß, Alpha Zitieren Link zu diesem Kommentar
hh2000 10 Geschrieben 26. Februar 2012 Melden Teilen Geschrieben 26. Februar 2012 Moin, ich würde erstmal testweise ein Update-Command direkt im Query Analyser abschicken, um evlt. Sperrungen o.a. die der Client auslösen könnte, auszuschliessen. Sollte das Problem dann immer noch auftauchen, so würde ich auch erstmal den Trigger vermuten. Du könnstest dann statt des AFTER-Triggers, einen INSTEAD OF-Trigger benutzen. Deine Änderungen/Exporte in eine Log-Tabelle etc. kannst mit Hilfe von Inserted und Deleted anfertigen. Anschließend must Du aber selbst dafür sorgen (im Unterschied zum AFTER-Trigger), dass die gewünschten Werte in Deine Tabelle eingetragen werden. CREATE TRIGGER TabelleUpd ON [dbo].[Tabelle] INSTEAD OF UPDATE AS -- Hier Deine Statements, Transcaction, Fehlerbehandlung etc -- Alte Werte sind in deleted enthalten und könnten in eine LogTabelle geschrieben werden UPDATE Tabelle SET Tabelle.SpalteA = inserted.SpalteA, Tabelle.SpalteB = inserted.SpalteB Tabelle.UpdateUser = SUSER_SNAME(), Tabelle.UpdateZeit = CURRENT_TIMESTAMP FROM Tabelle INNER JOIN inserted ON Tabelle.ID = inserted.ID END Mittels @@ERROR und RAISERROR (siehe Onlinehilfe) in den SQL Statements kannst du dann auch den Fehler besser eingrenzen, bzw. ausgeben. Gruß Kai Zitieren Link zu diesem Kommentar
tobee 10 Geschrieben 28. Februar 2012 Melden Teilen Geschrieben 28. Februar 2012 Hast Du schon mal über partitioned tables nachgedacht? Zitieren Link zu diesem Kommentar
phoenixcp 10 Geschrieben 28. Februar 2012 Melden Teilen Geschrieben 28. Februar 2012 Wieviel Testzeilen wolltest du denn auf einmal verändern? Der Fehler bei > 4000 Zeilen aufgetreten. Als SQL Server nehmen wir derzeit 2008 R2 Express (Standard soll demnächst aber folgen). Hm, das stimmt mich schon bedenklich... mit größeren Datenmengen spielen, Express Editionen einsetzen und dann über Mengen reden. Ich möchte nicht die Hand ins Feuer legen das die Express Edition ab einem gewissen Datenbestand bestimmte Probleme bekommen kann. Zitieren Link zu diesem Kommentar
Empfohlene Beiträge
Schreibe einen Kommentar
Du kannst jetzt antworten und Dich später registrieren. Falls Du bereits ein Mitglied bist, logge Dich jetzt ein.