Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   [MSSQL 2005] Speed Problem mit Update Trigger (https://www.delphipraxis.net/118281-%5Bmssql-2005%5D-speed-problem-mit-update-trigger.html)

ferby 4. Aug 2008 15:02

Datenbank: SQL SERVER 2005 • Zugriff über: Management Studio

[MSSQL 2005] Speed Problem mit Update Trigger
 
Hallo,

ich habe ein großes Performance Problem :-(


Also folgendes: Ich möchte sehr sehr sehr viele Datensätze aus einen Excel in eine SQL Tabele übertragen.
Das ganze funktioniert schon recht gut (und schnell).

Das Problem ist jetzt, das viele dieser Datensätze falsch sind und auf richtigkeit überprüft werden müssen.

Ein Beispiel wäre, das ich alle Datensätze die ein NULL Element enthalten rauswerfen muss, oder
das bestimmte Datensätze überprüft werden müssen, ob keine Buchstaben drin vorkommen, etc.

Was auch wichtig ist, das, sobald ein Fehler in den Daten auftritt, dass das insert sofort mit einer Fehlermeldung abbricht.

Ich habe das ganze mit einen Update Trigger so gelößt:

SQL-Code:
ALTER TRIGGER [dbo].[dbo.tr_t_xl_costcenter_cost_upd] on [dbo].[t_xl_costcenter_cost]
AFTER INSERT NOT FOR REPLICATION
AS
BEGIN
   
   SET NOCOUNT ON
   
   DECLARE @Error_Message nvarchar(500)

   SET @Error_Message = NULL
   
   -- delete NULL Elements
   Delete
   from dbo.t_xl_costcenter_cost
   where
   KST + IAS10 + MO + AMOUNT is NULL

   -- check if KST is nummeric
   if (select KST from dbo.t_xl_costcenter_cost where isnumeric(KST)=0) is not Null
   SET @Error_Message='The KST ''' + (select KST from dbo.t_xl_costcenter_cost where isnumeric(KST)=0) + ''' is not valid!'
   

        -- [..] noch ca. 10 weitere fehlerüberprüfungen

   -- prepare error message
   SET @Error_Message =   CHAR(10)+ CHAR(10) + N'---------------------------' + CHAR(10) + 
                     'IMPORT ERROR' + CHAR(10) + @Error_Message +
                     CHAR(10) + N'---------------------------' + CHAR(10) + CHAR(10)          

   -- throw error
   if @Error_Message is not NULL
   RAISERROR (@Error_Message, 11, 1)

END
Jedesmal wenn ein neuer Datensatz eingefügt wird, wird dieser validiert, wenn er falsch ist, bekommt der User eine Fehlermeldung um die Ohren.

Das Problem ist, das aber bei meiner Variante jedesmal ALLE Datensätze in der Datenbank Validiert werden.
Es kann aber immer nur der neueste falsch sein. Ich glaube daher braucht der SQL Server so lange.
(Wenn ich die Fehlerüberprüfungen raus nehme braucht er ca. 2 min, mit Fehlerüberprüfung 30min!)

Kennt jemand eine Methode, wie ich nur den aktuellen Datensatz prüfen kann (mit updated?!) und diesen Datensatz in die Tabelle aufnehme,
wenn er valide ist, ansosnten einen Error auslöse?


Mir fällt irgendwie nichts ein

NormanNG 4. Aug 2008 15:16

Re: [MSSQL 2005] Speed Problem mit Update Trigger
 
hi,

jedesmal alle datensätze zu validieren ist natürlich gelinde gesagt "unperformant" :-D

innerhalb eines triggers verwendet man die virtuellen tabellen "inserted" und "deleted" - such mal in den bol danach...

ferby 4. Aug 2008 15:52

Re: [MSSQL 2005] Speed Problem mit Update Trigger
 
Hello,

danke,

leider geht das auch nicht wirklich schneller :-(


habe mir sowas zusammengebasstelt

SQL-Code:
   -- delete NULL Elements
   if (select count(*) from inserted where KST + IAS10 + MO + AMOUNT is NULL) is not Null
   Delete from dbo.t_xl_costcenter_cost where KST + IAS10 + MO + AMOUNT is NULL




Mir wird wohl nix anderes übrig bleiben, als alle Daten hineinzuladen und dann eine validier Prozedur aufzurufen......




EDIT: Glaub die NULL Elemente rauswerfen ist das aufwenidgste von allen, der rest geht zimlich schnell....
Werd es wohl so machen, dass ich die überprüfungen im Trigger mache und am Ende ein Querry zum löschen alle NULL elemente abschicke.
So komm ich auf ca. 5 min

NormanNG 4. Aug 2008 16:00

Re: [MSSQL 2005] Speed Problem mit Update Trigger
 
hi,

Zitat:

if (select count(*) from inserted where KST + IAS10 + MO + AMOUNT is NULL) is not Null
Delete from dbo.t_xl_costcenter_cost where KST + IAS10 + MO + AMOUNT is NULL
damit hast du ja auch nicht wirklich viel geändert.
ich würde es so versuchen:
SQL-Code:
 
  Delete
   from dbo.inserted
   where KST is null

  Delete
   from dbo.inserted
   where IA10 is null

  Delete
   from dbo.inserted
   where MO is null

  Delete
   from dbo.inserted
   where AMOUNT is null
wenn dann noch die richtigen indizes vorhanden sind, sollte es schneller werden.

oder:
wenn es nur um die Übernahme der Daten aus Excel geht, reicht ja doch auch, dein Original-Script (aus dem Trigger) einmal nach dem Import aller Daten auszuführen :gruebel:

ferby 4. Aug 2008 16:45

Re: [MSSQL 2005] Speed Problem mit Update Trigger
 
Das Problem mit den 1x ausführen ist folgedes:
Die Daten werden per Access importiert. Wenn Ich ein RaiseError mache, dann wird diese fehlermeldung den Benutzer in Access angezeigt.

Lager ich das ganze in eine Prozedur aus, und löse dort den fehler aus, kommt bei Access keine Meldung :-(
Und der Benutzer weiß nichts von einer Fehleingabe


EDIT

Delete
from inserted
where AMOUNT is null



ERROR:
The logical tables INSERTED and DELETED cannot be updated.

NormanNG 4. Aug 2008 17:10

Re: [MSSQL 2005] Speed Problem mit Update Trigger
 
hi,

Zitat:

EDIT

Delete
from inserted
where AMOUNT is null
sorry,
du musst die original-tabelle und "inserted" über den (primary) key joinen

SQL-Code:
Delete cc
from dbo.t_xl_costcenter_cost cc
join inserted i on i.<PK> = cc.<PK>
where KST is NULL

Jelly 4. Aug 2008 19:58

Re: [MSSQL 2005] Speed Problem mit Update Trigger
 
Zitat:

Zitat von NormanNG
du musst die original-tabelle und "inserted" über den (primary) key joinen

Oder einen INSTEAD OF Trigger verwenden. Dann kann man sich selbst um das Inserten kümmern... Die Prüfung dann nach dieser Art:

SQL-Code:
Insert into Deine Tabelle
select * from inserted where AMOUNT is null and KST is null   usw.

nahpets 5. Aug 2008 08:51

Re: [MSSQL 2005] Speed Problem mit Update Trigger
 
Hallo,

irgendwie habe ich das Problem nicht verstanden:

Du möchtest doch beim Insert nur den Satz prüfen, der gerade eingefügt wird. Bei Deiner ursprünglichen Logik wird aber jedesmal die gesamte Tabelle geprüft, auch wenn nur der neueste Satz fehlerhaft sein kann, dies erhöht natürlich bei vielen Datensätzen die Laufzeit rapide.

Müsste nicht sowas in der Art
SQL-Code:
if inserted.KST + inserted.IAS10 + inserted.MO + inserted.AMOUNT is NULL)
RAISERROR ('Fehlermeldung', 11, 1)
ausreichen?

Kenne mich mit der Syntax des SQL-Servers überhaupt nicht aus, daher hier nur Pseudocode.

Stephan

Jelly 5. Aug 2008 12:14

Re: [MSSQL 2005] Speed Problem mit Update Trigger
 
Das Raiserror bricht den Import aber wohl komplett ab. Ich bin davons ausgegangen, dass falsche Datensätze übersprungen werden sollen.

Was ist denn nun gemeint?

DeddyH 5. Aug 2008 12:16

Re: [MSSQL 2005] Speed Problem mit Update Trigger
 
Zitat:

Zitat von ferby (#1)
Was auch wichtig ist, das, sobald ein Fehler in den Daten auftritt, dass das insert sofort mit einer Fehlermeldung abbricht.



Alle Zeitangaben in WEZ +1. Es ist jetzt 18:22 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz