web-dev-qa-db-ja.com

既存の列にIDを追加する

テーブルの主キーをidentityカラムに変更する必要があります。テーブルにはすでにいくつかの行があります。

IDが1から順番になるようにIDをクリーンアップするスクリプトを作成しました。テストデータベースでは正常に動作します。

IDプロパティを持つように列を変更するためのSQLコマンドは何ですか?

395
Kirschstein

識別用に既存の列を変更することはできません。

2つの選択肢があります、

  1. IDを指定して新しいテーブルを作成し、既存のテーブルを削除します

  2. IDを指定して新しい列を作成し、既存の列を削除します

アプローチ1( 新しいテーブル )ここで、新しく作成したID列に既存のデータ値を保持できます。

CREATE TABLE dbo.Tmp_Names
    (
      Id int NOT NULL
             IDENTITY(1, 1),
      Name varchar(50) NULL
    )
ON  [PRIMARY]
go

SET IDENTITY_INSERT dbo.Tmp_Names ON
go

IF EXISTS ( SELECT  *
            FROM    dbo.Names ) 
    INSERT  INTO dbo.Tmp_Names ( Id, Name )
            SELECT  Id,
                    Name
            FROM    dbo.Names TABLOCKX
go

SET IDENTITY_INSERT dbo.Tmp_Names OFF
go

DROP TABLE dbo.Names
go

Exec sp_rename 'Tmp_Names', 'Names'

アプローチ2( 新しい列 )新しく作成したID列に既存のデータ値を保持することはできません。ID列には一連の番号が入ります。

Alter Table Names
Add Id_new Int Identity(1, 1)
Go

Alter Table Names Drop Column ID
Go

Exec sp_rename 'Names.Id_new', 'ID', 'Column'

詳細については、次のMicrosoft SQL Serverフォーラムの投稿を参照してください。

カラムをアイデンティティに変更する方法(1,1)

429
John Sansom

SQL 2005以降では、テーブルのデータページを変更せずにこの問題を解決するためのトリックがあります。これは、すべてのデータページに触れるのに数分から数時間かかる大きなテーブルでは重要です。 ID列が主キーである場合、クラスタ化インデックスまたは非クラスタ化インデックスの一部である場合、またはより簡単な "列の追加/削除/名前の変更"の解決策に失敗する可能性がある場合でも、この手法は有効です。

SQL Serverの ALTER TABLE ... SWITCH ステートメントを使用してデータを変更せずにテーブルのスキーマを変更できます。つまり、テーブルをIDENTITYで同一のテーブルスキーマに置き換えることができます。 IDENTITY列なし。同じ方法で既存の列にIDENTITYを追加することもできます。

通常、 ALTER TABLE ... SWITCH は、パーティション表のフルパーティションを新しい空のパーティションで効率的に置き換えるために使用されます。ただし、非パーティション表でも使用できます。

このトリックを使用して、25秒の行テーブルの列をIDENTITYから非IDENTITYに変換しました(非IDENTITYに対してクエリプランがより効果的に機能する複数時間のクエリを実行するため)。その後、5秒以内にIDENTITY設定を復元します。

これがどのように機能するかのコードサンプルです。

 CREATE TABLE Test
 (
   id int identity(1,1),
   somecolumn varchar(10)
 );

 INSERT INTO Test VALUES ('Hello');
 INSERT INTO Test VALUES ('World');

 -- copy the table. use same schema, but no identity
 CREATE TABLE Test2
 (
   id int NOT NULL,
   somecolumn varchar(10)
 );

 ALTER TABLE Test SWITCH TO Test2;

 -- drop the original (now empty) table
 DROP TABLE Test;

 -- rename new table to old table's name
 EXEC sp_rename 'Test2','Test';

 -- update the identity seed
 DBCC CHECKIDENT('Test');

 -- see same records
 SELECT * FROM Test; 

