none
Alter table Add "Automatisiert" RRS feed

  • Frage

  • Moin

    kann ich aus einer vorhandenen tabelle ein Alter Table Add script(für eine Feld/Spalte) automatisch generieren lassen für eine andere Datenbank?

    mit Standardwert - evtl. einschränkungen...

    soetwas wie nimm Feld NeuesFeld aus der Datenbank x und erstelle mir dieses in Datenbank y in der gleichen tabelle

    Freitag, 5. Februar 2016 09:52

Antworten

  • Hallo,

    das Skript kannst Du über eine einfach Abfrage generieren lassen:

    SELECT N'ALTER TABLE ' + QUOTENAME(SCH.name) + N'.' + QUOTENAME(TBL.name) + N' ' +
           N'ADD ' + QUOTENAME(COL.name) + N' ' + TYP.name + 
           CASE WHEN TYP.system_type_id IN (239, 231, 167, 165, 175)
                THEN N'(' + CONVERT(varchar(15), COL.max_length) + N')'
                WHEN TYP.system_type_id IN (62, 106, 108)
                THEN N'(' + CONVERT(varchar(15), COL.precision) + N', ' + CONVERT(varchar(15), COL.scale) + N')'
                ELSE N''
                END +
           CASE WHEN COL.is_nullable = 0 THEN N' NOT ' ELSE N' ' END + N'NULL '
           N';'
    FROM sys.schemas AS SCH
         INNER JOIN
         sys.tables AS TBL
             ON SCH.schema_id = TBL.schema_id
         INNER JOIN
         sys.columns AS COL
             ON TBL.object_id = COL.object_id
         INNER JOIN
         sys.types AS TYP
             ON COL.system_type_id = TYP.system_type_id
                AND COL.user_type_id = TYP.user_type_id
    WHERE SCH.name = N'Person'
          AND TBL.name = N'Address'

    Es ist nicht vollständig ausformuliert, es werden noch nicht alle Typen richtig behandelt, aber als Ansatz sollte es reichen.

    Ergebnis:

    ALTER TABLE [Person].[Address] ADD [AddressID] int NOT NULL;
    ALTER TABLE [Person].[Address] ADD [AddressLine1] nvarchar(120) NOT NULL;
    ALTER TABLE [Person].[Address] ADD [AddressLine2] nvarchar(120) NULL;
    ALTER TABLE [Person].[Address] ADD [City] nvarchar(60) NOT NULL;
    ALTER TABLE [Person].[Address] ADD [StateProvinceID] int NOT NULL;
    ALTER TABLE [Person].[Address] ADD [PostalCode] nvarchar(30) NOT NULL;
    ALTER TABLE [Person].[Address] ADD [SpatialLocation] geography NULL;
    ALTER TABLE [Person].[Address] ADD [rowguid] uniqueidentifier NOT NULL;
    ALTER TABLE [Person].[Address] ADD [ModifiedDate] datetime NOT NULL;


    Olaf Helper

    [ Blog] [ Xing] [ MVP]


    • Bearbeitet Olaf HelperMVP Freitag, 5. Februar 2016 10:33
    • Als Antwort markiert MCDPone Freitag, 5. Februar 2016 12:36
    Freitag, 5. Februar 2016 10:33
  • TBL ist dann der Tabellenname.

    Einen schönen Tag noch, Christoph -- Data Platform MVP - http://www.insidesql.org/blogs/cmu

    • Als Antwort markiert MCDPone Freitag, 5. Februar 2016 12:36
    Freitag, 5. Februar 2016 12:22
  • Das Beispiel hatte ich auch der Demo Datenbank AdventureWorks ausgeführt, wo viel mit Schemas gearbeitet wird; nur ein paar Hilfstabellen sind im Schema "dbo". Also ja, Sch.name ist der Schema-Name.

    Wenn Du die WHERE Klausel ganz weg lässt, bekommst Du die ALTER Skripte für alle Tabellen/Felder. Nur wie gesagt, das Skript ist nicht vollständig. Auch so was wie Contraints / Defaults fehlen.


    Olaf Helper

    [ Blog] [ Xing] [ MVP]

    • Als Antwort markiert MCDPone Freitag, 5. Februar 2016 12:36
    Freitag, 5. Februar 2016 12:26

