Как Создать Сценарий Create Table Для Существующей Таблицы

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

Кроме того, некоторые представления системы скрывают интересные нюансы, позволяющие лучше понять, как работает система.

СУБД .

Для просмотра тела системного представления, а также любого другого объекта скрипта используйте функцию — OBJECT_DEFINITION :

  
  
  
  
  
  
  
  
   

PRINT OBJECT_DEFINITION(OBJECT_ID('sys.objects'))

Однако, OBJECT_DEFINITION , как и его аналог sp_helptext , есть существенный недостаток — с их помощью нельзя вернуть описание скрипта для табличного объекта.



IF OBJECT_ID('dbo.Table1', 'U') IS NOT NULL DROP TABLE dbo.Table1 GO CREATE TABLE dbo.Table1 (ColumnID INT PRIMARY KEY) GO EXEC sys.sp_helptext 'dbo.Table1' SELECT OBJECT_DEFINITION(OBJECT_ID('dbo.Table1', 'U'))

При выполнении sp_helptext мы получим ошибку: Сообщение 15197, уровень 16, состояние 1, процедура sp_helptext, строка 107 Для объекта dbo.Table1 нет текста.

В этих же условиях функция системы OBJECT_DEFINITION вернется НУЛЕВОЙ .

Также выборка из sys.sql_modules , поскольку внутри этого системного представления используется тот же вызов функции OBJECT_DEFINITION :

CREATE VIEW sys.sql_modules AS SELECT object_id = o.id, definition = object_definition(o.id), .

FROM sys.sysschobjs o

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

Что ж, давайте заглянем в системные представления и создадим аналог функции OBJECT_DEFINITION для работы с табличными объектами.

Для начала создадим тестовую таблицу, чтобы было понятнее процесс написания скрипта:

IF OBJECT_ID('dbo.WorkOut', 'U') IS NOT NULL DROP TABLE dbo.WorkOut GO CREATE TABLE dbo.WorkOut ( WorkOutID BIGINT IDENTITY(1,1) NOT NULL, TimeSheetDate AS DATEADD(DAY, -(DAY(DateOut) - 1), DateOut), DateOut DATETIME NOT NULL, EmployeeID INT NOT NULL, IsMainWorkPlace BIT NOT NULL DEFAULT 1, DepartmentUID UNIQUEIDENTIFIER NOT NULL, WorkShiftCD NVARCHAR(10) NULL, WorkHours REAL NULL, AbsenceCode VARCHAR(25) NULL, PaymentType CHAR(2) NULL, CONSTRAINT PK_WorkOut PRIMARY KEY CLUSTERED (WorkOutID) ) GO

И приступим к первому шагу — получению списка столбцов и их свойств: В принципе, вы можете получить список столбцов, просто обратившись к одному из нескольких системных представлений.

Важно выбирать из наиболее легких представлений системы, чтобы время выполнения запроса было минимальным.

Приведу пару примеров вместе с планами их реализации:

--#1 SELECT * FROM INFORMATION_SCHEMA.COLUMNS c WHERE c.TABLE_SCHEMA = 'dbo' AND c.TABLE_NAME = 'WorkOut'



Как создать сценарий CREATE TABLE для существующей таблицы



--#2 SELECT c.* FROM sys.columns c WITH(NOLOCK) JOIN sys.tables t WITH(NOLOCK) ON c.[object_id] = t.[object_id] JOIN sys.schemas s WITH(NOLOCK) ON t.[schema_id] = s.[schema_id] WHERE t.name = 'WorkOut' AND s.name = 'dbo'



Как создать сценарий CREATE TABLE для существующей таблицы



--#3 SELECT * FROM sys.columns c WITH(NOLOCK) WHERE OBJECT_NAME(c.[object_id]) = 'WorkOut' AND OBJECT_SCHEMA_NAME(c.[object_id]) = 'dbo'



Как создать сценарий CREATE TABLE для существующей таблицы



--#4 SELECT * FROM sys.columns c WITH(NOLOCK) WHERE c.[object_id] = OBJECT_ID('dbo.WorkOut', 'U')



Как создать сценарий CREATE TABLE для существующей таблицы

Из представленных планов выполнения видно, что варианты №1 и №2 содержат избыточное количество соединений, что увеличивает время выполнения запроса, а подход №3 приводит к полному сканированию индекса, что делает его наименее эффективным из всех.

С точки зрения производительности вариант №4 для меня остается наиболее привлекательным.

Однако данные, содержащиеся sys.columns (как и в INFORMATION_SCHEMA.COLUMNS ) недостаточно для полного описания структуры таблицы.

Это приводит к принудительному подключению к другим системным представлениям:

SELECT

Теги: #sql-сервер #sql #метаданные #t-sql #sql #Microsoft SQL Server

Вместе с данным постом часто просматривают: