2009-10-21 8 views

Répondre

15

SELECT INTO va créer une nouvelle table avec le même schéma. Donc, vous pouvez:

SELECT * 
INTO newdb.dbo.newtable 
FROM olddb.dbo.oldtable 

Pour copier simplement le schéma et non les données:

SELECT TOP 0 * 
INTO newdb.dbo.newtable 
FROM olddb.dbo.oldtable 

Ce ne serait pas des index ou des clés copier. Pour les copier, cliquez avec le bouton droit sur la table dans SQL Server Management Studio et choisissez "Table de script sous". Cela vous donnera un script que vous pouvez exécuter sur la nouvelle base de données.

+3

J'ai déjà essayé ceci mais j'ai besoin de copier aussi des contraintes et j'ai besoin de sql query pour cela. Merci pour votre message. – Himadri

+2

-1 ceci est incorrect et dangereux. ceci ne copie pas les contraintes –

+1

Il ne copie pas les contraintes! C'est seulement utile pour les copies simples. – natenho

5

Essayez avec SQL Server SCRIPT ASSISTANT

1) Sélectionnez une base de données

2) Clic droit -> Tâches -> Générer des scripts

3) Cliquez sur Suivant -> et dans l'écran de base de données Sélectionnez , choisissez la table (sera sélectionnée par défaut). Cochez la case "Script Tous les objets dans la base de données sélectionnée".

4) Cliquez sur Terminer.

Hope this helps

12

Bien sûr ses 2 ans plus tard, mais je voulais apporter une solution. Cette procédure copie une table dans "BackUp_ <YYYYMMDD> _ < Nom de la table d'origine > et sa contrainte de clé primaire Elle entoure le nom de la table avec le caractère générique '%' afin de permettre la copie d'un groupe de tables. clé primaire parce qu'il n'y a pas de recours à d'autres tables, donc moins de maux de tête. de plus, aucun Curseurs!

ALTER PROCEDURE dbo.Admin_CopyTable 
    @TableName NVARCHAR(255) 
AS 
BEGIN 

    -- SET NOCOUNT ON added to prevent extra result sets from interfering with SELECT statements. 
    SET NOCOUNT ON; 

    -- is there any work to do? 
    IF NOT (isNull(@TableName,'')='') 
    BEGIN 
     -- Get list of all tables that match the @TableName wildcard 
     DECLARE @tables TABLE (id BIGINT IDENTITY(1,1), [name] NVARCHAR(255)) -- using id as means to avoid cursor 
     INSERT INTO @tables SELECT table_name FROM information_schema.tables WHERE table_name LIKE '%' + @TableName + '%' AND table_name NOT LIKE 'BackUp_%' ORDER BY table_name 

     -- Go through each table and copy it 
     DECLARE @row BIGINT; 
     DECLARE @thisTable AS NVARCHAR(255); 
     DECLARE @dSQL NVARCHAR(4000);  -- holds the SQL string to execute and copy table data 
     DECLARE @TablePrefix NVARCHAR(255); -- Name that is prepended before the name of the actual table to show it is a backup table 

     -- set default prefix by adding todays date to the table name 
     SELECT @TablePrefix = 'BackUp_' + CONVERT(NVARCHAR(10), GetDate(), 112) + '_'; -- Date as YYYYMMDD 

     -- Get first row for looping through list of tables 
     SELECT @row = MIN(id) FROM @tables; 

     WHILE (isNull(@row, 0) <> 0) -- returns null when no more rows, which gets converted to 0 (zero) 
     BEGIN 
      SELECT @thisTable = [name] FROM @tables where id = @row 

      IF NOT EXISTS(SELECT table_name FROM information_schema.tables WHERE table_name like @TablePrefix + @thisTable) 
       BEGIN 
       SET @dSQL = 'Select * Into ' + @TablePrefix + @thisTable + ' from ' + @thisTable; 
       EXEC (@dSQL) 
       PRINT @TablePrefix + @thisTable + ': Data Backed up.' 

       -- Copy the Primary Key into the Backup table 
       BEGIN 
        -- Get list of all the columns that make up the Primary Key 
        -- for composite PK's = one row per pk column 
        DECLARE @PKColsTbl table ([name] NVARCHAR(255), col NVARCHAR(255)) 

        INSERT INTO @PKColsTbl 
        SELECT c.Constraint_Name, c.COLUMN_NAME 
        FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk 
          ,INFORMATION_SCHEMA.KEY_COLUMN_USAGE c 
        WHERE pk.TABLE_NAME = @thisTable 
         and CONSTRAINT_TYPE = 'PRIMARY KEY' 
         and c.TABLE_NAME = pk.TABLE_NAME 
         and c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME 

        -- Transpose rows into one column as a comma delimeted string 
        DECLARE @pkCol NVARCHAR(255); 
        SELECT @pkCol = stuff((select ',' + col from @PKColsTbl for XML PATH('')), 1,1,'') 

        -- Build the dynamic SQL statement and execute it 
        SET @dSQL = 'ALTER TABLE ' + @TablePrefix + @thisTable + ' ADD CONSTRAINT ' + 'PK_' + @TablePrefix + @thisTable + ' PRIMARY KEY (' + @pkCol + ')' 
        EXEC (@dSQL) 
        PRINT @TablePrefix + @thisTable + ': PK Created.' 

        -- Since its a loop, clear out the table 
        DELETE FROM @PKColsTbl 
       END 
       -- END of Copying the Primary Key 

       END 
      ELSE 
       BEGIN 
       PRINT @TablePrefix + @thisTable + ': Exists!' 
       END 

      -- Get next row 
      SELECT @row = min(id) FROM @tables WHERE id > @row 
     END 
    END 
END 
+0

cela sauvegardera également les tables avec des noms partiellement correspondants. par exemple. "myTable" comme nom de la table de sauvegarde désirée sauvegardera aussi "myTable1", "myTableABC" etc. – ryan

+0

et les schémas autres que [dbo]? J'ai deux tables avec le même nom mais sur des schémas différents! – armen

4

je l'ai écrit ce sp pour créer automatiquement le schéma avec toutes les choses, pk, fk, partitions, contraintes ...

IMPORTANT !! avant l'exécution

create type TestTableType as table (ObjectID int) 

ici la SP:

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 


--*************************************************************************************************' 
-- La procedura crea lo script di una tabella 

--*************************************************************************************************' 



alter PROCEDURE [dbo].[util_ScriptTable] 
    @DBName SYSNAME 
    ,@schema sysname 
    ,@TableName SYSNAME 
    ,@IncludeConstraints BIT = 1 
    ,@IncludeIndexes BIT = 1 
    ,@NewTableSchema sysname 
    ,@NewTableName SYSNAME = NULL 
    ,@UseSystemDataTypes BIT = 0 
    ,@script varchar(max) output 
