Announcement

Collapse
No announcement yet.

kopieren einer tabelle in andere db?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • kopieren einer tabelle in andere db?

    hallo,

    ich verwende die express version vom sql server 2005 (auch das management studio express) und habe nun 2 tabellen in einer db die sich so stark vom aktuellen stand unterscheiden, dass ich diese gerne umbenennen würde um danach aus einer anderen db die aktuelle version der tabellen hinein zu kopieren.

    nun habe ich also 2 dbs und 2 tabellen die den gleichen namen haben (somit auch gleiche keys(autowerte) und beziehungen).

    wie schaffe ich es nun am schnellsten die tabellen auf den neusten stand zu bringen (die werte in den tabellen bzw. deren schlüssel kann sich auch geändert haben).

    ich dachte: ursprüngliche tabelle umbenennen und dann die neuen mit dem gleichen namen reinkopieren. leider scheitere ich hierbei schon an der erzeugung (create in - script) der tabelle im sql - server management sudio.

    wie würdet ihr da am besten vorgehen?

    lg,
    stefan.

  • #2
    Hallo Stefan,

    das geht recht einfach mit folgendem Script:
    [highlight=SQL]TRUNCATE TABLE TabelleName --alte Daten löschen
    GO
    -- Und nun aus der anderen Datenbank wieder hinein kopieren
    INSERT INTO TabelleName
    (Feld1, Feld2, Feld3, ....)
    SELECT Feld1, Feld2, Feld3, ...
    FROM datenbankB.dbo.TabelleName [/highlight]
    Olaf Helper

    <Blog> <Xing>
    * cogito ergo sum * errare humanum est * quote erat demonstrandum *
    Wenn ich denke, ist das ein Fehler und das beweise ich täglich

    Comment


    • #3
      hallo olaf,

      danke für deinen tipp. leider geht das aber nicht so leicht weil ich da einen foreign-key auf die tabelle habe somit kann ich die auch nicht so leicht 'beschneiden'...

      gibt's da noch einen anderen trick?

      wahrscheinlich müsste ich alle keys, beziehungen etc erst mal entfernen die tabelle erstellen, daten reinkopieren und dann die keys wieder 'einschalten'

      oder gib es da eine einfachere methode?

      lg,
      stefan

      Comment


      • #4
        Wenn es darum geht, wie du es am "schnellsten" schaffst, dann würde ich dir zu einem kommerziellen Tool raten (einfach mal nach "data comparer" googeln). Aber wahrscheinlich willst du kein Geld dafür ausgeben, dann heisst es eben selber machen.
        Wenn es sich jetzt aber nicht um komplett einfache Tabellen handelt sondern auch noch Identitys und foreign keys mit im Spiel sind, dann wird das Ganze schnell ziemlich komplex und ist nichts, was man hier mit 10 Sätzen beschreiben kann. Da hilft nur hinsetzen, nachdenken, probieren ....

        bye,
        Helmut

        Comment


        • #5
          hallo helmut,

          danke das habe ich mir fast gedacht...

          Comment


          • #6
            Hallo Stefan,

            so wild ist es eigentlich nicht, das auch trotz FK oder Identity hinzubekommen.

            Ich hatte mir mal eine SP erstellt, die mir beliebige Tabellen über Server/DB hinweg "synchronisiert", quasi eine eigene Replikation.

            Es sollte alles denkbare berücksichtigen, auch TimeStamp- oder Identity-Felder; nur BLOBS werden nicht übertragen; wegen dem dynamischen SQL ist das schwierig.

            Es ermittelt die

            Hier mal das Script dazu:
            [highlight=SQL]/* ************************************************** ********** */
            /* spMySyncTable */
            /* Syncronisieren von Daten von einem anderen Server / gleiche DB */
            /* */

            /* Stored Procedure neu anlegen */

            CREATE PROCEDURE spMySyncTable
            (--Eingabe Parameter
            @SrcSrv sysname, -- Quell Server, aus dem die Daten übernommen werden sollen
            @DBName sysname, -- Quell DB
            @TableName sysname, -- zu sync. Tabelle
            @UpdtTimeStamp timestamp -- Timestamp des letzten Sync
            )
            AS

            SET NOCOUNT ON

            --Lokale Variable
            DECLARE @DELETE nvarchar(4000)
            DECLARE @UPDATE nvarchar(4000)
            DECLARE @INSERT nvarchar(4000)
            DECLARE @SQL nvarchar(4000)
            DECLARE @ColumnName sysname
            DECLARE @FldName sysname
            DECLARE @FldIncr int
            DECLARE @JoinONPK varchar(4000)
            DECLARE @UpdateFields nvarchar(4000)
            DECLARE @InsertFields nvarchar(4000)
            DECLARE @Ident smallint
            DECLARE @Idt smallint
            DECLARE @UpdateWhere nvarchar(4000)
            DECLARE @DataType sysname

            --Initialiserung
            SET @JoinONPK = ''
            SET @DELETE = ''
            SET @UPDATE = ''
            SET @UpdateWhere = ''
            SET @INSERT = ''
            SET @UpdateFields = ''
            SET @InsertFields = ''
            SET @Ident = 0

            CREATE TABLE #PKTable
            (TABLE_CATALOG sysname,
            TABLE_SCHEMA sysname,
            TABLE_NAME sysname,
            COLUMN_NAME sysname,
            COLUMN_GUID varchar(128),
            COLUMN_PROPID int,
            ORDINAL int,
            PK_NAME sysname)

            -- Felder des Primary Key ermittlen für JOIN Bedingung
            INSERT INTO #PKTable exec sp_primary_keys_rowset @TableName, N'dbo'

            DECLARE PKCur CURSOR LOCAL FOR
            SELECT COLUMN_NAME
            FROM #PKTable
            OPEN PKCur
            FETCH NEXT FROM PKCur INTO @ColumnName
            WHILE @@FETCH_STATUS = 0
            BEGIN
            SET @JoinOnPK = @JoinOnPK + 'SRC.' + @ColumnName + ' = DST.' + @ColumnName + ' AND '
            FETCH NEXT FROM PKCur INTO @ColumnName
            END
            IF LEN(@JoinOnPK) > 0 SET @JoinOnPK = SUBSTRING(@JoinOnPK, 1, LEN(@JoinOnPK) - 4)

            CLOSE PKCur
            DEALLOCATE PKCur
            DROP TABLE #PKTable

            --Tabellenfelder für Update- und Insert Statement + Info, ob AutoIncr vorhanden
            DECLARE TblFields CURSOR LOCAL FOR
            SELECT COLUMN_NAME, IDENT_INCR(@TableName) AS INC,
            COLUMNPROPERTY(OBJECT_ID(@TableName), Column_name, 'IsIdentity') AS IDT, DATA_TYPE
            FROM information_schema.columns
            WHERE Table_name = @TableName
            -- AND DATA_TYPE <> 'timestamp'
            AND DATA_TYPE <> 'text'
            AND DATA_TYPE <> 'ntext'
            AND DATA_TYPE <> 'image'
            ORDER BY ORDINAL_POSITION
            OPEN TblFields
            FETCH NEXT FROM TblFields INTO @FldName, @FldIncr, @Idt, @DataType
            WHILE @@FETCH_STATUS = 0
            BEGIN
            IF @DataType = 'timestamp'
            SET @UpdateWhere = 'WHERE SRC.' + @FldName + ' >= ' + CONVERT(varchar(40), CONVERT(bigint, @UpdtTimeStamp))
            ELSE
            BEGIN
            IF ISNULL(@Idt, 0) = 0 SET @UpdateFields = @UpdateFields + '[' + @FldName + ']' + ' = SRC.[' + @FldName + '], '
            SET @InsertFields = @InsertFields + 'SRC.[' + @FldName + ']' + ', '
            SET @Ident = ISNULL(@FldIncr, 0)
            END
            FETCH NEXT FROM TblFields INTO @FldName, @FldIncr, @Idt, @DataType
            END
            CLOSE TblFields
            DEALLOCATE TblFields
            IF LEN(@UpdateFields) > 0 SET @UpdateFields = SUBSTRING(@UpdateFields, 1 , LEN(@UpdateFields) - 1)
            IF LEN(@InsertFields) > 0 SET @InsertFields = SUBSTRING(@InsertFields, 1 , LEN(@InsertFields) - 1)

            --Zunächst alle in der Source nicht mehr enthaltenen Datensätze löschen
            SET @Delete = 'DELETE [' + @TableName + '] ' +
            'FROM [' + @TableName + '] AS DST ' +
            'LEFT JOIN [' + @SrcSrv + '].[' + @DBName + '].dbo.[' + @TableName + '] AS SRC ON ' +
            @JoinOnPK + ' ' +
            'WHERE SRC.' + @ColumnName + ' IS NULL'

            --(Noch) Vorhandene Datensätze updaten
            SET @Update = 'UPDATE [' + @DBName + '].dbo.[' + @TableName + '] ' +
            'SET ' + @UpdateFields + ' ' +
            'FROM [' + @DBName + '].dbo.[' + @TableName + '] AS DST ' +
            'INNER JOIN [' + @SrcSrv + '].[' + @DBName + '].dbo.[' + @TableName + '] AS SRC ON ' + @JoinOnPK + ' ' +
            @UpdateWhere

            --Fehlende Datensätze einfügen
            IF @Ident > 0 SET @Insert = 'SET IDENTITY_INSERT [' + @DBName + '].dbo.[' + @TableName + '] ON;'

            SET @Insert = @Insert +
            'INSERT INTO [' + @DBName + '].dbo.[' + @TableName + '] ' +
            '(' + @InsertFields +
            ') ' +
            'SELECT ' + @InsertFields + ' ' +
            'FROM [' + @DBName + '].dbo.[' + @TableName + '] AS DST ' +
            'RIGHT JOIN [' + @SrcSrv + '].[' + @DBName + '].dbo.[' + @TableName + '] AS SRC ON ' +
            @JoinOnPK + ' ' +
            'WHERE DST.' + @ColumnName + ' IS NULL;'

            IF @Ident > 0 SET @Insert = @Insert + 'SET IDENTITY_INSERT [' + @DBName + '].dbo.[' + @TableName + '] OFF;'

            EXEC sp_executesql @Delete
            EXEC sp_executesql @Update
            EXEC sp_executesql @Insert

            IF @@TranCount > 0 COMMIT TRANSACTION
            GO[/highlight]

            Die SP muss in der Ziel-DB angelegt und ausgeführt werden; man übergibt den Quell-Server + DB, der Tabellenname gilt dabei für beide DBs.

            Du mußt nur die Tabellen in der richtigen Reihenfolge sync.en wegen FK.
            Zuletzt editiert von O. Helper; 06.08.2008, 15:12.
            Olaf Helper

            <Blog> <Xing>
            * cogito ergo sum * errare humanum est * quote erat demonstrandum *
            Wenn ich denke, ist das ein Fehler und das beweise ich täglich

            Comment


            • #7
              wow...

              sorry, dass ich jetzt erst schreibe, irgendwie habe ich das auto-benachrichtigungs-teil nicht eingeschalten.

              vieeeeelen dank für das script werde es dann später gleich mal ausprobieren, das sieht echt chef-mäßig aus!

              DANKE!

              Comment

              Working...
              X