| 

.NET C# Java Javascript Exception

0
Ich will in einer großen Tabelle (mehrere 10.000 Datensätze) mittels einer Stored Procedure Datensätze in die Datenbank übertragen. Während der Übertragung soll die Stored Procedure gleich direkt abprüfen, ob der Satz bereits enthalten ist, und nur wenn er nicht enthalten ist soll der INSERT erfolgen.

Der Index der Datensätze erstreckt sich in diesem Fall über mehrere Felder (Datum, Personalnummer, Buchungstyp).

Wie kann ich das performant am Besten lösen?
News:
27.09.2011
commänder 420 1 7
4 Antworten
1
Mittels einer Stored Procedure kann man das so lösen:
CREATE PROCEDURE dbo.sp_test 
@col1 NVARCHAR(50), @col2 NVARCHAR(50), @col3 NVARCHAR(50), @col4 NVARCHAR(50)
AS
BEGIN
SET NOCOUNT ON

IF EXISTS (SELECT 1 FROM bulkinsert WHERE (col1 = @col1) and (col3 = @col3) and (col4 = @col4) )
RAISERROR('This value already exists.', 11, 1)
ELSE
INSERT bulkinsert(col1,col2,col3,col4) VALUES(@col1,@col2,@col3,@col4)
END
GO

Beziehungsweise so, falls keine Fehlermeldung erfolgen soll:
create PROCEDURE dbo.sp_test 
@col1 NVARCHAR(50), @col2 NVARCHAR(50), @col3 NVARCHAR(50), @col4 NVARCHAR(50)
AS
BEGIN
SET NOCOUNT ON

IF not EXISTS (SELECT 1 FROM bulkinsert WHERE (col1 = @col1) and (col3 = @col3) and (col4 = @col4) )
INSERT bulkinsert(col1,col2,col3,col4) VALUES(@col1,@col2,@col3,@col4)
END
GO

Wobei hier col1, col3 und col4 die Eindeutigkeit eines Datensatzes bilden.

PS: Schade, dass man seine Antwort immer noch nicht editieren kann.
27.09.2011
Jürgen Luhr 7,1k 2 9
Ach ja: bulkinsert ist der Tabellenname. Was besseres viel mir gerade nicht ein ;o)
Jürgen Luhr 27.09.2011
4
Wenn du einen MS SQL Server einsetzt, empfehle ich MERGE.

Ob es für andere DBS eine äquivalente Funktion gibt, kann ich dir nicht sagen.
27.09.2011
Andreas Richter 1,7k 1 2 8
MERGE ist der richtige Weg.
FrankHell 28.09.2011
0
Bei jedem Datensatz zu prüfen, ob er bereits vorhanden ist wäre sehr langsam.
Aber ich verstehe das Problem nicht so ganz. Meine Vorgehensweise wäre, einen Index auf die Schlüsselfelder und einen uniqueness constraint zu setzen. Damit ist gewährleistet, dass es keine doppelten Einträge gibt.
Du schreibst, dass es bereits einen Index über mehrere Felder gibt. Dann brauchst du den doch nur auf "Is Unique" setzen.
Eine Testtabelle, die ich erzeugt habe hat folgenden Index:
CREATE UNIQUE NONCLUSTERED INDEX [IX_bulkinsert] ON [dbo].[bulkinsert] 
(
[col1] ASC,
[col3] ASC,
[col4] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

Damit ist die Eindeutigkeit der Spalten col1, col3, col4 gewährleistet.
27.09.2011
Jürgen Luhr 7,1k 2 9
Ein UNIQUE Index funktioniert in meinem Fall leider nicht, da durch manuelle Bearbeitungen durchaus doppelte Sätze entstehen dürfen. Nur der Import soll doppelte Sätze vermeiden. Was schon drin ist, soll einfach nicht nochmals rein.
commänder 27.09.2011
0
Hallo commänder,

ich denke es fehlen noch ein paar Informationen um Dein Problem "optimal" zu lösen.
Soll die SP einen (Massen)Import, wenn ja von wo - interne Tabelle, externe Tabelle, ..., realisieren, oder sollen einzelne Datensätze eigefügt werden?

Möchtest Du eine Universallösung oder kannst Du ein Datenbanksystem festlegen?

Gruß, Sam
28.09.2011
samc 1 1
//--- allgm. Lösung

insert into tb_destination
select * from tb_source
where id in ( select s.id from
tb_source s
,tb_destination d
where
d.datum = s.datum
and
d.personalnummer = s. personalnummer
and
d.buchungstyp = s.buchungstyp
)
samc 28.09.2011
Danke der Rückfrage. Nein, es ist kein Massen-Import, eher ständige einzelne INSERTs. Es laufen verschiedene Programme und Windows-Services, die u.a. Daten von BDE-Geräten abrufen, und diese dann in die Datenbank beamen sollen. Mal ist es ein einzelner Satz, mal sind es mehrere hundert. Und wenn jemand eben sein Terminal resettet, dann werden alle Daten nochmals gesendet, auch wenn diese bereits schon mal übertragen worden sind.
commänder 28.09.2011
Ich bin "Herr über die Datenbank", und kann dort eigentlich alles machen, Datenbank-System ist ein SQL-Server 2005 aufwärts.

Bisher habe ich die Logik mehr schlecht als recht in den Clients, die die INSERTs machen. Da es aber mehrere Programme in verschiedenen Sprachen sind (Web, Windows, Mobil) will ich die Logik weg vom Client in den Server verschieben, eben mittels einer Stored Procedure.
commänder 28.09.2011

Stelle deine Sql-server-Frage jetzt!