AS 
BEGIN try 
    if not exists (select * from sys.types where name = 'TestTableType') 
     create type TestTableType as table (ObjectID int)--drop type TestTableType 

    declare @sql nvarchar(max) 

    DECLARE @MainDefinition TABLE (FieldValue VARCHAR(200)) 
    --DECLARE @DBName SYSNAME 
    DECLARE @ClusteredPK BIT 
    DECLARE @TableSchema NVARCHAR(255) 

    --SET @DBName = DB_NAME(DB_ID()) 
    SELECT @TableName = name FROM sysobjects WHERE id = OBJECT_ID(@TableName) 

    DECLARE @ShowFields TABLE (FieldID INT IDENTITY(1,1) 
             ,DatabaseName VARCHAR(100) 
             ,TableOwner VARCHAR(100) 
             ,TableName VARCHAR(100) 
             ,FieldName VARCHAR(100) 
             ,ColumnPosition INT 
             ,ColumnDefaultValue VARCHAR(100) 
             ,ColumnDefaultName VARCHAR(100) 
             ,IsNullable BIT 
             ,DataType VARCHAR(100) 
             ,MaxLength varchar(10) 
             ,NumericPrecision INT 
             ,NumericScale INT 
             ,DomainName VARCHAR(100) 
             ,FieldListingName VARCHAR(110) 
             ,FieldDefinition CHAR(1) 
             ,IdentityColumn BIT 
             ,IdentitySeed INT 
             ,IdentityIncrement INT 
             ,IsCharColumn BIT 
             ,IsComputed varchar(255)) 

    DECLARE @HoldingArea TABLE(FldID SMALLINT IDENTITY(1,1) 
             ,Flds VARCHAR(4000) 
             ,FldValue CHAR(1) DEFAULT(0)) 

    DECLARE @PKObjectID TABLE(ObjectID INT) 

    DECLARE @Uniques TABLE(ObjectID INT) 

    DECLARE @HoldingAreaValues TABLE(FldID SMALLINT IDENTITY(1,1) 
               ,Flds VARCHAR(4000) 
               ,FldValue CHAR(1) DEFAULT(0)) 

    DECLARE @Definition TABLE(DefinitionID SMALLINT IDENTITY(1,1) 
             ,FieldValue VARCHAR(200)) 


    set @sql= 
    ' 
    use '[email protected]+' 
    SELECT distinct DB_NAME() 
      ,TABLE_SCHEMA 
      ,TABLE_NAME 
      ,''[''+COLUMN_NAME+'']'' as COLUMN_NAME 
      ,CAST(ORDINAL_POSITION AS INT) 
      ,COLUMN_DEFAULT 
      ,dobj.name AS ColumnDefaultName 
      ,CASE WHEN c.IS_NULLABLE = ''YES'' THEN 1 ELSE 0 END 
      ,DATA_TYPE 
      ,case CHARACTER_MAXIMUM_LENGTH when -1 then ''max'' else CAST(CHARACTER_MAXIMUM_LENGTH AS varchar) end--CAST(CHARACTER_MAXIMUM_LENGTH AS INT) 
      ,CAST(NUMERIC_PRECISION AS INT) 
      ,CAST(NUMERIC_SCALE AS INT) 
      ,DOMAIN_NAME 
      ,COLUMN_NAME + '','' 
      ,'''' AS FieldDefinition 
      ,CASE WHEN ic.object_id IS NULL THEN 0 ELSE 1 END AS IdentityColumn 
      ,CAST(ISNULL(ic.seed_value,0) AS INT) AS IdentitySeed 
      ,CAST(ISNULL(ic.increment_value,0) AS INT) AS IdentityIncrement 
      ,CASE WHEN st.collation_name IS NOT NULL THEN 1 ELSE 0 END AS IsCharColumn 
      ,cc.definition 
      FROM INFORMATION_SCHEMA.COLUMNS c 
      JOIN sys.columns sc ON c.TABLE_NAME = OBJECT_NAME(sc.object_id) AND c.COLUMN_NAME = sc.Name 
      LEFT JOIN sys.identity_columns ic ON c.TABLE_NAME = OBJECT_NAME(ic.object_id) AND c.COLUMN_NAME = ic.Name 
      JOIN sys.types st ON COALESCE(c.DOMAIN_NAME,c.DATA_TYPE) = st.name 
      LEFT OUTER JOIN sys.objects dobj ON dobj.object_id = sc.default_object_id AND dobj.type = ''D'' 
      left join sys.computed_columns cc on c.TABLE_NAME=OBJECT_NAME(cc.object_id) and sc.column_id=cc.column_id 
    WHERE c.TABLE_NAME = @TableName and [email protected] 
    ORDER BY c.TABLE_NAME, c.ORDINAL_POSITION 
    ' 

    print @sql 
    INSERT INTO @ShowFields(DatabaseName 
            ,TableOwner 
            ,TableName 
            ,FieldName 
            ,ColumnPosition 
            ,ColumnDefaultValue 
            ,ColumnDefaultName 
            ,IsNullable 
            ,DataType 
            ,MaxLength 
            ,NumericPrecision 
            ,NumericScale 
            ,DomainName 
            ,FieldListingName 
            ,FieldDefinition 
            ,IdentityColumn 
            ,IdentitySeed 
            ,IdentityIncrement 
            ,IsCharColumn 
            ,IsComputed) 

    exec sp_executesql @sql, 
         N'@TableName varchar(50),@schema varchar(50)', 
         @[email protected],@[email protected]    
    /* 
    SELECT @DBName--DB_NAME() 
      ,TABLE_SCHEMA 
      ,TABLE_NAME 
      ,COLUMN_NAME 
      ,CAST(ORDINAL_POSITION AS INT) 
      ,COLUMN_DEFAULT 
      ,dobj.name AS ColumnDefaultName 
      ,CASE WHEN c.IS_NULLABLE = 'YES' THEN 1 ELSE 0 END 
      ,DATA_TYPE 
      ,CAST(CHARACTER_MAXIMUM_LENGTH AS INT) 
      ,CAST(NUMERIC_PRECISION AS INT) 
      ,CAST(NUMERIC_SCALE AS INT) 
      ,DOMAIN_NAME 
      ,COLUMN_NAME + ',' 
      ,'' AS FieldDefinition 
      ,CASE WHEN ic.object_id IS NULL THEN 0 ELSE 1 END AS IdentityColumn 
      ,CAST(ISNULL(ic.seed_value,0) AS INT) AS IdentitySeed 
      ,CAST(ISNULL(ic.increment_value,0) AS INT) AS IdentityIncrement 
      ,CASE WHEN st.collation_name IS NOT NULL THEN 1 ELSE 0 END AS IsCharColumn 
      FROM INFORMATION_SCHEMA.COLUMNS c 
      JOIN sys.columns sc ON c.TABLE_NAME = OBJECT_NAME(sc.object_id) AND c.COLUMN_NAME = sc.Name 
      LEFT JOIN sys.identity_columns ic ON c.TABLE_NAME = OBJECT_NAME(ic.object_id) AND c.COLUMN_NAME = ic.Name 
      JOIN sys.types st ON COALESCE(c.DOMAIN_NAME,c.DATA_TYPE) = st.name 
      LEFT OUTER JOIN sys.objects dobj ON dobj.object_id = sc.default_object_id AND dobj.type = 'D' 

    WHERE c.TABLE_NAME = @TableName 
    ORDER BY c.TABLE_NAME, c.ORDINAL_POSITION 
    */ 
    SELECT TOP 1 @TableSchema = TableOwner FROM @ShowFields 

    INSERT INTO @HoldingArea (Flds) VALUES('(') 

    INSERT INTO @Definition(FieldValue)VALUES('CREATE TABLE ' + CASE WHEN @NewTableName IS NOT NULL THEN @DBName + '.' + @NewTableSchema + '.' + @NewTableName ELSE @DBName + '.' + @TableSchema + '.' + @TableName END) 
    INSERT INTO @Definition(FieldValue)VALUES('(') 
    INSERT INTO @Definition(FieldValue) 
    SELECT CHAR(10) + FieldName + ' ' + 
     --CASE WHEN DomainName IS NOT NULL AND @UseSystemDataTypes = 0 THEN DomainName + CASE WHEN IsNullable = 1 THEN ' NULL ' ELSE ' NOT NULL ' END ELSE UPPER(DataType) +CASE WHEN IsCharColumn = 1 THEN '(' + CAST(MaxLength AS VARCHAR(10)) + ')' ELSE '' END +CASE WHEN IdentityColumn = 1 THEN ' IDENTITY(' + CAST(IdentitySeed AS VARCHAR(5))+ ',' + CAST(IdentityIncrement AS VARCHAR(5)) + ')' ELSE '' END +CASE WHEN IsNullable = 1 THEN ' NULL ' ELSE ' NOT NULL ' END +CASE WHEN ColumnDefaultName IS NOT NULL AND @IncludeConstraints = 1 THEN 'CONSTRAINT [' + ColumnDefaultName + '] DEFAULT' + UPPER(ColumnDefaultValue) ELSE '' END END + CASE WHEN FieldID = (SELECT MAX(FieldID) FROM @ShowFields) THEN '' ELSE ',' END 

     CASE WHEN DomainName IS NOT NULL AND @UseSystemDataTypes = 0 THEN DomainName + 
      CASe WHEN IsNullable = 1 THEN ' NULL ' 
      ELSE ' NOT NULL ' 
      END 
     ELSE 
      case when IsComputed is null then 
       UPPER(DataType) + 
       CASE WHEN IsCharColumn = 1 THEN '(' + CAST(MaxLength AS VARCHAR(10)) + ')' 
       ELSE 
        CASE WHEN DataType = 'numeric' THEN '(' + CAST(NumericPrecision AS VARCHAR(10))+','+ CAST(NumericScale AS VARCHAR(10)) + ')' 
        ELSE 
         CASE WHEN DataType = 'decimal' THEN '(' + CAST(NumericPrecision AS VARCHAR(10))+','+ CAST(NumericScale AS VARCHAR(10)) + ')' 
         ELSE '' 
         end 
        end 
       END + 
       CASE WHEN IdentityColumn = 1 THEN ' IDENTITY(' + CAST(IdentitySeed AS VARCHAR(5))+ ',' + CAST(IdentityIncrement AS VARCHAR(5)) + ')' 
       ELSE '' 
       END + 
       CASE WHEN IsNullable = 1 THEN ' NULL ' 
       ELSE ' NOT NULL ' 
       END + 
       CASE WHEN ColumnDefaultName IS NOT NULL AND @IncludeConstraints = 1 THEN 'CONSTRAINT [' + replace(ColumnDefaultName,@TableName,@NewTableName) + '] DEFAULT' + UPPER(ColumnDefaultValue) 
       ELSE '' 
       END 
      else 
       ' as '+IsComputed+' ' 
      end 
     END + 
     CASE WHEN FieldID = (SELECT MAX(FieldID) FROM @ShowFields) THEN '' 
     ELSE ',' 
     END 

    FROM @ShowFields 

    IF @IncludeConstraints = 1 
     BEGIN  

     set @sql= 
     ' 
     use '[email protected]+' 
     SELECT distinct '',CONSTRAINT ['' + replace(name,@TableName,@NewTableName) + ''] FOREIGN KEY ('' + ParentColumns + '') REFERENCES ['' + ReferencedObject + '']('' + ReferencedColumns + '')'' 
      FROM (SELECT ReferencedObject = OBJECT_NAME(fk.referenced_object_id), ParentObject = OBJECT_NAME(parent_object_id),fk.name 
       , REVERSE(SUBSTRING(REVERSE(( SELECT cp.name + '','' 
       FROM sys.foreign_key_columns fkc 
       JOIN sys.columns cp ON fkc.parent_object_id = cp.object_id AND fkc.parent_column_id = cp.column_id 
       WHERE fkc.constraint_object_id = fk.object_id FOR XML PATH('''') )), 2, 8000)) ParentColumns, 
       REVERSE(SUBSTRING(REVERSE(( SELECT cr.name + '','' 
       FROM sys.foreign_key_columns fkc 
       JOIN sys.columns cr ON fkc.referenced_object_id = cr.object_id AND fkc.referenced_column_id = cr.column_id 
       WHERE fkc.constraint_object_id = fk.object_id FOR XML PATH('''') )), 2, 8000)) ReferencedColumns 
       FROM sys.foreign_keys fk  
        inner join sys.schemas s on fk.schema_id=s.schema_id and [email protected]) a  
      WHERE ParentObject = @TableName  
     ' 

     print @sql 

     INSERT INTO @Definition(FieldValue) 
     exec sp_executesql @sql, 
        N'@TableName varchar(50),@NewTableName varchar(50),@schema varchar(50)', 
         @[email protected],@[email protected],@[email protected] 
      /* 
      SELECT ',CONSTRAINT [' + name + '] FOREIGN KEY (' + ParentColumns + ') REFERENCES [' + ReferencedObject + '](' + ReferencedColumns + ')' 
      FROM (SELECT ReferencedObject = OBJECT_NAME(fk.referenced_object_id), ParentObject = OBJECT_NAME(parent_object_id),fk.name 
       , REVERSE(SUBSTRING(REVERSE(( SELECT cp.name + ',' 
       FROM sys.foreign_key_columns fkc 
       JOIN sys.columns cp ON fkc.parent_object_id = cp.object_id AND fkc.parent_column_id = cp.column_id 
       WHERE fkc.constraint_object_id = fk.object_id FOR XML PATH('') )), 2, 8000)) ParentColumns, 
       REVERSE(SUBSTRING(REVERSE(( SELECT cr.name + ',' 
       FROM sys.foreign_key_columns fkc 
       JOIN sys.columns cr ON fkc.referenced_object_id = cr.object_id AND fkc.referenced_column_id = cr.column_id 
       WHERE fkc.constraint_object_id = fk.object_id FOR XML PATH('') )), 2, 8000)) ReferencedColumns 
       FROM sys.foreign_keys fk ) a  
      WHERE ParentObject = @TableName  
      */ 

      set @sql= 
      ' 
      use '[email protected]+' 
      SELECT distinct '',CONSTRAINT ['' + replace(c.name,@TableName,@NewTableName) + ''] CHECK '' + definition 
      FROM sys.check_constraints c join sys.schemas s on c.schema_id=s.schema_id and [email protected]  
      WHERE OBJECT_NAME(parent_object_id) = @TableName 
      ' 

      print @sql 
      INSERT INTO @Definition(FieldValue) 
      exec sp_executesql @sql, 
           N'@TableName varchar(50),@NewTableName varchar(50),@schema varchar(50)', 
         @[email protected],@[email protected],@[email protected] 
      /* 
      SELECT ',CONSTRAINT [' + name + '] CHECK ' + definition FROM sys.check_constraints  
      WHERE OBJECT_NAME(parent_object_id) = @TableName 
      */ 

      set @sql= 
      ' 
      use '[email protected]+' 
      SELECT DISTINCT PKObject = cco.object_id 
      FROM sys.key_constraints cco  
      JOIN sys.index_columns cc ON cco.parent_object_id = cc.object_id AND cco.unique_index_id = cc.index_id  
      JOIN sys.indexes i ON cc.object_id = i.object_id AND cc.index_id = i.index_id 
      join sys.schemas s on cco.schema_id=s.schema_id and [email protected] 
      WHERE OBJECT_NAME(parent_object_id) = @TableName AND i.type = 1 AND is_primary_key = 1 
      ' 
      print @sql 
      INSERT INTO @PKObjectID(ObjectID) 
      exec sp_executesql @sql, 
           N'@TableName varchar(50),@schema varchar(50)', 
           @[email protected],@[email protected] 
      /* 
      SELECT DISTINCT PKObject = cco.object_id 
      FROM sys.key_constraints cco  
      JOIN sys.index_columns cc ON cco.parent_object_id = cc.object_id AND cco.unique_index_id = cc.index_id  
      JOIN sys.indexes i ON cc.object_id = i.object_id AND cc.index_id = i.index_id 
      WHERE OBJECT_NAME(parent_object_id) = @TableName AND i.type = 1 AND is_primary_key = 1 
      */ 

      set @sql= 
      ' 
      use '[email protected]+' 
      SELECT DISTINCT PKObject = cco.object_id 
      FROM sys.key_constraints cco 
      JOIN sys.index_columns cc ON cco.parent_object_id = cc.object_id AND cco.unique_index_id = cc.index_id 
      JOIN sys.indexes i ON cc.object_id = i.object_id AND cc.index_id = i.index_id 
      join sys.schemas s on cco.schema_id=s.schema_id and [email protected] 
      WHERE OBJECT_NAME(parent_object_id) = @TableName AND i.type = 2 AND is_primary_key = 0 AND is_unique_constraint = 1 
      ' 
      print @sql 
      INSERT INTO @Uniques(ObjectID) 
      exec sp_executesql @sql, 
           N'@TableName varchar(50),@schema varchar(50)', 
           @[email protected],@[email protected] 
      /* 
      SELECT DISTINCT PKObject = cco.object_id 
      FROM sys.key_constraints cco 
      JOIN sys.index_columns cc ON cco.parent_object_id = cc.object_id AND cco.unique_index_id = cc.index_id 
      JOIN sys.indexes i ON cc.object_id = i.object_id AND cc.index_id = i.index_id 
      WHERE OBJECT_NAME(parent_object_id) = @TableName AND i.type = 2 AND is_primary_key = 0 AND is_unique_constraint = 1 
      */ 

      SET @ClusteredPK = CASE WHEN @@ROWCOUNT > 0 THEN 1 ELSE 0 END 

      declare @t TestTableType 
      insert @t select * from @PKObjectID 
      declare @u TestTableType 
      insert @u select * from @Uniques 

      set @sql= 
      ' 
      use '[email protected]+' 
      SELECT distinct '',CONSTRAINT '' + replace(cco.name,@TableName,@NewTableName) + CASE type WHEN ''PK'' THEN '' PRIMARY KEY '' + CASE WHEN pk.ObjectID IS NULL THEN '' NONCLUSTERED '' ELSE '' CLUSTERED '' END WHEN ''UQ'' THEN '' UNIQUE '' END + CASE WHEN u.ObjectID IS NOT NULL THEN '' NONCLUSTERED '' ELSE '''' END 
      + ''(''+REVERSE(SUBSTRING(REVERSE((SELECT c.name + + CASE WHEN cc.is_descending_key = 1 THEN '' DESC'' ELSE '' ASC'' END + '',''  
      FROM sys.key_constraints ccok 
      LEFT JOIN sys.index_columns cc ON ccok.parent_object_id = cc.object_id AND cco.unique_index_id = cc.index_id 
      LEFT JOIN sys.columns c ON cc.object_id = c.object_id AND cc.column_id = c.column_id 
      LEFT JOIN sys.indexes i ON cc.object_id = i.object_id AND cc.index_id = i.index_id 
      WHERE i.object_id = ccok.parent_object_id AND ccok.object_id = cco.object_id  
      order by key_ordinal FOR XML PATH(''''))), 2, 8000)) + '')'' 
      FROM sys.key_constraints cco 
      inner join sys.schemas s on cco.schema_id=s.schema_id and [email protected] 
      LEFT JOIN @U u ON cco.object_id = u.objectID 
      LEFT JOIN @t pk ON cco.object_id = pk.ObjectID  
      WHERE OBJECT_NAME(cco.parent_object_id) = @TableName 

      ' 

      print @sql 
      INSERT INTO @Definition(FieldValue) 
      exec sp_executesql @sql, 
           N'@TableName varchar(50),@NewTableName varchar(50),@schema varchar(50),@t TestTableType readonly,@u TestTableType readonly', 
           @[email protected],@[email protected],@[email protected],@[email protected],@[email protected] 

      /* 
      SELECT ',CONSTRAINT ' + name + CASE type WHEN 'PK' THEN ' PRIMARY KEY ' + CASE WHEN pk.ObjectID IS NULL THEN ' NONCLUSTERED ' ELSE ' CLUSTERED ' END WHEN 'UQ' THEN ' UNIQUE ' END + CASE WHEN u.ObjectID IS NOT NULL THEN ' NONCLUSTERED ' ELSE '' END 
      + '(' +REVERSE(SUBSTRING(REVERSE((SELECT c.name + + CASE WHEN cc.is_descending_key = 1 THEN ' DESC' ELSE ' ASC' END + ','  
      FROM sys.key_constraints ccok 
      LEFT JOIN sys.index_columns cc ON ccok.parent_object_id = cc.object_id AND cco.unique_index_id = cc.index_id 
      LEFT JOIN sys.columns c ON cc.object_id = c.object_id AND cc.column_id = c.column_id 
      LEFT JOIN sys.indexes i ON cc.object_id = i.object_id AND cc.index_id = i.index_id 
      WHERE i.object_id = ccok.parent_object_id AND ccok.object_id = cco.object_id FOR XML PATH(''))), 2, 8000)) + ')' 
      FROM sys.key_constraints cco 
      LEFT JOIN @PKObjectID pk ON cco.object_id = pk.ObjectID  
      LEFT JOIN @Uniques u ON cco.object_id = u.objectID 
      WHERE OBJECT_NAME(cco.parent_object_id) = @TableName 
      */ 
     END 

     INSERT INTO @Definition(FieldValue) VALUES(')') 

     set @sql= 
     ' 
     use '[email protected]+' 
     select '' on '' + d.name + ''([''+c.name+''])'' 
     from sys.tables t join sys.indexes i on(i.object_id = t.object_id and i.index_id < 2) 
          join sys.index_columns ic on(ic.partition_ordinal > 0 and ic.index_id = i.index_id and ic.object_id = t.object_id) 
          join sys.columns c on(c.object_id = ic.object_id and c.column_id = ic.column_id) 
          join sys.schemas s on t.schema_id=s.schema_id 
          join sys.data_spaces d on i.data_space_id=d.data_space_id 
     where [email protected] and [email protected] 
     order by key_ordinal 
     ' 

     print 'x' 
     print @sql 
     INSERT INTO @Definition(FieldValue) 
     exec sp_executesql @sql, 
          N'@TableName varchar(50),@schema varchar(50)', 
          @[email protected],@[email protected] 

     IF @IncludeIndexes = 1 
     BEGIN 
      set @sql= 
      ' 
      use '[email protected]+' 
      SELECT distinct '' CREATE '' + i.type_desc + '' INDEX ['' + replace(i.name COLLATE SQL_Latin1_General_CP1_CI_AS,@TableName,@NewTableName) + ''] ON '[email protected]+'.'[email protected]+'.'[email protected]+' ('' 
      + REVERSE(SUBSTRING(REVERSE(( SELECT name + CASE WHEN sc.is_descending_key = 1 THEN '' DESC'' ELSE '' ASC'' END + '','' 
      FROM sys.index_columns sc 
      JOIN sys.columns c ON sc.object_id = c.object_id AND sc.column_id = c.column_id 
      WHERE [email protected] AND sc.object_id = i.object_id AND sc.index_id = i.index_id 
             and is_included_column=0 
      ORDER BY key_ordinal ASC FOR XML PATH('''') )), 2, 8000)) + '')''+ 
      ISNULL('' include (''+REVERSE(SUBSTRING(REVERSE(( SELECT name + '','' 
      FROM sys.index_columns sc 
      JOIN sys.columns c ON sc.object_id = c.object_id AND sc.column_id = c.column_id 
      WHERE [email protected] AND sc.object_id = i.object_id AND sc.index_id = i.index_id 
             and is_included_column=1 
      ORDER BY key_ordinal ASC FOR XML PATH('''') )), 2, 8000))+'')'' ,'''')+''''  
      FROM sys.indexes i join sys.tables t on i.object_id=t.object_id 
           join sys.schemas s on t.schema_id=s.schema_id 
      AND CASE WHEN @ClusteredPK = 1 AND is_primary_key = 1 AND i.type = 1 THEN 0 ELSE 1 END = 1 AND is_unique_constraint = 0 AND is_primary_key = 0 
       where [email protected] and [email protected] 
      ' 

      print @sql 
      INSERT INTO @Definition(FieldValue)  
      exec sp_executesql @sql, 
           N'@TableName varchar(50),@NewTableName varchar(50),@schema varchar(50), @ClusteredPK bit', 
           @[email protected],@[email protected],@[email protected],@[email protected] 

     END 

      /* 

       SELECT 'CREATE ' + type_desc + ' INDEX [' + [name] COLLATE SQL_Latin1_General_CP1_CI_AS + '] ON [' + OBJECT_NAME(object_id) + '] (' + REVERSE(SUBSTRING(REVERSE(( SELECT name + CASE WHEN sc.is_descending_key = 1 THEN ' DESC' ELSE ' ASC' END + ',' 
       FROM sys.index_columns sc 
       JOIN sys.columns c ON sc.object_id = c.object_id AND sc.column_id = c.column_id 
       WHERE OBJECT_NAME(sc.object_id) = @TableName AND sc.object_id = i.object_id AND sc.index_id = i.index_id 
       ORDER BY index_column_id ASC FOR XML PATH('') )), 2, 8000)) + ')'  
       FROM sys.indexes i  
       WHERE OBJECT_NAME(object_id) = @TableName 
       AND CASE WHEN @ClusteredPK = 1 AND is_primary_key = 1 AND type = 1 THEN 0 ELSE 1 END = 1 AND is_unique_constraint = 0 AND is_primary_key = 0 

      */ 

      INSERT INTO @MainDefinition(FieldValue) 
      SELECT FieldValue FROM @Definition  
      ORDER BY DefinitionID ASC 

      ---------------------------------- 

      declare @q varchar(max) 

      set @q=(select replace((SELECT FieldValue FROM @MainDefinition FOR XML PATH('')),'</FieldValue>','')) 

      set @script=(select REPLACE(@q,'<FieldValue>','')) 
      --drop type TestTableType 
END try 
-- ############################################################################################################################################################################## 
BEGIN CATCH   
    BEGIN 
     -- INIZIO Procedura in errore ========================================================================================================================================================= 
      PRINT '***********************************************************************************************************************************************************' 
      PRINT 'ErrorNumber    : ' + CAST(ERROR_NUMBER() AS NVARCHAR(MAX)) 
      PRINT 'ErrorSeverity    : ' + CAST(ERROR_SEVERITY() AS NVARCHAR(MAX)) 
      PRINT 'ErrorState    : ' + CAST(ERROR_STATE() AS NVARCHAR(MAX)) 
      PRINT 'ErrorLine     : ' + CAST(ERROR_LINE() AS NVARCHAR(MAX)) 
      PRINT 'ErrorMessage    : ' + CAST(ERROR_MESSAGE() AS NVARCHAR(MAX)) 
      PRINT '***********************************************************************************************************************************************************' 
     -- FINE Procedura in errore ========================================================================================================================================================= 
    END 
     set @script='' 
    return -1 
END CATCH 
-- ############################################################################################################################################################################## 

exec il:

declare @s varchar(max) 
exec [util_ScriptTable] 'db','schema_source','table_source',1,1,'schema_dest','tab_dest',0,@s output 
select @s 
3

et ici sp pour trouver différentes de la source ne destination:

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 


--*************************************************************************************************' 
-- confronta 2 tabelle e fornisce lo scrit di aggiornamento 
-- Tabella : xxxxx 
-- Creata da : E.Mantovanelli 
-- Data creazione : 26-11-2013 
-- Data modifica: 26-11-2013 
--*************************************************************************************************' 

/* 
    --  nn supporta il caso inm cui si rinomini una colonna(colonne nn coincidenti, esegue drop+add) 

    --  ID----|-----Data-----|-- User  --------- | ---- Note 

*/ 

ALTER PROCEDURE [dbo].[util_ScriptTable_Update] 
    @DBName SYSNAME 
    ,@schema_1 sysname 
    ,@TableName_1 SYSNAME 
    ,@IncludeConstraints BIT = 1 
    ,@IncludeIndexes BIT = 1 
    ,@Schema_2 sysname 
    ,@TableName_2 SYSNAME = NULL 
    ,@UseSystemDataTypes BIT = 0 
    ,@script varchar(max) output 
AS 
BEGIN try 
    if not exists (select * from sys.types where name = 'TestTableType') 
     create type TestTableType as table (ObjectID int)--drop type TestTableType 

    declare @sql nvarchar(max), 
      @t0 varchar(max), 
      @t1 varchar(max), 
      @t2 varchar(max), 
      @script_add varchar(max), 
      @script_drop varchar(max) 

    DECLARE @MainDefinition TABLE (FieldValue VARCHAR(max)) 
    DECLARE @ClusteredPK_1 BIT, 
      @ClusteredPK_2 BIT 

    DECLARE @TableSchema NVARCHAR(255) 
    declare @partition varchar(max) 

    --SET @DBName = DB_NAME(DB_ID()) 
    SELECT @TableName_1 = name FROM sysobjects WHERE id = OBJECT_ID(@TableName_1) 

    DECLARE @ShowFields_1 TABLE (FieldID INT IDENTITY(1,1) 
             ,DatabaseName VARCHAR(100) 
             ,TableOwner VARCHAR(100) 
             ,TableName VARCHAR(100) 
             ,FieldName VARCHAR(max) 
             ,ColumnPosition INT 
             ,ColumnDefaultValue VARCHAR(100) 
             ,ColumnDefaultName VARCHAR(100) 
             ,IsNullable BIT 
             ,DataType VARCHAR(100) 
             ,MaxLength varchar(10) 
             ,NumericPrecision INT 
             ,NumericScale INT 
             ,DomainName VARCHAR(100) 
             ,FieldListingName VARCHAR(110) 
             ,FieldDefinition CHAR(1) 
             ,IdentityColumn BIT 
             ,IdentitySeed INT 
             ,IdentityIncrement INT 
             ,IsCharColumn BIT 
             ,IsComputed varchar(255)) 

    DECLARE @ShowFields_2 TABLE (FieldID INT IDENTITY(1,1) 
             ,DatabaseName VARCHAR(100) 
             ,TableOwner VARCHAR(100) 
             ,TableName VARCHAR(100) 
             ,FieldName VARCHAR(max) 
             ,ColumnPosition INT 
             ,ColumnDefaultValue VARCHAR(100) 
             ,ColumnDefaultName VARCHAR(100) 
             ,IsNullable BIT 
             ,DataType VARCHAR(100) 
             ,MaxLength varchar(10) 
             ,NumericPrecision INT 
             ,NumericScale INT 
             ,DomainName VARCHAR(100) 
             ,FieldListingName VARCHAR(110) 
             ,FieldDefinition CHAR(1) 
             ,IdentityColumn BIT 
             ,IdentitySeed INT 
             ,IdentityIncrement INT 
             ,IsCharColumn BIT 
             ,IsComputed varchar(255)) 

    DECLARE @HoldingArea TABLE(FldID SMALLINT IDENTITY(1,1) 
             ,Flds VARCHAR(4000) 
             ,FldValue CHAR(1) DEFAULT(0)) 

    DECLARE @PKObjectID TABLE(ObjectID INT) 

    DECLARE @Uniques TABLE(ObjectID INT) 

    DECLARE @HoldingAreaValues TABLE(FldID SMALLINT IDENTITY(1,1) 
               ,Flds VARCHAR(4000) 
               ,FldValue CHAR(1) DEFAULT(0)) 

    DECLARE @Definition TABLE(--DefinitionID SMALLINT IDENTITY(1,1) 
             state int 
             ,FieldValue_1 VARCHAR(max),FieldValue_2 VARCHAR(max)) 

    ------------------------------ 
    --FK 
    ------------------------------ 

    delete @Definition 
    delete @ShowFields_1 
    delete @ShowFields_2 

    set @sql= 
    ' 
    use '[email protected]+' 
    SELECT distinct db_name(),@schema,ParentObject,name, ''('' + ParentColumns + '') REFERENCES ['' + ReferencedObject + '']('' + ReferencedColumns + '')'' 
     FROM (SELECT ReferencedObject = OBJECT_NAME(fk.referenced_object_id), ParentObject = OBJECT_NAME(parent_object_id),fk.name 
      , REVERSE(SUBSTRING(REVERSE(( SELECT cp.name + '','' 
      FROM sys.foreign_key_columns fkc 
      JOIN sys.columns cp ON fkc.parent_object_id = cp.object_id AND fkc.parent_column_id = cp.column_id 
      WHERE fkc.constraint_object_id = fk.object_id FOR XML PATH('''') )), 2, 8000)) ParentColumns, 
      REVERSE(SUBSTRING(REVERSE(( SELECT cr.name + '','' 
      FROM sys.foreign_key_columns fkc 
      JOIN sys.columns cr ON fkc.referenced_object_id = cr.object_id AND fkc.referenced_column_id = cr.column_id 
      WHERE fkc.constraint_object_id = fk.object_id FOR XML PATH('''') )), 2, 8000)) ReferencedColumns 
      FROM sys.foreign_keys fk  
       inner join sys.schemas s on fk.schema_id=s.schema_id and [email protected]) a  
     WHERE ParentObject = @TableName  
    ' 

    print @sql 

    INSERT INTO @ShowFields_1(DatabaseName 
           ,TableOwner 
           ,TableName 
           ,ColumnDefaultName 
           ,FieldName 
          ) 
    exec sp_executesql @sql, 
       N'@TableName varchar(50),@schema varchar(50)', 
       @[email protected]_1,@[email protected]_1 

    INSERT INTO @ShowFields_2(DatabaseName 
           ,TableOwner 
           ,TableName 
           ,ColumnDefaultName 
           ,FieldName 
          ) 
    exec sp_executesql @sql, 
       N'@TableName varchar(50),@schema varchar(50)', 
       @[email protected]_2,@[email protected]_2 

    INSERT INTO @Definition(FieldValue_1) 
    select '['[email protected]_2+'_'+RIGHT(substring(convert(varchar(10),RAND()),3,10),10)+'] FOREIGN KEY '+FieldName+',' 
    from 
    (
     select COUNT(*)c,MAX(TableOwner)s,MAX(TableName)t,FieldName from 
     ( 
      select * from @ShowFields_1 union all 
      select * from @ShowFields_2 
     )t 
     group by FieldName   
    )t 
    where c=1 and [email protected]_1 and [email protected]_1 

    INSERT INTO @Definition(FieldValue_2) 
    select '['+k+'],' 
    from 
    (
     select COUNT(*)c,MAX(TableOwner)s,MAX(TableName)t,MAX(ColumnDefaultName)k,FieldName from 
     ( 
      select * from @ShowFields_1 union all 
      select * from @ShowFields_2 
     )t 
     group by FieldName   
    )t 
    where c=1 and [email protected]_2 and [email protected]_2 

    set @t1=case when (select COUNT(FieldValue_1) from @Definition)>0 then (select ' alter table '[email protected]_2+'.'[email protected]_2+' add CONSTRAINT'+(replace((select replace((SELECT SUBSTRING(FieldValue_1,0,LEN(FieldValue_1)+1) FROM @Definition FOR XML PATH('')),'</FieldValue_1>','')),'<FieldValue_1>',''))) else '' end 
    set @t2=case when (select COUNT(FieldValue_2) from @Definition)>0 then (select ' alter table '[email protected]_2+'.'[email protected]_2+' drop CONSTRAINT '+(replace((select replace((SELECT SUBSTRING(FieldValue_2,0,LEN(FieldValue_2)+1) FROM @Definition FOR XML PATH('')),'</FieldValue_2>','')),'<FieldValue_2>',''))) else '' end 

    --prima la drop, poi la add 
    set @script_drop =' '+ substring(@t2,0,len(@t2)) 
    set @script_add =' '+ substring(@t1,0,len(@t1)) 

    ----------------------------- 
    --Keys 
    ----------------------------- 

    delete @Definition 
    delete @ShowFields_1 
    delete @ShowFields_2 

    set @sql= 
    ' 
    use '[email protected]+' 
    SELECT DISTINCT PKObject = cco.object_id 
    FROM sys.key_constraints cco  
    JOIN sys.index_columns cc ON cco.parent_object_id = cc.object_id AND cco.unique_index_id = cc.index_id  
    JOIN sys.indexes i ON cc.object_id = i.object_id AND cc.index_id = i.index_id 
    join sys.schemas s on cco.schema_id=s.schema_id and [email protected] 
    WHERE OBJECT_NAME(parent_object_id) = @TableName AND i.type = 1 AND is_primary_key = 1 
    ' 
    print @sql 
    INSERT INTO @PKObjectID(ObjectID) 
    exec sp_executesql @sql, 
         N'@TableName varchar(50),@schema varchar(50)', 
         @[email protected]_1,@[email protected]_1 

    print @sql 
    INSERT INTO @PKObjectID(ObjectID) 
    exec sp_executesql @sql, 
         N'@TableName varchar(50),@schema varchar(50)', 
         @[email protected]_2,@[email protected]_2 
    /* 
    SELECT DISTINCT PKObject = cco.object_id 
    FROM sys.key_constraints cco  
    JOIN sys.index_columns cc ON cco.parent_object_id = cc.object_id AND cco.unique_index_id = cc.index_id  
    JOIN sys.indexes i ON cc.object_id = i.object_id AND cc.index_id = i.index_id 
    WHERE OBJECT_NAME(parent_object_id) = @TableName AND i.type = 1 AND is_primary_key = 1 
    */ 

    set @sql= 
    ' 
    use '[email protected]+' 
    SELECT DISTINCT PKObject = cco.object_id 
    FROM sys.key_constraints cco 
    JOIN sys.index_columns cc ON cco.parent_object_id = cc.object_id AND cco.unique_index_id = cc.index_id 
    JOIN sys.indexes i ON cc.object_id = i.object_id AND cc.index_id = i.index_id 
    join sys.schemas s on cco.schema_id=s.schema_id and [email protected] 
    WHERE OBJECT_NAME(parent_object_id) = @TableName AND i.type = 2 AND is_primary_key = 0 AND is_unique_constraint = 1 
    ' 
    print @sql 
    INSERT INTO @Uniques(ObjectID) 
    exec sp_executesql @sql, 
         N'@TableName varchar(50),@schema varchar(50)', 
         @[email protected]_1,@[email protected]_1 

    SET @ClusteredPK_1 = CASE WHEN @@ROWCOUNT > 0 THEN 1 ELSE 0 END 

    print @sql 
    INSERT INTO @Uniques(ObjectID) 
    exec sp_executesql @sql, 
         N'@TableName varchar(50),@schema varchar(50)', 
         @[email protected]_2,@[email protected]_2 

    SET @ClusteredPK_2 = CASE WHEN @@ROWCOUNT > 0 THEN 1 ELSE 0 END 

    -------------------------------------- 
    --PK 
    -------------------------------------- 

    delete @Definition 
    delete @ShowFields_1 
    delete @ShowFields_2 

    set @sql= 
    ' 
    use '[email protected]+' 
    SELECT distinct db_name(),@schema,@TableName,cco.name,CASE type WHEN ''PK'' THEN '' PRIMARY KEY '' + CASE WHEN pk.ObjectID IS NULL THEN '' NONCLUSTERED '' ELSE '' CLUSTERED '' END WHEN ''UQ'' THEN '' UNIQUE '' END + CASE WHEN u.ObjectID IS NOT NULL THEN '' NONCLUSTERED '' ELSE '''' END 
      + ''(''+REVERSE(SUBSTRING(REVERSE((SELECT c.name + + CASE WHEN cc.is_descending_key = 1 THEN '' DESC'' ELSE '' ASC'' END + '',''  
      FROM sys.key_constraints ccok 
      LEFT JOIN sys.index_columns cc ON ccok.parent_object_id = cc.object_id AND cco.unique_index_id = cc.index_id 
      LEFT JOIN sys.columns c ON cc.object_id = c.object_id AND cc.column_id = c.column_id 
      LEFT JOIN sys.indexes i ON cc.object_id = i.object_id AND cc.index_id = i.index_id 
      WHERE i.object_id = ccok.parent_object_id AND ccok.object_id = cco.object_id  
      order by key_ordinal FOR XML PATH(''''))), 2, 8000)) + '')'' 
      FROM sys.key_constraints cco 
      inner join sys.schemas s on cco.schema_id=s.schema_id and [email protected] 
      LEFT JOIN @U u ON cco.object_id = u.objectID 
      LEFT JOIN @t pk ON cco.object_id = pk.ObjectID  
      WHERE OBJECT_NAME(cco.parent_object_id) = @TableName 
    ' 

    declare @t TestTableType 
    insert @t select * from @PKObjectID 
    declare @u TestTableType 
    insert @u select * from @Uniques 

    print @sql 

    INSERT INTO @ShowFields_1(DatabaseName 
           ,TableOwner 
           ,TableName 
           ,ColumnDefaultName 
           ,FieldName 
          ) 
    exec sp_executesql @sql, 
         N'@TableName varchar(50),@schema varchar(50),@t TestTableType readonly,@u TestTableType readonly', 
         @[email protected]_1,@[email protected]_1,@[email protected],@[email protected] 

    INSERT INTO @ShowFields_2(DatabaseName 
           ,TableOwner 
           ,TableName 
           ,ColumnDefaultName 
           ,FieldName 
          ) 
    exec sp_executesql @sql, 
         N'@TableName varchar(50),@schema varchar(50),@t TestTableType readonly,@u TestTableType readonly', 
         @[email protected]_2,@[email protected]_2,@[email protected],@[email protected] 

    INSERT INTO @Definition(FieldValue_1) 
    select ' alter table '[email protected]_2+'.'[email protected]_2+' add constraint ['+k+'] '+FieldName+';' 
    from 
    (
     select COUNT(*)c,MAX(TableOwner)s,MAX(TableName)t,MAX(ColumnDefaultName)k,FieldName from 
     ( 
      select * from @ShowFields_1 union all 
      select * from @ShowFields_2 
     )t 
     group by FieldName   
    )t 
    where c=1 and [email protected]_1 and [email protected]_1 

    INSERT INTO @Definition(FieldValue_2) 
    select ' alter table '[email protected]_2+'.'[email protected]_2+' drop constraint ['+k+'] ;' 
    from 
    (
     select COUNT(*)c,MAX(TableOwner)s,MAX(TableName)t,MAX(ColumnDefaultName)k,FieldName from 
     ( 
      select * from @ShowFields_1 union all 
      select * from @ShowFields_2 
     )t 
     group by FieldName   
    )t 
    where c=1 and [email protected]_2 and [email protected]_2 

    set @t1=case when (select COUNT(FieldValue_1) from @Definition)>0 then ((replace((select replace((SELECT SUBSTRING(FieldValue_1,0,LEN(FieldValue_1)+1) FROM @Definition FOR XML PATH('')),'</FieldValue_1>','')),'<FieldValue_1>',''))) else '' end 
    set @t2=case when (select COUNT(FieldValue_2) from @Definition)>0 then ((replace((select replace((SELECT SUBSTRING(FieldValue_2,0,LEN(FieldValue_2)+1) FROM @Definition FOR XML PATH('')),'</FieldValue_2>','')),'<FieldValue_2>',''))) else '' end 

    --prima la drop, poi la add 
    set @script_drop +=' '+ substring(@t2,0,len(@t2)) 
    set @script_add =substring(@t1,0,len(@t1))+ ' ' [email protected]_add 


    -------------------------------------- 
    --Partition 
    -------------------------------------- 

    delete @Definition 
    delete @ShowFields_1 
    delete @ShowFields_2 

    set @sql= 
    ' 
    use '[email protected]+' 
    select @partition='' on '' + d.name + ''([''+c.name+''])'' 
    from sys.tables t join sys.indexes i on(i.object_id = t.object_id and i.index_id < 2) 
         join sys.index_columns ic on(ic.partition_ordinal > 0 and ic.index_id = i.index_id and ic.object_id = t.object_id) 
         join sys.columns c on(c.object_id = ic.object_id and c.column_id = ic.column_id) 
         join sys.schemas s on t.schema_id=s.schema_id 
         join sys.data_spaces d on i.data_space_id=d.data_space_id 
    where [email protected] and [email protected] 
    order by key_ordinal 
    ' 

    print 'x' 
    print @sql 
    exec sp_executesql @sql, 
         N'@TableName varchar(50),@schema varchar(50),@partition varchar(max) output', 
         @[email protected]_1,@[email protected]_1,@[email protected] output 

    if(@partition is null) 
     set @partition='' 

    --select @partition  

    -------------------------------------- 
    --Indexes 
    -------------------------------------- 

    delete @Definition 
    delete @ShowFields_1 
    delete @ShowFields_2 

    IF @IncludeIndexes = 1 
    BEGIN 
     set @sql= 
     ' 
     use '[email protected]+' 
     SELECT DB_NAME(),s.name,t.name,i.name COLLATE SQL_Latin1_General_CP1_CI_AS, i.type_desc ,''(''+REVERSE(SUBSTRING(REVERSE(( SELECT name + CASE WHEN sc.is_descending_key = 1 THEN '' DESC'' ELSE '' ASC'' END + '','' 
     FROM sys.index_columns sc 
     JOIN sys.columns c ON sc.object_id = c.object_id AND sc.column_id = c.column_id 
     WHERE [email protected] AND sc.object_id = i.object_id 
           AND sc.index_id = i.index_id 
           and t.schema_id=s.schema_id 
           and is_included_column=0 
           --caso di tabelle partizionate 
           --inserisce in automatico la pk 
           and (key_ordinal!=0 or partition_ordinal!=1) 
     ORDER BY key_ordinal ASC FOR XML PATH('''') )), 2, 8000)) + '')''+ 
     ISNULL('' include (''+REVERSE(SUBSTRING(REVERSE(( SELECT name + '','' 
     FROM sys.index_columns sc 
     JOIN sys.columns c ON sc.object_id = c.object_id AND sc.column_id = c.column_id 
     WHERE [email protected] AND sc.object_id = i.object_id 
           AND sc.index_id = i.index_id 
           and t.schema_id=s.schema_id 
           and is_included_column=1 
     ORDER BY key_ordinal ASC FOR XML PATH('''') )), 2, 8000))+'')'' ,'''')+''''  
     FROM sys.indexes i join sys.tables t on i.object_id=t.object_id 
          join sys.schemas s on t.schema_id=s.schema_id 
     AND CASE WHEN @ClusteredPK = 1 AND is_primary_key = 1 AND i.type = 1 THEN 0 ELSE 1 END = 1 AND is_unique_constraint = 0 AND is_primary_key = 0 
      where [email protected] and [email protected] 
     ' 

     print @ClusteredPK_1 
     print @sql 
     INSERT INTO @ShowFields_1(DatabaseName 
            ,TableOwner 
            ,TableName 
            ,ColumnDefaultName 
            ,ColumnDefaultValue 
            ,FieldName 
           ) 
     exec sp_executesql @sql, 
          N'@TableName varchar(50),@schema varchar(50), @ClusteredPK bit', 
          @[email protected]_1,@[email protected]_1,@[email protected]_1 


     INSERT INTO @ShowFields_2(DatabaseName 
            ,TableOwner 
            ,TableName 
            ,ColumnDefaultName 
            ,ColumnDefaultValue 
            ,FieldName 
           ) 
     exec sp_executesql @sql, 
          N'@TableName varchar(50),@schema varchar(50), @ClusteredPK bit', 
          @[email protected]_2,@[email protected]_2,@[email protected]_2 


     INSERT INTO @Definition(FieldValue_1) 
     select 'create '+ColumnDefaultValue+' index ['+n+'] on '[email protected]_2+'.'[email protected][email protected]+';' 
     from 
     (
      select COUNT(*)c,MAX(TableOwner)s,MAX(TableName)t,MAX(ColumnDefaultName)n,ColumnDefaultValue,FieldName from 
      ( 
       select * from @ShowFields_1 union all 
       select * from @ShowFields_2 
      )t 
      group by ColumnDefaultValue,FieldName   
     )t 
     where c=1 and [email protected]_1 and [email protected]_1 

     INSERT INTO @Definition(FieldValue_2) 
     select 'drop index ['+n+'] on '[email protected]_2+'.'[email protected]_2+' ;' 
     from 
     (
      select COUNT(*)c,MAX(TableOwner)s,MAX(TableName)t,MAX(ColumnDefaultName)n,ColumnDefaultValue,FieldName from 
      ( 
       select * from @ShowFields_1 union all 
       select * from @ShowFields_2 
      )t 
      group by ColumnDefaultValue,FieldName   
     )t 
     where c=1 and [email protected]_2 and [email protected]_2 

     set @t1=case when (select COUNT(FieldValue_1) from @Definition)>0 then ((replace((select replace((SELECT SUBSTRING(FieldValue_1,0,LEN(FieldValue_1)+1) FROM @Definition FOR XML PATH('')),'</FieldValue_1>','')),'<FieldValue_1>',''))) else '' end 
     set @t2=case when (select COUNT(FieldValue_2) from @Definition)>0 then ((replace((select replace((SELECT SUBSTRING(FieldValue_2,0,LEN(FieldValue_2)+1) FROM @Definition FOR XML PATH('')),'</FieldValue_2>','')),'<FieldValue_2>',''))) else '' end 

     --prima la drop, poi la add 
     set @script_drop +=' '+ substring(@t2,0,len(@t2)) 
     set @script_add =substring(@t1,0,len(@t1))+ ' ' [email protected]_add 

    END  
    ----------------------------- 
    --Columns 
    ----------------------------- 

    delete @Definition 
    delete @ShowFields_1 
    delete @ShowFields_2 

    set @sql= 
    ' 
    use '[email protected]+' 
    SELECT distinct DB_NAME() 
      ,TABLE_SCHEMA 
      ,TABLE_NAME 
      ,''[''+COLUMN_NAME+'']'' as COLUMN_NAME 
      ,CAST(ORDINAL_POSITION AS INT) 
      ,COLUMN_DEFAULT 
      ,dobj.name AS ColumnDefaultName 
      ,CASE WHEN c.IS_NULLABLE = ''YES'' THEN 1 ELSE 0 END 
      ,DATA_TYPE 
      ,case CHARACTER_MAXIMUM_LENGTH when -1 then ''max'' else CAST(CHARACTER_MAXIMUM_LENGTH AS varchar) end--CAST(CHARACTER_MAXIMUM_LENGTH AS INT) 
      ,CAST(NUMERIC_PRECISION AS INT) 
      ,CAST(NUMERIC_SCALE AS INT) 
      ,DOMAIN_NAME 
      ,COLUMN_NAME + '','' 
      ,'''' AS FieldDefinition 
      ,CASE WHEN ic.object_id IS NULL THEN 0 ELSE 1 END AS IdentityColumn 
      ,CAST(ISNULL(ic.seed_value,0) AS INT) AS IdentitySeed 
      ,CAST(ISNULL(ic.increment_value,0) AS INT) AS IdentityIncrement 
      ,CASE WHEN st.collation_name IS NOT NULL THEN 1 ELSE 0 END AS IsCharColumn 
      ,cc.definition 
      FROM INFORMATION_SCHEMA.COLUMNS c 
      JOIN sys.columns sc ON c.TABLE_NAME = OBJECT_NAME(sc.object_id) AND c.COLUMN_NAME = sc.Name 
      LEFT JOIN sys.identity_columns ic ON c.TABLE_NAME = OBJECT_NAME(ic.object_id) AND c.COLUMN_NAME = ic.Name 
      JOIN sys.types st ON COALESCE(c.DOMAIN_NAME,c.DATA_TYPE) = st.name 
      LEFT OUTER JOIN sys.objects dobj ON dobj.object_id = sc.default_object_id AND dobj.type = ''D'' 
      left join sys.computed_columns cc on c.TABLE_NAME=OBJECT_NAME(cc.object_id) and sc.column_id=cc.column_id 
    WHERE c.TABLE_NAME = @TableName and [email protected] 
    ORDER BY c.TABLE_NAME, c.ORDINAL_POSITION 
    ' 

    print @sql 
    INSERT INTO @ShowFields_1(DatabaseName 
            ,TableOwner 
            ,TableName 
            ,FieldName 
            ,ColumnPosition 
            ,ColumnDefaultValue 
            ,ColumnDefaultName 
            ,IsNullable 
            ,DataType 
            ,MaxLength 
            ,NumericPrecision 
            ,NumericScale 
            ,DomainName 
            ,FieldListingName 
            ,FieldDefinition 
            ,IdentityColumn 
            ,IdentitySeed 
            ,IdentityIncrement 
            ,IsCharColumn 
            ,IsComputed) 

    exec sp_executesql @sql, 
         N'@TableName varchar(50),@schema varchar(50)', 
         @[email protected]_1,@[email protected]_1  

    INSERT INTO @ShowFields_2(DatabaseName 
            ,TableOwner 
            ,TableName 
            ,FieldName 
            ,ColumnPosition 
            ,ColumnDefaultValue 
            ,ColumnDefaultName 
            ,IsNullable 
            ,DataType 
            ,MaxLength 
            ,NumericPrecision 
            ,NumericScale 
            ,DomainName 
            ,FieldListingName 
            ,FieldDefinition 
            ,IdentityColumn 
            ,IdentitySeed 
            ,IdentityIncrement 
            ,IsCharColumn 
            ,IsComputed) 

    exec sp_executesql @sql, 
         N'@TableName varchar(50),@schema varchar(50)', 
         @[email protected]_2,@[email protected]_2    


      ---------------------------------- 


    INSERT INTO @Definition(state,FieldValue_1) 
    SELECT t2.c,t.FieldName + ' ' + 
     --CASE WHEN DomainName IS NOT NULL AND @UseSystemDataTypes = 0 THEN DomainName + CASE WHEN IsNullable = 1 THEN ' NULL ' ELSE ' NOT NULL ' END ELSE UPPER(DataType) +CASE WHEN IsCharColumn = 1 THEN '(' + CAST(MaxLength AS VARCHAR(10)) + ')' ELSE '' END +CASE WHEN IdentityColumn = 1 THEN ' IDENTITY(' + CAST(IdentitySeed AS VARCHAR(5))+ ',' + CAST(IdentityIncrement AS VARCHAR(5)) + ')' ELSE '' END +CASE WHEN IsNullable = 1 THEN ' NULL ' ELSE ' NOT NULL ' END +CASE WHEN ColumnDefaultName IS NOT NULL AND @IncludeConstraints = 1 THEN 'CONSTRAINT [' + ColumnDefaultName + '] DEFAULT' + UPPER(ColumnDefaultValue) ELSE '' END END + CASE WHEN FieldID = (SELECT MAX(FieldID) FROM @ShowFields) THEN '' ELSE ',' END 

     CASE WHEN DomainName IS NOT NULL AND @UseSystemDataTypes = 0 THEN DomainName + 
      CASe WHEN IsNullable = 1 THEN ' NULL ' 
      ELSE ' NOT NULL ' 
      END 
     ELSE 
      case when IsComputed is null then 
       UPPER(DataType) + 
       CASE WHEN IsCharColumn = 1 THEN '(' + CAST(MaxLength AS VARCHAR(10)) + ')' 
       ELSE 
        CASE WHEN DataType = 'numeric' THEN '(' + CAST(NumericPrecision AS VARCHAR(10))+','+ CAST(NumericScale AS VARCHAR(10)) + ')' 
        ELSE 
         CASE WHEN DataType = 'decimal' THEN '(' + CAST(NumericPrecision AS VARCHAR(10))+','+ CAST(NumericScale AS VARCHAR(10)) + ')' 
         ELSE '' 
         end 
        end 
       END + 
       CASE WHEN IdentityColumn = 1 THEN ' IDENTITY(' + CAST(IdentitySeed AS VARCHAR(5))+ ',' + CAST(IdentityIncrement AS VARCHAR(5)) + ')' 
       ELSE '' 
       END + 
       CASE WHEN IsNullable = 1 THEN ' NULL ' 
       ELSE ' NOT NULL ' 
       END + 
       CASE WHEN ColumnDefaultName IS NOT NULL AND @IncludeConstraints = 1 THEN 'CONSTRAINT [' + replace(ColumnDefaultName,@TableName_1,@TableName_2) + '] DEFAULT' + UPPER(ColumnDefaultValue) 
       ELSE '' 
       END 
      else 
       ' as '+IsComputed+' ' 
      end 
     END + 
     --, per add, ; per alter 
     CASE WHEN t2.c = 1 THEN ',' 
     ELSE ';' 
     END 

    from 
    (
     select * 
     FROM  
     (  --escludo la ColumnPosition xkè: 
       -- c1, c2, c3 
       -- cancello c2 e aggiungo c4 quindi 
       -- c1, c3, c4 
       -- c2 è in posizione 2 
       -- se considero anche la ColumnPosition c3 sarebbe da cancellare e ricreare, e perderei i dati 
       -- in qsto modo mantengo la stessa colonna che con la drop delle altre si rimette al suo posto 
       -- ATTENZIONE.!!. 
       -- se cancello c2 e poi lo ricreo (passa da posizione 2 a posizione 3) nn percepisco il cambiamento 
       select COUNT(*)c,MAX(TableOwner) s,MAX(TableName) t,MAX(ColumnPosition)p 
         ,FieldName,ColumnDefaultValue,ColumnDefaultName,IsNullable,DataType 
         ,MaxLength,NumericPrecision,NumericScale,DomainName,FieldListingName,FieldDefinition 
         ,IdentityColumn,IdentitySeed,IdentityIncrement,IsCharColumn,IsComputed 
       from 
       (
        select * from @ShowFields_1 union all 
        select * from @ShowFields_2 
        --order by TableOwner,TableName,ColumnPosition 
       )t 
       group by FieldName,ColumnDefaultValue,ColumnDefaultName,IsNullable,DataType 
         ,MaxLength,NumericPrecision,NumericScale,DomainName,FieldListingName,FieldDefinition 
         ,IdentityColumn,IdentitySeed,IdentityIncrement,IsCharColumn,IsComputed 
     )t 
     where [email protected]_1 and [email protected]_1 and c=1 
    )t 
    --distinguo le colonne columi(t2.c=2 -> alter column; t2.c=1 -> add column) 
    join 
    (
     select FieldName,COUNT(*)c from 
     (
      select FieldName from @ShowFields_1 union all 
      select FieldName from @ShowFields_2 
     )a 
     group by FieldName 
    )t2 on t.FieldName=t2.FieldName 
    order by s,t,p--,ColumnPosition 

    INSERT INTO @Definition(FieldValue_2) 
    SELECT ' '+t.FieldName + ', ' 
    from 
    (
     select * 
     FROM  
     (  --escludo la ColumnPosition xkè: 
       -- c1, c2, c3 
       -- cancello c2 e aggiungo c4 quindi 
       -- c1, c3, c4 
       -- c2 è in posizione 2 
       -- se considero anche la ColumnPosition c3 sarebbe da cancellare e ricreare, e perderei i dati 
       -- in qsto modo mantengo la stessa colonna che con la drop delle altre si rimette al suo posto 
       -- ATTENZIONE.!!. 
       -- se cancello c2 e poi lo ricreo (passa da posizione 2 a posizione 3) nn percepisco il cambiamento 
       select COUNT(*)c,MAX(TableOwner) s,MAX(TableName) t--,MAX(ColumnPosition)p 
         ,FieldName,ColumnDefaultValue,ColumnDefaultName,IsNullable,DataType 
         ,MaxLength,NumericPrecision,NumericScale,DomainName,FieldListingName,FieldDefinition 
         ,IdentityColumn,IdentitySeed,IdentityIncrement,IsCharColumn,IsComputed 
       from 
       (
        select * from @ShowFields_1 union all 
        select * from @ShowFields_2 
        --order by TableOwner,TableName,ColumnPosition 
       )t 
       group by FieldName,ColumnDefaultValue,ColumnDefaultName,IsNullable,DataType 
         ,MaxLength,NumericPrecision,NumericScale,DomainName,FieldListingName,FieldDefinition 
         ,IdentityColumn,IdentitySeed,IdentityIncrement,IsCharColumn,IsComputed 
     )t 
     where [email protected]_2 and [email protected]_2 and c=1 
    )t 
    --distinguo le colonne columi tra le tabelle(t2.c=2 -> alter column; t2.c=1 -> add column) 
    join 
    (
     select FieldName,COUNT(*)c from 
     (
      select FieldName from @ShowFields_1 union all 
      select FieldName from @ShowFields_2 
     )a 
     group by FieldName 
     having COUNT(*)=1 
    )t2 on t.FieldName=t2.FieldName 
    order by s,t--,ColumnPosition 

    --state=1 -> add 
    --state=2 -> alter 
    set @t0=case when (select COUNT(FieldValue_1) from @Definition where state=1)>0 then (select ' alter table '[email protected]_2+'.'[email protected]_2+' add '+(replace((select replace((SELECT SUBSTRING(FieldValue_1,0,LEN(FieldValue_1)+1) FROM @Definition where state=1 FOR XML PATH('')),'</FieldValue_1>','')),'<FieldValue_1>',''))) else '' end 
    set @t1=case when (select COUNT(FieldValue_1) from @Definition where state=2)>0 then (select (replace((select replace((SELECT ' alter table '[email protected]_2+'.'[email protected]_2+' alter column '+SUBSTRING(FieldValue_1,0,LEN(FieldValue_1)+1) FROM @Definition where state=2 FOR XML PATH('')),'</FieldValue_1>','')),'<FieldValue_1>',''))) else '' end 
    set @t2=case when (select COUNT(FieldValue_2) from @Definition)>0 then (select ' alter table '[email protected]_2+'.'[email protected]_2+' drop column '+(replace((select replace((SELECT SUBSTRING(FieldValue_2,0,LEN(FieldValue_2)+1) FROM @Definition FOR XML PATH('')),'</FieldValue_2>','')),'<FieldValue_2>',''))) else '' end 

    --prima la drop, poi la add 
    set @script_drop +=' '+ substring(@t2,0,len(@t2)) 
    set @script_add =substring(@t0,0,len(@t0)) + ' ' + substring(@t1,0,len(@t1))+ ' ' [email protected]_add 

    set @[email protected][email protected]_add 


END try 
-- ############################################################################################################################################################################## 
BEGIN CATCH   
    BEGIN 

      PRINT 'ErrorNumber    : ' + CAST(ERROR_NUMBER() AS NVARCHAR(MAX)) 
      PRINT 'ErrorSeverity    : ' + CAST(ERROR_SEVERITY() AS NVARCHAR(MAX)) 
      PRINT 'ErrorState    : ' + CAST(ERROR_STATE() AS NVARCHAR(MAX)) 
      PRINT 'ErrorLine     : ' + CAST(ERROR_LINE() AS NVARCHAR(MAX)) 
      PRINT 'ErrorMessage    : ' + CAST(ERROR_MESSAGE() AS NVARCHAR(MAX)) 
      PRINT 
    END 
     set @script='' 
    return -1 
END CATCH 

exec il:

declare @s varchar(max) 
exec [util_ScriptTable_Update] 'db','schema_source','table_source',1,1,'schema_dest','tab_dest',0,@s output 
select @s 
Questions connexes