Добавление идентификатора в существующий столбец

Мне нужно изменить первичный ключ таблицы на столбец идентификаторов, и в таблице уже есть несколько строк.

У меня есть script, чтобы очистить идентификаторы, чтобы убедиться, что они последовательны, начиная с 1, отлично работает в моей тестовой базе данных.

Что команда SQL для изменения столбца, чтобы иметь свойство идентификации?

Ответ 1

Вы не можете изменить существующие столбцы для идентификации.

У вас есть 2 варианта,

  • Создайте новую таблицу с идентификатором и отпустите существующую таблицу

  • Создайте новый столбец с идентификатором и отпустите существующий столбец

Подход 1. (Новая таблица) Здесь вы можете сохранить существующие значения данных во вновь созданном столбце идентификации.

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 (Новый столбец). Вы не можете сохранить существующие значения данных во вновь созданном столбце идентификации. Столбец идентификации будет содержать последовательность чисел.

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)

Ответ 2

В SQL 2005 и выше существует способ решить эту проблему без изменения страниц данных таблицы. Это важно для больших таблиц, где прикосновение к каждой странице данных может занять минуты или часы. Эта хитрость также работает, даже если столбец идентификаторов является первичным ключом, является частью кластерного или некластеризованного индекса или других ошибок, которые могут привести к путанице в более простом решении "добавить/удалить/переименовать столбец".

Здесь хитрость: вы можете использовать SQL Server инструкцию ALTER TABLE... SWITCH, чтобы изменить схему таблицы без изменения данных, то есть вы можете заменить таблицу на IDENTITY на идентичная схема таблицы, но без столбца IDENTITY. Тот же трюк работает для добавления IDENTITY в существующий столбец.

Обычно ALTER TABLE... SWITCH используется для эффективной замены полного раздела в многораздельной таблице новым пустым разделом. Но его также можно использовать и в однораздельных таблицах.

Я использовал этот трюк для преобразования менее чем за 5 секунд столбца таблицы из 2,5 миллиардов строк из IDENTITY в не-IDENTITY (для того, чтобы выполнить многочасовой запрос, план запроса которого работал лучше для не-IDENTITY столбцы), а затем восстановил настройку IDENTITY, снова менее чем за 5 секунд.

Вот пример кода того, как это работает.

 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 name
 EXEC sp_rename 'Test2','Test';

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

 -- see same records
 SELECT * FROM Test; 

Это, очевидно, более сложная задача, чем решения в других ответах, но если ваша таблица большая, это может реально спасти жизнь. Есть несколько предостережений:

  • Насколько я знаю, идентичность - это единственное, что вы можете изменить в столбцах таблицы с помощью этого метода. Добавление/удаление столбцов, изменение обнуляемости и т.д. Запрещено.
  • Вам нужно будет сбросить чужие ключи, прежде чем переключаться, и восстановить их после.
  • То же самое для функций WITH SCHEMABINDING, представлений и т.д.
  • новые табличные индексы должны точно совпадать (те же столбцы, тот же порядок и т.д.)
  • Старые и новые таблицы должны быть в одной файловой группе.
  • Работает только на SQL Server 2005 или более поздней версии
  • Ранее я считал, что этот прием работает только в редакциях SQL Server для предприятий или разработчиков (поскольку разделы поддерживаются только в версиях Enterprise и для разработчиков), но Мейсон Дж. Жвити в своем комментарии ниже говорит, что он также работает и в SQL Standard Edition. Я предполагаю, что это означает, что ограничение на Enterprise или Developer не распространяется на ALTER TABLE... SWITCH.

В TechNet есть хорошая статья, в которой подробно описаны приведенные выше требования.

ОБНОВЛЕНИЕ - Эрик Ву оставил комментарий, который добавляет важную информацию об этом решении. Скопируйте его сюда, чтобы убедиться, что он привлекает больше внимания:

Здесь есть еще одна оговорка, о которой стоит упомянуть. Хотя новая таблица с радостью получит данные из старой таблицы, а все новые строки будут вставлены в соответствии с шаблоном идентификации, они будут начинаться с 1 и потенциально прерываться, если указанный столбец является первичным ключом. Попробуйте запустить DBCC CHECKIDENT('<newTableName>') сразу после переключение. См. msdn.microsoft.com/en-us/library/ms176057.aspx для получения дополнительной информации. Информация.