これは明らかに他の答えの解決策よりも複雑ですが、あなたのテーブルが大きい場合、これは本当の命を救うことができます。注意点がいくつかあります。

  • 私の知る限りでは、この方法でテーブルの列を変更できるのはIDだけです。列の追加/削除、null入力可能性の変更などは許可されていません。
  • 切り替えを行う前にforiegnキーを削除して、後で元に戻す必要があります。
  • WITH SCHEMABINDING関数、ビューなども同じです。
  • 新しいテーブルのインデックスは完全に一致する必要があります(同じ列、同じ順序など)。
  • 古いテーブルと新しいテーブルは同じファイルグループに存在する必要があります。
  • SQL Server 2005以降でのみ動作します
  • 私は以前、このトリックはSQL ServerのEnterpriseまたはDeveloperエディションでのみ機能すると考えていましたが(パーティションはEnterpriseおよびDeveloperバージョンでのみサポートされているため)、Mason G. Zhwitiは下記のコメントでSQL Standard Editionでも機能すると述べています。これは、EnterpriseまたはDeveloperへの制限がALTER TABLE ... SWITCHには適用されないことを意味します。

上記の要件を詳述した優れた TechNetの記事 があります。

UPDATE - Eric Wu さんに、この解決策に関する重要な情報を追加する以下のコメントがありました。それがもっと注目を集めることを確認するためにここにそれをコピーする:

言及する価値があるもう一つの注意がここにあります。新しいテーブルは古いテーブルから喜んでデータを受け取り、すべての新しい行は識別パターンに従って挿入されますが、それらは1から始まり、その列が主キーの場合は壊れる可能性があります。切り替え直後にDBCC CHECKIDENT('<newTableName>')を実行することを検討してください。詳細については、 msdn.Microsoft.com/en-us/library/ms176057.aspx を参照してください。

テーブルが新しい行でアクティブに拡張されている場合(つまり、IDENTITYを追加してから新しい行を追加するまでのダウンタイムが少ない場合は、DBCC CHECKIDENTの代わりに新しいテーブルスキーマのIDシード値を手動で設定します)。 IDENTITY (2435457, 1)のように、テーブル内に存在する最大のIDよりも大きくすることができますトランザクションにALTER TABLE...SWITCHDBCC CHECKIDENTの両方を含めることはできます(またはこれをテストしていません)が、シードを設定するようです。手動で値を設定する方が簡単で安全になります。

明らかに、新しい行がテーブルに追加されていない場合(または毎日のETLプロセスのように時々追加されるだけの場合)、この競合状態は発生しないので、DBCC CHECKIDENTは問題ありません。

182
Justin Grant

列をIDENTITY列に変更することはできません。 get-goからIDENTITYとして定義されている新しい列を作成し、次に古い列をドロップして、新しい列の名前を古い名前に変更します。

ALTER TABLE (yourTable) ADD NewColumn INT IDENTITY(1,1)

ALTER TABLE (yourTable) DROP COLUMN OldColumnName

EXEC sp_rename 'yourTable.NewColumn', 'OldColumnName', 'COLUMN'

マーク

63
marc_s

ここで説明されているクールな解決策があります: SQLサーバ - 列にIDプロパティを追加または削除

簡単に言うと、SQLマネージャでテーブルを手動で編集し、IDを変更し、変更を保存しないで、変更用に作成されるスクリプトを表示してコピーして後で使用するだけです。

変更したテーブルに関連するすべての外部キー、インデックスなどが含まれているため、非常に時間がかかりません。これを手動で書くと…神は禁じられています。

14
greenoldman

IDENTITYの代わりにSEQUENCE を使用することを検討してください。

IN SQL Serverの2014(私はより低いバージョンについては知らない)あなたはシーケンスを使用して、これを簡単に行うことができます。

CREATE SEQUENCE  sequence_name START WITH here_higher_number_than_max_existed_value_in_column INCREMENT BY 1;

ALTER TABLE table_name ADD CONSTRAINT constraint_name DEFAULT NEXT VALUE FOR sequence_name FOR column_name

ここから: 列のデフォルト値としてのシーケンス

6
OTAR

簡単な説明

Sp_RENAMEを使用して既存の列の名前を変更する

EXEC sp_RENAME 'Table_Name.Existing_ColumnName'、 'New_ColumnName'、 'C​​OLUMN'

名前変更の例:

既存の列UserIDはOldUserIDに名前変更されました

EXEC sp_RENAME 'AdminUsers.UserID' , 'OldUserID', 'COLUMN'