Alle Antworten

  • Prinzipiell natürlich.

    Man kann dies in ein dymanisches SQL Statement verpacken und dann mithilfe von sp_executesql ausühren.

    in der Realität wirst Du vorher prüfen wollen, wie viele Datensätze in der Tabelle sind, was für ein Datentyp es ist und ob er einen Default-Wert haben soll oder nicht, da dies alles Einfluss auf die Aktion hat, die ja auch protokolliert wird und zu einer länger dauernden Sperre führen kann.

    Unter dem selben Problem leiden prinzipiell alle Schema-Compare+Update Tools. In kleinen Datenbanken geht es meist problemlos, in größeren halt oft nicht mehr einfach so.


    Andreas Wolter (Blog | Twitter)
    MCSM: Microsoft Certified Solutions Master Data Platform, MCM, MVP
    www.SarpedonQualityLab.com | www.SQL-Server-Master-Class.com

    Freitag, 5. Februar 2016 10:29
  • Hallo,

    das Skript kannst Du über eine einfach Abfrage generieren lassen:

    SELECT N'ALTER TABLE ' + QUOTENAME(SCH.name) + N'.' + QUOTENAME(TBL.name) + N' ' +
           N'ADD ' + QUOTENAME(COL.name) + N' ' + TYP.name + 
           CASE WHEN TYP.system_type_id IN (239, 231, 167, 165, 175)
                THEN N'(' + CONVERT(varchar(15), COL.max_length) + N')'
                WHEN TYP.system_type_id IN (62, 106, 108)
                THEN N'(' + CONVERT(varchar(15), COL.precision) + N', ' + CONVERT(varchar(15), COL.scale) + N')'
                ELSE N''
                END +
           CASE WHEN COL.is_nullable = 0 THEN N' NOT ' ELSE N' ' END + N'NULL '
           N';'
    FROM sys.schemas AS SCH
         INNER JOIN
         sys.tables AS TBL
             ON SCH.schema_id = TBL.schema_id
         INNER JOIN
         sys.columns AS COL
             ON TBL.object_id = COL.object_id
         INNER JOIN
         sys.types AS TYP
             ON COL.system_type_id = TYP.system_type_id
                AND COL.user_type_id = TYP.user_type_id
    WHERE SCH.name = N'Person'
          AND TBL.name = N'Address'

    Es ist nicht vollständig ausformuliert, es werden noch nicht alle Typen richtig behandelt, aber als Ansatz sollte es reichen.

    Ergebnis:

    ALTER TABLE [Person].[Address] ADD [AddressID] int NOT NULL;
    ALTER TABLE [Person].[Address] ADD [AddressLine1] nvarchar(120) NOT NULL;
    ALTER TABLE [Person].[Address] ADD [AddressLine2] nvarchar(120) NULL;
    ALTER TABLE [Person].[Address] ADD [City] nvarchar(60) NOT NULL;
    ALTER TABLE [Person].[Address] ADD [StateProvinceID] int NOT NULL;
    ALTER TABLE [Person].[Address] ADD [PostalCode] nvarchar(30) NOT NULL;
    ALTER TABLE [Person].[Address] ADD [SpatialLocation] geography NULL;
    ALTER TABLE [Person].[Address] ADD [rowguid] uniqueidentifier NOT NULL;
    ALTER TABLE [Person].[Address] ADD [ModifiedDate] datetime NOT NULL;


    Olaf Helper

    [ Blog] [ Xing] [ MVP]


    • Bearbeitet Olaf HelperMVP Freitag, 5. Februar 2016 10:33
    • Als Antwort markiert MCDPone Freitag, 5. Februar 2016 12:36
    Freitag, 5. Februar 2016 10:33
  • Hi,

    willst Du einen Abgleich zwischen zwei oder mehreren Datenbanken durchführen? Falls ja, betrifft das nur neue Spalten in Tabellen oder auch andere Objekte wie Views, SPs, ...? Falls letzteres, würde ich dir eher ein Tool wie bspw. RedGate SQL Compare empfehlen. Damit lässt sich sowas automatisieren. Natürlich hat man auch hiereiniges zu beachten, wie Andreas schon geschrieben hat. Dennoch würde ich eher mit einem solchen Tool arbeiten, da viele Problem- und Spezialfälle hier bereits berücksichtigt werden und die möglichen Fehlerquellen stark reduziert werden.


    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


    Freitag, 5. Februar 2016 10:53
    Moderator
  • Hallo,

    evtl. in Deinem Fall einen Blick wert: tablediff (Hilfsprogramm)

    Gruß Elmar

    Freitag, 5. Februar 2016 11:44
    Beantworter
  • ich glaube der anatz ist für mich der richtige

    nur verstehe ich diesen nicht so ganz

    frage

    WHERE SCH.name = N'Person'
          AND TBL.name = N'Address'

    ist für mich der datenbankname und tabellenname - richtig?

    wo holt er sich den datenbanknamen der "master" datenbank her?

    Freitag, 5. Februar 2016 12:13
  • Hi,

    SCH dürfte das Schema sein (meistens, aber nicht zwingend "dbo"), TBL ist dann der Datenbankname.

    Der Datenbankname wird in dem gezeigten Ausschnitt nicht angegeben.


    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

    Freitag, 5. Februar 2016 12:15
    Moderator
  • TBL ist dann der Tabellenname.

    Einen schönen Tag noch, Christoph -- Data Platform MVP - http://www.insidesql.org/blogs/cmu

    • Als Antwort markiert MCDPone Freitag, 5. Februar 2016 12:36
    Freitag, 5. Februar 2016 12:22
  • Das Beispiel hatte ich auch der Demo Datenbank AdventureWorks ausgeführt, wo viel mit Schemas gearbeitet wird; nur ein paar Hilfstabellen sind im Schema "dbo". Also ja, Sch.name ist der Schema-Name.

    Wenn Du die WHERE Klausel ganz weg lässt, bekommst Du die ALTER Skripte für alle Tabellen/Felder. Nur wie gesagt, das Skript ist nicht vollständig. Auch so was wie Contraints / Defaults fehlen.


    Olaf Helper

    [ Blog] [ Xing] [ MVP]

    • Als Antwort markiert MCDPone Freitag, 5. Februar 2016 12:36
    Freitag, 5. Februar 2016 12:26
  • Danke - genau "fast" so habe ich es gebraucht - du hast mir sehr weiter geholfen
    Freitag, 5. Februar 2016 12:38
  • Hallo,

    ich hatte mir hierzu mal ein paar Zeilen zusammen geschrieben:

      https://social.msdn.microsoft.com/Forums/de-DE/ed1e9c5b-d59c-41e1-bdfe-544f82cfb419/datentransfer-sql-server-2012-2008-beste-methode-mit-microsoft-technologien?forum=sqlserverde#47fdbec1-89ad-4a14-8a71-6faec4a8fe73

    Allerdings ohne Gewähr; bei mir funktioniert es.

    Anwendung:

    Datenbank auslesen, und mit dem Skript, dass dabei erstellt wird, auf die Datenbank, die angepasst werden soll, anwenden.

    Wie gesagt; zunächst testen!

    Schönen Abend.



    • Bearbeitet Joerg_x Freitag, 5. Februar 2016 17:49
    • Bearbeitet Stefan FalzModerator Freitag, 5. Februar 2016 18:04 Link als Link eingefügt
    Freitag, 5. Februar 2016 17:46