Если таблица активно расширяется новыми строками (то есть у вас не так много простоев между добавлением IDENTITY и добавлением новых строк, тогда вместо DBCC CHECKIDENT вы захотите вручную установить начальное значение идентификатора в новой таблице схема должна быть больше самого большого существующего идентификатора в таблице, например, IDENTITY (2435457, 1). Возможно, вы сможете включить в транзакцию ALTER TABLE...SWITCH и DBCC CHECKIDENT (или not-- не проверял это), но кажется, например, установка начального значения вручную будет проще и безопаснее.

Очевидно, что если в таблицу не добавляются новые строки (или они добавляются только изредка, например, ежедневный процесс ETL), то этого условия гонки не будет, поэтому DBCC CHECKIDENT будет в порядке.

Ответ 3

Вы не можете изменить столбец как столбец IDENTITY. Что вам нужно сделать, так это создать новый столбец, который определяется как идентификатор из get-go, затем удалить старый столбец и переименовать новый в старое имя.

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

ALTER TABLE (yourTable) DROP COLUMN OldColumnName

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

Марк

Ответ 4

Существует крутое решение, описанное здесь: SQL SERVER - добавление или удаление свойства идентификатора в столбце

Вкратце отредактируйте вручную таблицу в SQL Manager, переключите идентификатор, НЕ СОХРАНИТЕ изменения, просто покажите script, который будет создан для изменений, скопируйте и используйте его позже.

Это огромная экономия времени, потому что она (script) содержит все внешние ключи, индексы и т.д., связанные с таблицей, которую вы меняете. Напиши это вручную... Не дай бог.

Ответ 5

Простое объяснение

Переименуйте существующий столбец, используя sp_RENAME

EXEC sp_RENAME 'Table_Name.Existing_ColumnName', 'New_ColumnName', 'COLUMN'

Пример для переименования:

Существующий столбец UserID переименован в OldUserID

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

Затем добавьте новый столбец, используя альтернативный запрос для установки в качестве первичного ключа и значения идентификатора

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

Теперь мы добавили ключевой ключ и идентификатор в существующий столбец таблицы.

Ответ 6

Попробуйте использовать ПОСЛЕДОВАТЕЛЬНОСТЬ вместо ИДЕНТИЧНОСТИ.

В 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

Отсюда: Последовательность в качестве значения по умолчанию для столбца

Ответ 7

Я разработчик java, который оказался в команде без администратора баз данных, и где я как разработчик, я не могу получить права DBA. Мне было поручено переместить целую схему между двумя базами данных, поэтому без администратора базы данных мне пришлось это сделать и сделать это, запустив скрипты, не имея возможности использовать графический интерфейс в SQL Server 2008, потому что у меня не было прав администратора.

Однако все было перемещено без проблем, однако при запуске хранимой процедуры на новой schema.table я обнаружил, что потерял поле идентификации в таблице. Я дважды проверил скрипт, который создал таблицу, и он был там, однако SQL Server не получил его, когда я запускал скрипт. Позднее я сказал администратору базы данных, что раньше он видел эту проблему.

В любом случае, для SQL Server 2008, это шаги, которые я предпринял, чтобы решить эту проблему, и они работали, поэтому я размещаю это здесь, надеясь, что это поможет кому-то. Это то, что я сделал, поскольку у меня были зависимости FK от другой таблицы, что усложнило это:

Я использовал этот запрос для проверки того, что идентификация действительно отсутствует и для просмотра зависимостей от таблицы.

1.) Найти статистику по таблице:

exec sp_help 'dbo.table_name_old';

2.) Создайте дубликат, идентичную новую таблицу, за исключением добавления поля идентификации в поле PK, где оно было раньше.

3.) Отключите личность для перемещения данных.

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.) Восстановите идентификатор.

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.) Следующие шаги основаны на сценариях, созданных в SQL Server 2008 на шаге 9.

--Add ПК в новую таблицу.

--Add FK в новую таблицу.

--Add FK обратно в таблицу зависимостей.

14.) Убедитесь, что все правильно и полно. Я использовал графический интерфейс для просмотра таблиц.

15.) Переименуйте новую таблицу в имя исходных таблиц.

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

Наконец, все сработало!

Ответ 8

Как я понял в обычных случаях, мы создаем таблицу с ключом Primary, обладающим свойством Identity
Поэтому переименовать или удалить столбец, связанный с ограничением первичного ключа, не будет возможным, поскольку правила ограничения проверяют структуру столбцов.
Чтобы достичь этого, мы должны обработать некоторые шаги следующим образом:
Предположим, что TableName = 'Employee' и ColumnName = 'EmployeeId'