次に、alter queryを使用して新しい列を追加し、主キーおよびID値として設定します。

ALTER TABLE TableName ADD Old_ColumnName INT NOT NULL PRIMARY KEY IDENTITY(1,1)

主キー設定の例

新しく作成された列名はUserIDです

ALTER TABLE Users ADD UserID INT NOT NULL PRIMARY KEY IDENTITY(1,1)

次に名前を変更した列を削除します

ALTER TABLE Table_Name DROP COLUMN Renamed_ColumnName

列の名前を変更したDropの例

ALTER TABLE Users DROP COLUMN OldUserID

これで、テーブルの既存の列に主キーとIDを追加しました。

6

私はたまたまDBAなしでチームに参加したJava開発者で、開発者としてDBA権限を取得できない人です。スキーマ全体を2つのデータベース間で移動する作業を担当していたため、DBAを使用せずにスクリプトを実行して作業する必要がありました。管理者権限がないため、SQL Server 2008ではGUIを使用できませんでした。

すべて問題なく移動できましたが、新しいschema.tableでストアドプロシージャを実行すると、テーブルのIDフィールドが失われました。私はテーブルを作成したスクリプトを二重チェックしました、そして、それはそこにありました、しかし、私がスクリプトを走らせたとき、SQL Serverはそれを得ませんでした。私はDBAから後で、同じ問題を以前に経験したことがあると言われました。

いずれにせよ、SQL Server 2008の場合、これらは解決するために私が講じた手順であり、うまくいきました。したがって、これが誰かに役立つことを願ってここに投稿します。これは私がこれをより困難にした別のテーブルへのFKの依存関係を持っていたので私がしたことです:

このクエリを使用して、IDが実際に欠落していることを確認し、テーブルへの依存関係を表示しました。

1.)テーブルで統計を見つけます。

exec sp_help 'dbo.table_name_old';

2.)PKフィールドの以前のIDフィールドを追加することを除いて、重複した同一の新しいテーブルを作成します。

3.)データを移動するためにIDを無効にします。

SET IDENTITY_INSERT dbo.table_name ON 

4.)データを転送してください。

INSERT INTO dbo.table_name_new
(
field1, field2, etc...
)
SELECT 
field1, field2, etc...
FROM 
dbo.table_name_old;

5.)データがあることを確認してください。

SELECT * FROM dbo.table_name_new

6.)IDを再度有効にします。

SET IDENTITY_INSERT ToyRecP.ToyAwards.lkpFile_New OFF

7.) これは、元のテーブルがどのテーブルを依存関係として参照しているかを確認するためのすべてのFK関係を取得するために見つけた最良のスクリプトです。

SELECT f.name AS ForeignKey,
   OBJECT_NAME(f.parent_object_id) AS TableName,
   COL_NAME(fc.parent_object_id, fc.parent_column_id) AS ColumnName,
   OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName,
   COL_NAME(fc.referenced_object_id, fc.referenced_column_id) AS ReferenceColumnName
FROM sys.foreign_keys AS f
INNER JOIN sys.foreign_key_columns AS fc
   ON f.OBJECT_ID = fc.constraint_object_id
   ORDER BY ReferenceTableName;

8.)この次のステップの前に、関係するすべてのテーブルのすべてのPKおよびFKスクリプトがあることを確認してください。

9.)各キーを右クリックし、SQL Server 2008を使用してこれをスクリプト化することができます。

10.)次の構文を使用して、依存関係テーブルからFKを削除します。

ALTER TABLE [dbo].[table_name] DROP CONSTRAINT [Name_of_FK]

11.)元のテーブルを削除します。

DROP TABLE dbo.table_name_old;

13.)次の手順は、手順9でSQL Server 2008で作成したスクリプトに基づいています。

- 新しいテーブルにPKを追加します。

- 新しいテーブルにFKを追加します。

- FKを依存関係テーブルに追加します。

14.)すべてが正しく完了していることを確認します。私はGUIを使ってテーブルを見ました。

15.)新しいテーブルの名前を元のテーブルの名前に変更します。

exec sp_RENAME '[Schema_Name.OldTableName]' , '[NewTableName]';

