none
SQL Server 2008 - bereits vorhandenen Datensatz in DB überschreiben RRS feed

  • Frage

  • Gibt es eine Möglichkeit, um bei einem Import in eine DB einen Datensatz zu überschreiben, wenn dieser schon vorhanden ist.

    bsp.:

    Belegnummer, Belegdatum, Kunde, Betrag

    ^4711^,^01.04.2010^,^TestKunde^,^200^

    Wenn jetzt wieder ein Datensatz mit der Belegnummer  "4711" kommt, soll dieser den vorhandenen überschreiben.

    ^4711^,^16.01.2011^,^TestKunde2^,^1254^

     

    Vielen Dank im Voraus.

     

    Moin,

    ich vermute, meine Problematik nicht korrekt beschrieben zu haben.

    "Ich" erhalte täglich eine txt-Datei mit zahlreichen Datensätzen. Diese werden in eine Tabelle eingelesen. Leider führt das aktuelle Import-Verfahren dazu, dass es im laufe der Zeit mehrere Datensätze mit der selben Belegnummer "4711" geben kann, weil z.B. für die Weiterverarbeitung ein Datensatz mit älteren Werten menötigt wird. Es soll (darf) aber immer nur einen Datensatz mit dieser Nummer geben.

    Ich suche / benötige also eine Art "replace"-Funktion beim Import meiner Datensätze.

     


    Dienstag, 10. Mai 2011 10:40