1. Добавить столбец "EmployeeId_new" в таблице "Сотрудник"
ALTER TABLE Сотрудник ADD EmployeeId_new INT IDENTITY (1,1)

  1. Теперь удалите столбец "EmployeeId" из таблицы "Сотрудник"
    ALTER TABLE Сотрудник DROP COLUMN EmployeeId

  2. Это вызовет ошибку, поскольку правила ограничения первичного ключа применимы и проверяют структуру столбцов.
    * ### ' Msg 5074, уровень 16, состояние 1, строка 1 Объект [PK_dbo.Employee] зависит от colmn [EmployeeId].' ###

  3. Поэтому нам нужно сначала удалить ограничение первичного ключа из таблицы "Сотрудник", после чего мы можем удалить столбец
    ALTER TABLE Ограничение DROP сотрудника [PK_dbo.Employee]

  4. Теперь мы можем удалить столбец "EmployeeId" из таблицы "Employee", как это было на предыдущем шаге, где мы получили ошибку
    ALTER TABLE Сотрудник DROP COLUMN EmployeeId

  5. Теперь Столбец "EmployeeId" удален из таблицы Итак, мы переименуем новый добавленный столбец "EmployeeId_new" с "EmployeeId",
    sp_rename 'Employee.EmployeeId', 'EmployeeId_new', 'COLUMN'

  6. Чтобы переупорядочить таблицу в том же виде, что и было, мы должны добавить ограничение первичного ключа для столбца "EmployeeId"
    ALTER TABLE Сотрудник добавляет ограничение [PK_dbo.Employee] первичный ключ (EmployeeId)

8. Теперь таблица "Сотрудник" с "EmployeeId" изменена для правил Identity вместе с существующим ограничением первичного ключа

Ответ 9

По дизайну нет простого способа включить или отключить функцию идентификации для существующего столбца. Единственный чистый способ сделать это - создать новый столбец и сделать его столбцом идентификации или создать новую таблицу и перенести данные.

Если мы используем SQL Server Management Studio, чтобы избавиться от значения идентификатора в столбце "id", создается новая временная таблица, данные перемещаются во временную таблицу, старая таблица отбрасывается и новая таблица переименовывается.

Используйте Management Studio, чтобы внести изменения, а затем щелкните правой кнопкой мыши в дизайнере и выберите "Сгенерировать изменение Script".

Вы увидите, что это то, что делает SQL-сервер в фоновом режиме.

Ответ 10

вы не можете этого сделать, вам нужно добавить другой столбец, удалить исходный столбец и переименовать новый столбец или создать новую таблицу, скопировать данные и удалить старую таблицу, а затем переименовать новую таблицу к старой таблице

если вы используете SSMS и установите для свойства identity значение ON в конструкторе, это то, что SQL Server делает за кулисами. Поэтому, если у вас есть таблица с именем [user], это происходит, если вы делаете идентификатор пользователя и идентификатор

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

Сказав, что есть способ взломать системную таблицу, чтобы выполнить ее, установив побитовое значение, но это не поддерживается, и я бы этого не сделал.

Ответ 11

Принимаемый ответ неверен: вы можете изменить существующий столбец как личность , пока не содержит никаких нулевых значений. После изменения семя идентичности начнется с max (column) + 1.

Итак, что вам действительно нужно сделать в первую очередь, это указать значения для всех нулей.

Ответ 12

Нет, к сожалению, нет; свойство IDENTITY принадлежит таблице, а не столбцу.

Более простой способ - это сделать это в графическом интерфейсе, но если это не вариант, вы можете пройти длинный путь копирования данных, сбросить столбец, повторно добавить его с идентификатором и поместить данные назад.

См. здесь для пошаговой учетной записи.

Ответ 13

Щелкните правой кнопкой мыши на имени таблицы в Обозревателе объектов. Вы получите некоторые варианты. Нажмите "Дизайн". Для этой таблицы будет открыта новая вкладка. Вы можете добавить ограничение Identity здесь в "Свойства столбца".

Ответ 14