最後に、すべてがうまくいった!

5
James Drinkard

通常のケースで理解したように、Identityプロパティを持つPrimary keyでテーブルを作成しています。
したがって、Primary Keyconstraintに関連付けられている列のRenameまたはDeleteは、制約規則によって列構造が検証されるため使用できません。
これを達成するには、次のようにいくつかのステップを処理する必要があります。
TableName = 'Employee'およびColumnName = 'EmployeeId'とします。

1。 'Employee'テーブルに新しい列 'EmployeeId_new'を追加します。
ALTER TABLE従業員ADD EmployeeId_new INT IDENTITY(1,1)

  1. 'Employee'テーブルから 'EmployeeId'列を削除します
    ALTER TABLE従業員DROP COLUMN EmployeeId

  2. 主キー制約規則が適用可能であり、列構造を検証するため、これはエラーをスローします。
    * ### ' メッセージ5074、レベル16、状態1、行1オブジェクト[PK_dbo.Employee]はcolmn [EmployeeId]に依存しています。 ###

  3. したがって、最初にテーブル 'Employee'から主キー制約を削除する必要があります。その後、列を削除できます。
    ALTER TABLE従業員DROP制約[PK_dbo.Employee]

  4. これで、エラーが発生した前の手順で行ったように、 'Employee'テーブルから 'EmployeeId'列を削除できます。
    ALTER TABLE従業員DROP COLUMN EmployeeId

  5. これで、列 'EmployeeId'がテーブルから削除されたので、新しく追加した新しい列 'EmployeeId_new'の名前を 'EmployeeId'に変更します。
    sp_rename 'Employee.EmployeeId'、 'EmployeeId_new'、 'C​​OLUMN'

  6. テーブルを元の状態と同じ形式に並べ替えるには、列 'EmployeeId'に主キー制約を追加する必要があります。
    ALTER TABLE従業員追加制約[PK_dbo.Employee]主キー(EmployeeId)

8. 現在、 'EmployeeId'を持つテーブル 'Employee'は、既存の主キー制約と共にIdentityルール用に変更されています。

3
Rinku

設計上、既存の列のID機能をオンまたはオフにする簡単な方法はありません。これを行う唯一のきれいな方法は、新しい列を作成してそれを識別列にするか、または新しいテーブルを作成してデータを移行することです。

SQL Server Management Studioを使用して列 "id"のID値を削除すると、新しい一時テーブルが作成され、データが一時テーブルに移動され、古いテーブルが削除され、新しいテーブルの名前が変更されます。

Management Studioを使用して変更を加え、デザイナーを右クリックして[Generate Change Script]を選択します。

これが、SQLサーバーがバックグラウンドで実行していることです。

3
Raj

そのようなことはできません。別の列を追加し、元の列を削除して新しい列を作成するか、新しいテーブルを作成するか、データをコピーして古いテーブルを削除してから新しいテーブルの名前を変更する必要があります。表

sSMSを使用し、デザイナでidentityプロパティをONに設定した場合は、SQL Serverがその背後で行うことになります。あなたが[user]という名前のテーブルを持っているなら、これはあなたがUserIDとidentityを作るとどうなるかです。

BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION

GO

GO
CREATE TABLE dbo.Tmp_User
    (
    UserID int NOT NULL IDENTITY (1, 1),
    LastName varchar(50) NOT NULL,
    FirstName varchar(50) NOT NULL,
    MiddleInitial char(1) NULL

    )  ON [PRIMARY]
GO