Antworten

  • Dienstag, 10. Mai 2011 10:55
  • Hi,

    etwas allgemeiner und nicht auf SQL Server 2008 (inkl. R2) beschränkt (ja, ich weiß, dass Du SQL 2008 hast, andere aber ggfs. nicht :):

      UPDATE <Tabelle> ( ... ) SET ... FROM <ImportTabelle> WHERE <ImportTabelle>.<IdSpalte> IN ( SELECT <IdSpalte> FROM <Tabelle> )

      INSERT INTO <Tabelle> ( ... ) SELECT ... FROM <ImportTabelle> WHERE <IdSpalte> NOT IN ( SELECT <IdSpalte> FROM <Tabelle> )

    Syntax könnte noch fehlerhaft sein, da ichs grade nicht ausprobieren kann. Der Ansatz sollte damit aber (hoffentlich^^) ersichtlich sein.

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Dienstag, 10. Mai 2011 11:04
    Moderator
  • Hallo Eggi,

    das macht doch das Beispiel von Stefan doch

    USE tempdb
    GO
    
    -- Zu importierende Daten
    CREATE TABLE #Import
    (
    	Belegnummer	varchar(10),
    	Belegtext	varchar(50)
    )
    GO
    
    -- Deine Tabelle mit Belegdaten
    DECLARE @Test TABLE
    (
    	BelegNummer	varchar(10)	PRIMARY KEY CLUSTERED,
    	BelegText	varchar(50)
    )
    
    INSERT INTO @Test
    (BelegNummer, BelegText)
    VALUES
    ('123456', 'BelegText10'),
    ('234567', 'BelegText20'),
    ('345678', 'BelegText30')
    
    
    INSERT INTO #Import
    (Belegnummer, Belegtext)
    VALUES
    ('123456', 'BelegText1'),
    ('234567', 'BelegText2'),
    ('345678', 'BelegText3'),
    ('123456', 'BelegText4'),
    ('987654', 'NOCH EIN BELEGTEXT')
    
    -- Was haben wir jetzt?
    SELECT 'Import', * FROM #Import
    SELECT 'Bestand', * FROM @Test
    
    -- Aktualisierung der Daten (last win)
    DECLARE	@Belegnummer	varchar(10)
    DECLARE	@BelegText	varchar(50)
    
    DECLARE	c CURSOR
    FOR
    	SELECT	BelegNummer, BelegText
    	FROM	#Import
    
    OPEN c
    
    FETCH NEXT FROM c INTO @BelegNummer, @BelegText
    WHILE @@FETCH_STATUS <> -1
    BEGIN
    	IF EXISTS (SELECT TOP 1 * FROM @Test WHERE BelegNummer = @Belegnummer)
    	BEGIN
    		PRINT 'Aktualisierung muss durchgeführt werden...'
    		UPDATE	@Test
    		SET	Belegtext = @BelegText
    		WHERE	Belegnummer = @Belegnummer
    	END
    	
    	ELSE
    	
    	BEGIN
    		PRINT 'Daten müssen neu eingetragen werden ...'
    		INSERT INTO @Test
    		(BelegNummer, BelegText)
    		VALUES
    		(@Belegnummer, @BelegText)
    	END
    	
    	FETCH NEXT FROM c INTO @BelegNummer, @BelegText
    END
    
    CLOSE c
    DEALLOCATE c
    
    -- Und was haben wir jetzt
    SELECT 'Import', * FROM #Import
    SELECT 'Bestand', * FROM @Test
    
    DROP TABLE #Import
    
    

    !

    Mein Beispiel verdeutlicht, wie man bei solchen Exporten vorgehen kann. Ich gebe aber zu bedenken, dass diese Variante eher schlecht ist, da Du ja bei mehrfachem Vorkommen der Belegnummer immer nur den letzten Eintrag haben wirst! Der Output des Scripts verdeutlicht das ja auch:

    Belegnummer Belegtext
    ------ ----------- --------------------------------------------------
    Import 123456   BelegText1
    Import 234567   BelegText2
    Import 345678   BelegText3
    Import 123456   BelegText4
    Import 987654   NOCH EIN BELEGTEXT
    
        BelegNummer BelegText
    ------- ----------- --------------------------------------------------
    Bestand 123456   BelegText10
    Bestand 234567   BelegText20
    Bestand 345678   BelegText30
    
    Aktualisierung muss durchgeführt werden...
    Aktualisierung muss durchgeführt werden...
    Aktualisierung muss durchgeführt werden...
    Aktualisierung muss durchgeführt werden...
    Daten müssen neu eingetragen werden ...
        Belegnummer Belegtext
    ------ ----------- --------------------------------------------------
    Import 123456   BelegText1
    Import 234567   BelegText2
    Import 345678   BelegText3
    Import 123456   BelegText4
    Import 987654   NOCH EIN BELEGTEXT
    
        BelegNummer BelegText
    ------- ----------- --------------------------------------------------
    Bestand 123456   BelegText4
    Bestand 234567   BelegText2
    Bestand 345678   BelegText3
    Bestand 987654   NOCH EIN BELEGTEXT
    
    

    Uwe Ricken

    MCIT Database Administrator 2005
    MCIT Database Administrator 2008
    MCTS SQL Server 2005
    MCTS SQL Server 2008, Implementation and Maintenance
    db Berater GmbH
    http://www-db-berater.de
    Dienstag, 10. Mai 2011 12:28