Чтобы изменить свойства идентификации для столбца:

  • В проводнике сервера щелкните правой кнопкой мыши таблицу с параметрами идентификации, которые вы хотите изменить, и нажмите "Открыть таблицу определения". Таблица открывается в Table Designer.
  • Снимите флажок Разрешить nulls для столбца, который вы хотите изменить.
  • На вкладке "Свойства столбца" разверните свойство "Спецификация удостоверений".
  • Щелкните ячейку сетки для дочернего объекта Is Identity и выберите "Да" в раскрывающемся списке.
  • Введите значение в ячейке Identity Seed. Это значение будет присвоено первой строке в таблице. Значение 1 будет присвоено по умолчанию.

Что это, и это сработало для меня

Ответ 15

Если вы используете Visual Studio 2017+

  1. В обозревателе объектов сервера щелкните правой кнопкой мыши таблицу и выберите "просмотреть код"
  2. Добавьте модификатор "IDENTITY" в свой столбец
  3. Обновление

Это сделает все для вас.

Ответ 16

Если исходный плакат действительно хотел установить существующий столбец как PRIMARY KEY для таблицы и фактически не нуждался в столбце, который должен быть столбцом IDENTITY (две разные вещи), то это можно сделать через t -SQL с:

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

Обратите внимание на скобки вокруг имени столбца после параметра PRIMARY KEY.

Несмотря на то, что этот пост является старым, и я делаю предположение о необходимости запросов, я чувствовал, что эта дополнительная информация может быть полезна для пользователей, сталкивающихся с этим потоком, поскольку я считаю, что разговор может заставить человека поверить, что существующий столбец не может быть установлен чтобы быть первичным ключом, не добавляя его как новый столбец, который был бы неправильным.

Ответ 18

В соответствии с моим текущим состоянием я придерживаюсь такого подхода. Я хочу дать идентификатор первичной таблице после ввода данных через script.

Как я хочу добавить идентификатор, поэтому он всегда начинается с 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

Это создаст тот же самый столбец первичного ключа с идентификатором

Я использовал эти ссылки: https://blog.sqlauthority.com/2014/10/11/sql-server-add-auto-incremental-identity-column-to-table-after-creating-table/

Добавить первичный ключ в существующую таблицу

Ответ 19

Я не верю, что вы можете изменить существующий столбец как столбец идентификаторов, используя tsql. Тем не менее, вы можете сделать это с помощью проектного представления Enterprise Manager.

В качестве альтернативы вы можете создать новую строку в качестве столбца идентификации, удалить старый столбец, а затем переименовать новый столбец.

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

Ответ 20

В принципе существует четыре логических шага.

  • Создайте новый столбец Identity. Включите Insert Identity для этого нового столбца.

  • Вставьте данные из исходного столбца (столбца, который вы хотите преобразовать в Identity) в этот новый столбец.

  • Отключите идентификатор Insert для нового столбца.

  • Оставьте исходный столбец и переименуйте новый столбец в имя столбца источника.

Может возникнуть несколько сложностей, например, работа с несколькими серверами и т.д.

Пожалуйста, обратитесь к следующей статье для шагов (используя 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

Ответ 21

генерирует script для всех таблиц с первичным ключом = 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  '[email protected]+' FROM ['[email protected]_schema+'].['[email protected]_name+'] ORDER BY '[email protected]+' 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 ['[email protected]_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 [email protected]@identity

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

insert into @sql(s) values( 'SET IDENTITY_INSERT ['[email protected]_schema+'].['[email protected]_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 ['[email protected]_schema+'].['[email protected]_name+'])')
insert into @sql(s) values( 'EXEC(''INSERT INTO ['[email protected]_schema+'].['[email protected]_name+'_Temp] ('[email protected]+')')
insert into @sql(s) values( 'SELECT '[email protected]+' FROM ['[email protected]_schema+'].['[email protected]_name+']'')')

insert into @sql(s) values( 'SET IDENTITY_INSERT ['[email protected]_schema+'].['[email protected]_name+'_Temp] OFF')


insert into @sql(s) values( 'DROP TABLE ['[email protected]_schema+'].['[email protected]_name+']')

insert into @sql(s) values( 'EXECUTE sp_rename N''['[email protected]_schema+'].['[email protected]_name+'_Temp]'', N'''[email protected]_name+''', ''OBJECT''')

if ( @pkname is not null ) begin
    insert into @sql(s) values('ALTER TABLE ['[email protected]_schema+'].['[email protected]_name+'] ADD CONSTRAINT ['[email protected]+'] 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 [email protected]@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: '[email protected]_name
EXEC sp_executeSql @fqry

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