SET IDENTITY_INSERT dbo.Tmp_User ON
GO
IF EXISTS(SELECT * FROM dbo.[User])
 EXEC('INSERT INTO dbo.Tmp_User (UserID, LastName, FirstName, MiddleInitial)
    SELECT UserID, LastName, FirstName, MiddleInitialFROM dbo.[User] TABLOCKX')
GO
SET IDENTITY_INSERT dbo.Tmp_User OFF
GO

GO
DROP TABLE dbo.[User]
GO
EXECUTE sp_rename N'dbo.Tmp_User', N'User', 'OBJECT'
GO
ALTER TABLE dbo.[User] ADD CONSTRAINT
    PK_User PRIMARY KEY CLUSTERED 
    (
    UserID
    ) ON [PRIMARY]

GO
COMMIT

ビット単位の値を設定することでシステムテーブルをハックしてそれを達成する方法はあるとは言っても、それはサポートされていませんし、私もそうしません

3
SQLMenace

列のIDプロパティを変更するには

  • サーバーエクスプローラで、変更するIDプロパティを含むテーブルを右クリックし、[テーブル定義を開く]をクリックします。テーブルがテーブルデザイナーで開きます。
  • 変更する列の[NULLを許可する]チェックボックスをオフにします。
  • 「列プロパティー」タブで、「ID仕様」プロパティーを展開します。
  • Is Identity子プロパティのグリッドセルをクリックし、ドロップダウンリストからYesを選択します。
  • Identity Seedセルに値を入力します。この値はテーブルの最初の行に割り当てられます。値1がデフォルトで割り当てられます。

それはそれだ、そしてそれは私のために働いた

2
Ken.Fukizi

残念ながら、それはありません。 IDENTITYプロパティは列ではなくテーブルに属します。

より簡単な方法はGUIでそれを行うことですが、これが選択肢でない場合は、データをコピーし、列を削除し、IDを付けて再度追加し、そしてデータを元に戻すという長い道のりを回ることができます。

一撃一撃のアカウントについては ここ を参照してください。

2
Jeremy Smyth

オブジェクトエクスプローラでテーブル名を右クリックします。いくつかの選択肢があります。 「デザイン」をクリックしてください。このテーブル用に新しいタブが開きます。ここで、 '列のプロパティ'にID制約を追加できます。

2
vamsi_874

偶然にVisual Studio 2017+を使用している場合

  1. サーバーオブジェクトエクスプローラで、テーブルを右クリックして[コードの表示]を選択します。
  2. 列に修飾子 "IDENTITY"を追加してください。
  3. 更新

これですべてが完了します。

1
jdisla

元の投稿者が実際に既存の列をテーブルのPRIMARY KEYに設定し、実際にその列をIDENTITY列にする必要がなかった場合(2つの異なる点)、これはt-SQLを使用して実行できます。

ALTER TABLE [YourTableName]
ADD CONSTRAINT [ColumnToSetAsPrimaryKey] PRIMARY KEY ([ColumnToSetAsPrimaryKey])

PRIMARY KEYオプションの後の列名を囲む括弧に注意してください。

この記事は古く、私は要求者のニーズについて仮定していますが、このスレッドに遭遇したユーザーにとっては、この追加情報が役立つことがあると思いました。最初に新しい列として追加せずに主キーを入力してください。これは正しくありません。

1
A. Omalley

私の現在の状況に従って、私はこのアプローチに従います。スクリプトを介してデータを挿入した後に、プライマリテーブルにIDを付与したい。

私はアイデンティティを追加したいので、それは常に私が欲しい1からレコードカウントの終わりまで始まります。

--first drop column and add with identity
ALTER TABLE dbo.tblProductPriceList drop column ID 
ALTER TABLE dbo.tblProductPriceList add ID INT IDENTITY(1,1)

--then add primary key to that column (exist option you can ignore)
IF  NOT EXISTS (SELECT * FROM sys.key_constraints  WHERE object_id = OBJECT_ID(N'[dbo].[PK_tblProductPriceList]') AND parent_object_id = OBJECT_ID(N'[dbo].[tblProductPriceList]'))
    ALTER TABLE [tblProductPriceList] ADD PRIMARY KEY (id)
GO

これにより、IDを持つ同じ主キー列が作成されます。

私はこのリンクを使用しました: https://blog.sqlauthority.com/2014/10/11/sql-server-add-auto-incremental-identity-column-to-table-after-creating-table/

既存のテーブルに主キーを追加します

1
Ajay2707

基本的に4つの論理的なステップがあります。

  1. 新しい[ID]列を作成します。この新しい列に対してIDの挿入をオンにします。

  2. この新しい列に、ソース列(Identityに変換したい列)のデータを挿入します。

  3. 新しい列のIDの挿入をオフにします。

  4. ソース列をドロップして、新しい列の名前をソース列の名前に変更します。

複数のサーバーなどにまたがって作業するなど、もっと複雑なことがあるかもしれません。

手順については、次の記事を参照してください(ssms&T-sqlを使用)。これらの手順は、T-SQLをあまり理解していない初心者を対象としています。

http://social.technet.Microsoft.com/wiki/contents/articles/23816.how-to-convert-int-column-to-identity-in-the-ms-sql-server.aspx

Tsqlを使って既存のカラムをidentityカラムに変更できるとは思わない。ただし、これはEnterprise Managerデザインビューから実行できます。

あるいは、ID列として新しい行を作成し、古い列をドロップしてから、新しい列の名前を変更することもできます。

ALTER TABLE FooTable
ADD BarColumn INT IDENTITY(1, 1)
               NOT NULL
               PRIMARY KEY CLUSTERED
0

iDが設定されていない、主キー= bigintを持つすべてのテーブル用のスクリプトを生成します。これは各テーブルと共に生成されたスクリプトのリストを返します。

SET NOCOUNT ON;

declare @sql table(s varchar(max), id int identity)

DECLARE @table_name nvarchar(max),
        @table_schema nvarchar(max);

DECLARE vendor_cursor CURSOR FOR 
SELECT
  t.name, s.name
FROM sys.schemas AS s
INNER JOIN sys.tables AS t
  ON s.[schema_id] = t.[schema_id]
WHERE EXISTS (
    SELECT
    [c].[name]
    from sys.columns [c]
    join sys.types [y] on [y].system_type_id = [c].system_type_id
    where [c].[object_id] = [t].[object_id] and [y].name = 'bigint' and [c].[column_id] = 1
) and NOT EXISTS 
(
  SELECT 1 FROM sys.identity_columns
    WHERE [object_id] = t.[object_id]
) and exists (
    select 1 from sys.indexes as [i] 
    inner join sys.index_columns as [ic]  ON  i.OBJECT_ID = ic.OBJECT_ID AND i.index_id = ic.index_id
    where object_name([ic].[object_id]) = [t].[name]
)
OPEN vendor_cursor

FETCH NEXT FROM vendor_cursor 
INTO @table_name, @table_schema

WHILE @@FETCH_STATUS = 0
BEGIN

DELETE FROM @sql

declare @pkname varchar(100),
    @pkcol nvarchar(100)

SELECT  top 1
        @pkname = i.name,
        @pkcol = COL_NAME(ic.OBJECT_ID,ic.column_id)
FROM    sys.indexes AS [i]
INNER JOIN sys.index_columns AS [ic] ON  i.OBJECT_ID = ic.OBJECT_ID AND i.index_id = ic.index_id
WHERE   i.is_primary_key = 1 and OBJECT_NAME(ic.OBJECT_ID) = @table_name

declare @q nvarchar(max) = 'SELECT  '+@pkcol+' FROM ['+@table_schema+'].['+@table_name+'] ORDER BY '+@pkcol+' DESC'

DECLARE @ident_seed nvarchar(max) -- Change this to the datatype that you are after
SET @q = REPLACE(@q, 'SELECT', 'SELECT TOP 1 @output = ')
EXEC sp_executeSql @q, N'@output bigint OUTPUT', @ident_seed OUTPUT

insert into  @sql(s) values ('BEGIN TRANSACTION')
insert into  @sql(s) values ('BEGIN TRY')

-- create statement
insert into  @sql(s) values ('create table ['+@table_schema+'].[' + @table_name + '_Temp] (')

-- column list
insert into @sql(s) 
select 
    '  ['+[c].[name]+'] ' +
    y.name + 

    (case when [y].[name] like '%varchar' then
    coalesce('('+(case when ([c].[max_length] < 0 or [c].[max_length] >= 1024) then 'max' else cast([c].max_length as varchar) end)+')','')
    else '' end)

     + ' ' +
    case when [c].name = @pkcol then 'IDENTITY(' +COALESCE(@ident_seed, '1')+',1)' else '' end + ' ' +
    ( case when c.is_nullable = 0 then 'NOT ' else '' end ) + 'NULL ' + 
    coalesce('DEFAULT ('+(
        REPLACE(
            REPLACE(
                LTrim(
                    RTrim(
                        REPLACE(
                            REPLACE(
                                REPLACE(
                                    REPLACE(
                                        LTrim(
                                            RTrim(
                                                REPLACE(
                                                    REPLACE(
                                                        object_definition([c].default_object_id)
                                                    ,' ','~')
                                                ,')',' ')
                                            )
                                        )
                                    ,' ','*')
                                ,'~',' ')
                            ,' ','~')
                        ,'(',' ')
                    )
                )
            ,' ','*')
        ,'~',' ')
    ) +
    case when object_definition([c].default_object_id) like '%get%date%' then '()' else '' end
    +
    ')','') + ','
 from sys.columns c
 JOIN sys.types y ON y.system_type_id = c.system_type_id
  where OBJECT_NAME(c.[object_id]) = @table_name and [y].name != 'sysname'
 order by [c].column_id


 update @sql set s=left(s,len(s)-1) where id=@@identity

-- closing bracket
insert into @sql(s) values( ')' )

insert into @sql(s) values( 'SET IDENTITY_INSERT ['+@table_schema+'].['+@table_name+'_Temp] ON')

declare @cols nvarchar(max)
SELECT @cols = STUFF(
    (
        select ',['+c.name+']'
        from sys.columns c
        JOIN sys.types y ON y.system_type_id = c.system_type_id
        where c.[object_id] = OBJECT_ID(@table_name)
        and [y].name != 'sysname'
        and [y].name != 'timestamp'
        order by [c].column_id
        FOR XML PATH ('')
     )
    , 1, 1, '')

insert into @sql(s) values( 'IF EXISTS(SELECT * FROM ['+@table_schema+'].['+@table_name+'])')
insert into @sql(s) values( 'EXEC(''INSERT INTO ['+@table_schema+'].['+@table_name+'_Temp] ('+@cols+')')
insert into @sql(s) values( 'SELECT '+@cols+' FROM ['+@table_schema+'].['+@table_name+']'')')

insert into @sql(s) values( 'SET IDENTITY_INSERT ['+@table_schema+'].['+@table_name+'_Temp] OFF')


insert into @sql(s) values( 'DROP TABLE ['+@table_schema+'].['+@table_name+']')

insert into @sql(s) values( 'EXECUTE sp_rename N''['+@table_schema+'].['+@table_name+'_Temp]'', N'''+@table_name+''', ''OBJECT''')

if ( @pkname is not null ) begin
    insert into @sql(s) values('ALTER TABLE ['+@table_schema+'].['+@table_name+'] ADD CONSTRAINT ['+@pkname+'] PRIMARY KEY CLUSTERED (')
    insert into @sql(s)
        select '  ['+COLUMN_NAME+'] ASC,' from information_schema.key_column_usage
        where constraint_name = @pkname
        GROUP BY COLUMN_NAME, ordinal_position
        order by ordinal_position

    -- remove trailing comma
    update @sql set s=left(s,len(s)-1) where id=@@identity
    insert into @sql(s) values ('  )')
end

insert into  @sql(s) values ('--Run your Statements')
insert into  @sql(s) values ('COMMIT TRANSACTION')
insert into  @sql(s) values ('END TRY')
insert into  @sql(s) values ('BEGIN CATCH')
insert into  @sql(s) values ('        ROLLBACK TRANSACTION')
insert into  @sql(s) values ('        DECLARE @Msg NVARCHAR(MAX)  ')
insert into  @sql(s) values ('        SELECT @Msg=ERROR_MESSAGE() ')
insert into  @sql(s) values ('        RAISERROR(''Error Occured: %s'', 20, 101,@msg) WITH LOG')
insert into  @sql(s) values ('END CATCH')

declare @fqry nvarchar(max)

-- result!
SELECT @fqry = (select char(10) + s from @sql order by id FOR XML PATH (''))


SELECT @table_name as [Table_Name], @fqry as [Generated_Query]
PRINT 'Table: '+@table_name
EXEC sp_executeSql @fqry

    FETCH NEXT FROM vendor_cursor 
    INTO @table_name, @table_schema
END 
CLOSE vendor_cursor;
DEALLOCATE vendor_cursor;
0
Kyle Gibbar