Alle Antworten

  • Dienstag, 10. Mai 2011 10:55
  • Hi,

    etwas allgemeiner und nicht auf SQL Server 2008 (inkl. R2) beschränkt (ja, ich weiß, dass Du SQL 2008 hast, andere aber ggfs. nicht :):

      UPDATE <Tabelle> ( ... ) SET ... FROM <ImportTabelle> WHERE <ImportTabelle>.<IdSpalte> IN ( SELECT <IdSpalte> FROM <Tabelle> )

      INSERT INTO <Tabelle> ( ... ) SELECT ... FROM <ImportTabelle> WHERE <IdSpalte> NOT IN ( SELECT <IdSpalte> FROM <Tabelle> )

    Syntax könnte noch fehlerhaft sein, da ichs grade nicht ausprobieren kann. Der Ansatz sollte damit aber (hoffentlich^^) ersichtlich sein.

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Dienstag, 10. Mai 2011 11:04
    Moderator
  • Hi,

    etwas allgemeiner und nicht auf SQL Server 2008 (inkl. R2) beschränkt (ja, ich weiß, dass Du SQL 2008 hast, andere aber ggfs. nicht :):

      UPDATE <Tabelle> ( ... ) SET ... FROM <ImportTabelle> WHERE <ImportTabelle>.<IdSpalte> IN ( SELECT <IdSpalte> FROM <Tabelle> )

      INSERT INTO <Tabelle> ( ... ) SELECT ... FROM <ImportTabelle> WHERE <IdSpalte> NOT IN ( SELECT <IdSpalte> FROM <Tabelle> )

    Syntax könnte noch fehlerhaft sein, da ichs grade nicht ausprobieren kann. Der Ansatz sollte damit aber (hoffentlich^^) ersichtlich sein.

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community


    Moin,

    ich vermute, meine Problematik nicht korrekt beschrieben zu haben.

    "Ich" erhalte täglich eine txt-Datei mit zahlreichen Datensätzen. Diese werden in eine Tabelle eingelesen. Leider führt das aktuelle Import-Verfahren dazu, dass es im laufe der Zeit mehrere Datensätze mit der selben Belegnummer "4711" geben kann, weil z.B. für die Weiterverarbeitung ein Datensatz mit älteren Werten menötigt wird. Es soll (darf) aber immer nur einen Datensatz mit dieser Nummer geben.

    Ich suche / benötige also eine Art "replace"-Funktion beim Import meiner Datensätze.

    Gruß Eggi

    Dienstag, 10. Mai 2011 12:00
  • Moin Eggi,

    ich würde MERGE einsetzen.

    Falls Du die Datenbereinigung nach dem Import durchführen möchtest, wie entscheidest Du welchen Datensatz zu löschen ist, wenn bereits mehrere Datensätze mit der gleichen ID in der Tabelle vorhanden sind?

    Dienstag, 10. Mai 2011 12:21
  • Hallo Eggi,
    ich würde die Datensätze in eine leere Tabelle importieren und das Ergebnis dann mit MERGE in die Zieltabelle schreiben!

    Einen schönen Tag noch,
    Christoph


    Microsoft SQL Server MVP
    http://www.insidesql.org/blogs/cmu

    Dienstag, 10. Mai 2011 12:22
  • Hi,
    "Ich" erhalte täglich eine txt-Datei mit zahlreichen Datensätzen. Diese werden in eine Tabelle eingelesen. Leider führt das aktuelle Import-Verfahren dazu, dass es im laufe der Zeit mehrere Datensätze mit der selben Belegnummer "4711" geben kann, weil z.B. für die Weiterverarbeitung ein Datensatz mit älteren Werten menötigt wird. Es soll (darf) aber immer nur einen Datensatz mit dieser Nummer geben.

    Ich suche / benötige also eine Art "replace"-Funktion beim Import meiner Datensätze.

    genau das machen sämtliche vorgeschlagenen Varianten. Einfach mal ausprobieren.

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    Dienstag, 10. Mai 2011 12:26
    Moderator
  • Hallo Eggi,

    das macht doch das Beispiel von Stefan doch

    USE tempdb
    GO
    
    -- Zu importierende Daten
    CREATE TABLE #Import
    (
    	Belegnummer	varchar(10),
    	Belegtext	varchar(50)
    )
    GO
    
    -- Deine Tabelle mit Belegdaten
    DECLARE @Test TABLE
    (
    	BelegNummer	varchar(10)	PRIMARY KEY CLUSTERED,
    	BelegText	varchar(50)
    )
    
    INSERT INTO @Test
    (BelegNummer, BelegText)
    VALUES
    ('123456', 'BelegText10'),
    ('234567', 'BelegText20'),
    ('345678', 'BelegText30')
    
    
    INSERT INTO #Import
    (Belegnummer, Belegtext)
    VALUES
    ('123456', 'BelegText1'),
    ('234567', 'BelegText2'),
    ('345678', 'BelegText3'),
    ('123456', 'BelegText4'),
    ('987654', 'NOCH EIN BELEGTEXT')
    
    -- Was haben wir jetzt?
    SELECT 'Import', * FROM #Import
    SELECT 'Bestand', * FROM @Test
    
    -- Aktualisierung der Daten (last win)
    DECLARE	@Belegnummer	varchar(10)
    DECLARE	@BelegText	varchar(50)
    
    DECLARE	c CURSOR
    FOR
    	SELECT	BelegNummer, BelegText
    	FROM	#Import
    
    OPEN c
    
    FETCH NEXT FROM c INTO @BelegNummer, @BelegText
    WHILE @@FETCH_STATUS <> -1
    BEGIN
    	IF EXISTS (SELECT TOP 1 * FROM @Test WHERE BelegNummer = @Belegnummer)
    	BEGIN
    		PRINT 'Aktualisierung muss durchgeführt werden...'
    		UPDATE	@Test
    		SET	Belegtext = @BelegText
    		WHERE	Belegnummer = @Belegnummer
    	END
    	
    	ELSE
    	
    	BEGIN
    		PRINT 'Daten müssen neu eingetragen werden ...'
    		INSERT INTO @Test
    		(BelegNummer, BelegText)
    		VALUES
    		(@Belegnummer, @BelegText)
    	END
    	
    	FETCH NEXT FROM c INTO @BelegNummer, @BelegText
    END
    
    CLOSE c
    DEALLOCATE c
    
    -- Und was haben wir jetzt
    SELECT 'Import', * FROM #Import
    SELECT 'Bestand', * FROM @Test
    
    DROP TABLE #Import
    
    

    !

    Mein Beispiel verdeutlicht, wie man bei solchen Exporten vorgehen kann. Ich gebe aber zu bedenken, dass diese Variante eher schlecht ist, da Du ja bei mehrfachem Vorkommen der Belegnummer immer nur den letzten Eintrag haben wirst! Der Output des Scripts verdeutlicht das ja auch:

    Belegnummer Belegtext
    ------ ----------- --------------------------------------------------
    Import 123456   BelegText1
    Import 234567   BelegText2
    Import 345678   BelegText3
    Import 123456   BelegText4
    Import 987654   NOCH EIN BELEGTEXT
    
        BelegNummer BelegText
    ------- ----------- --------------------------------------------------
    Bestand 123456   BelegText10
    Bestand 234567   BelegText20
    Bestand 345678   BelegText30
    
    Aktualisierung muss durchgeführt werden...
    Aktualisierung muss durchgeführt werden...
    Aktualisierung muss durchgeführt werden...
    Aktualisierung muss durchgeführt werden...
    Daten müssen neu eingetragen werden ...
        Belegnummer Belegtext
    ------ ----------- --------------------------------------------------
    Import 123456   BelegText1
    Import 234567   BelegText2
    Import 345678   BelegText3
    Import 123456   BelegText4
    Import 987654   NOCH EIN BELEGTEXT
    
        BelegNummer BelegText
    ------- ----------- --------------------------------------------------
    Bestand 123456   BelegText4
    Bestand 234567   BelegText2
    Bestand 345678   BelegText3
    Bestand 987654   NOCH EIN BELEGTEXT
    
    

    Uwe Ricken

    MCIT Database Administrator 2005
    MCIT Database Administrator 2008
    MCTS SQL Server 2005
    MCTS SQL Server 2008, Implementation and Maintenance
    db Berater GmbH
    http://www-db-berater.de
    Dienstag, 10. Mai 2011 12:28
  • Vielen Dank für die sehr ausführlichen Hinweise.

    Gruß Eggi

    Mittwoch, 11. Mai 2011 16:04