Запрос T-SQL для отображения определения таблицы?

105

Какой запрос покажет мне полное определение, включая индексы и ключи для таблицы SQL Server? Мне нужен чистый запрос - и я знаю, что SQL Studio может дать мне это, но я часто нахожусь на «диких» компьютерах, на которых установлены только самые простые приложения, и у меня нет прав на установку Studio. Но SQLCMD - это всегда вариант.

ОБНОВЛЕНИЕ: я пробовал sp_help, но он просто дает одну запись, которая показывает имя, владельца, тип и Created_Datetime. Что-то еще мне не хватает в sp_help?

Вот что я называю:

sp_help аэропорты

Обратите внимание, что мне действительно нужен DDL, определяющий таблицу.

Дэниел Уильямс
источник
1
Вам не хватает того, sp_helpчто он возвращает несколько наборов результатов. Вы описываете столбцы, возвращаемые первым набором результатов.
Джо Стефанелли
1
Хороший вопрос. Исходя из MySQL, решения слишком короткие, так как нельзя увидеть столбцы, индексы, внешние ключи, имена ограничений в одном месте. Это серьезно, когда у вас много баз данных / таблиц в проводнике объектов. Надеюсь, что Microsoft решит эту проблему в будущем. Я не использовал никаких инструментов для повышения производительности, но SSMSBoost выглядит многообещающим.
питер н
1
@Microsoft добавьте DESC TABLE, как MySQL. Легко. Просто. Готово.
Пит Элвин

Ответы:

127

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

SELECT ORDINAL_POSITION, COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH
       , IS_NULLABLE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Customers'

SELECT CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.CONSTRAINT_TABLE_USAGE
WHERE TABLE_NAME = 'Customers'

SELECT name, type_desc, is_unique, is_primary_key
FROM sys.indexes
WHERE [object_id] = OBJECT_ID('dbo.Customers')
Энтони Фолл
источник
1
Спасибо. Я начал подозревать, что единственный способ получить это - это запросить несколько отдельных таблиц, и что это то, что делает SQL Studio, когда вы говорите ей «сгенерировать DDL». Я удивлен, что нет общего SP, который сделает это за вас.
Дэниел Уильямс
6
Это. Если вам нужна только информация о столбце, вы можете выполнить, sp_columnsкак я упоминал в своем ответе. Если вам нужна информация о FK, запустите sp_fkeys. Если вы хотите узнать индексы, выполните sp_statistics.
69

Вы пробовали sp_help?

sp_help 'TableName'
SQLMenace
источник
1
Здесь показана структура, ограничения, типы ограничений и т. Д. Только одно замечание: вы должны написать полное имя таблицы данных. Schema.TableName. В противном случае он полностью решает проблему и дает всю информацию о таблице.
FrenkyB 09
1
Не возвращает DDL таблицы, даже если записан полный путь.
CoveGeek
25

Посетите http://www.stormrage.com/SQLStuff/sp_GetDDL_Latest.txt .

Вы найдете код sp_getddlпроцедуры для SQL Server. Цель процедуры - создать сценарий для любой таблицы, временной таблицы или объекта.

ИСПОЛЬЗОВАНИЕ:

exec sp_GetDDL GMACT

или

exec sp_GetDDL 'bob.example'

или

exec sp_GetDDL '[schemaname].[tablename]'

или

exec sp_GetDDL #temp

Я тестировал его на SQL Server 2012, и он отлично справляется.

Я не автор процедуры. Любые улучшения, которые вы вносите в него, отправляйте Лоуэллу Изагирре (scripts@stormrage.com).

Декстер Вака
источник
Спасибо за этот сценарий и за то, что поделился! Я бы спросил, есть ли у вас пост, где мы можем обсудить этот сценарий?
Bellash
Превосходно! У MSFT должна быть такая функция внутри Management Studio
Tertium
19

Самый простой и быстрый способ, который я могу придумать, - это использовать sp_help

sp_help 'TableName'

кодирование
источник
18

Используйте это небольшое приложение командной строки Windows, которое получает CREATE TABLEсценарий (с ограничениями) для любой таблицы. Я написал это на C #. Просто скомпилируйте его и перенесите на карту памяти. Возможно, кто-нибудь сможет перенести его на Powershell.

using System;
using System.Linq;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
namespace ViewSource
{
    public class ViewSource
    {
        public static void Main(string[] args)
        {
            if (args.Length != 6)
            {
                Console.Error.WriteLine("Syntax: ViewSource.exe <server>" +
                     " <user> <password> <database> <schema> <table>");
            }

            Script(args[0], args[1], args[2], args[3], args[4], args[5]);
        }
        private static void Script(string server, string user,
            string password, string database, string schema, string table)
        {
            new Server(new ServerConnection(server, user, password))
                .Databases[database]
                .Tables[table, schema]
                .Script(new ScriptingOptions { SchemaQualify = true,
                                               DriAll = true })
                .Cast<string>()
                .Select(s => s + "\n" + "GO")
                .ToList()
                .ForEach(Console.WriteLine);
        }
    }
}
Энтони Фолл
источник
2
Но это не T-SQL
ivan_pozdeev
Интересно, что бы вы увидели, если бы использовали SQL Profiler для захвата запущенных команд. : ->
Пол Смит
Просто хотел добавить, что при этом не будут написаны никакие таблицы CDC :( поскольку в настоящее время это не поддерживается в SMO.
Х. Абрахам Чавес,
Я добавил ответ с портом PowerShell. Надеюсь, это кому-то поможет.
Р. Хорбер
6

Это вернет столбцы, типы данных и индексы, определенные в таблице:

--List all tables in DB
select * from sysobjects where xtype = 'U'

--Table Definition
sp_help TableName

Это вернет триггеры, определенные в таблице:

--Triggers in SQL Table
select * from sys.triggers where parent_id = object_id(N'SQLTableName') 
Шива
источник
6

Начиная с SQL 2012 вы можете запускать следующий оператор:

Exec sp_describe_first_result_set @tsql= N'Select * from <yourtable>'

Если вы введете сложный оператор выбора (объединения, подзапросы и т. Д.), Он даст вам определение набора результатов. Это очень удобно, если вам нужно создать новую таблицу (или временную таблицу), и вы не хотите проверять каждое определение поля вручную.

https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-describe-first-result-set-transact-sql

Дэн Стеф
источник
4

Просто введите имя таблицы, выберите его и нажмите ATL + F1.

Скажите, что имя вашей таблицы Customerзатем открывает новое окно запроса , введите и выберите имя таблицы и нажмите ALT + F1.

Он покажет полное определение таблицы.

Али Адрави
источник
Хорошая)) Но по мне показывает данные для всей базы. Я пробовал новые окна запросов с одним названием таблицы в нем, и это не работает - всегда показывает все. В противном случае, хороший совет :)
FrenkyB 09
Я использовал его в 2008 и 2012 годах, не уверен в более старых версиях, и он всегда работает для меня, просто имя таблицы и ALT + F1, если хотите использовать схему, затем schema.table.
Али Адрави,
Это ярлык sp_help 'schema.tablename'
Али Адрави,
2
Сработало, когда я выделил \ выделил имя таблицы. Показать всю базу данных, если в окне запроса было что-то еще.
DB Tech
3

Вариант ответа @Anthony Faull для тех, кто использует LINQPad:

new Server(new ServerConnection(this.Connection.DataSource))
    .Databases[this.Connection.Database]
    .Tables["<table>", "dbo"]
    ?.Script(new ScriptingOptions {
        SchemaQualify = true,
        DriAll = true,
    })

Вам нужно будет сослаться на 2 сборки:

  • Microsoft.SqlServer.ConnectionInfo.dll
  • Microsoft.SqlServer.Smo.dll

И добавьте ссылки на пространства имен, как указано во фрагменте Anthony.

Тарас Стрипко
источник
3

Я знаю, что это старый вопрос, но именно то, что я искал. Поскольку я хочу создать пакетный сценарий для некоторых таблиц, я переписал код C # от Энтони Фаулла для PowerShell.

Здесь используется встроенная безопасность:

Import-Module sqlps

$serverInstance = "<server>"
$database = "<database>"
$table = "<table>"
$schema = "<schema>"

$options = New-Object -TypeName Microsoft.SqlServer.Management.Smo.ScriptingOptions
$options.DriAll = $true
$options.SchemaQualify = $true

$connection = New-Object -TypeName Microsoft.SqlServer.Management.Common.ServerConnection `
    -ArgumentList $serverInstance
$server = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Server `
    -ArgumentList $connection

$server.Databases.Item($database).Tables.Item($table, $schema).Script($options) `
    | ForEach-Object -Process { $_ + "`nGO"}

А вот с логином и паролем:

Import-Module sqlps

$serverInstance = "<server>"
$user = "<user>"
$password = "<pasword>"
$database = "<database>"
$table = "<table>"
$schema = "<schema>"

$options = New-Object -TypeName Microsoft.SqlServer.Management.Smo.ScriptingOptions
$options.DriAll = $true
$options.SchemaQualify = $true

$connection = New-Object -TypeName Microsoft.SqlServer.Management.Common.ServerConnection `
    -ArgumentList $serverInstance
$connection.LoginSecure = $false
$connection.Login = $user
$connection.Password = $password
$server = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Server `
    -ArgumentList $connection

$server.Databases.Item($database).Tables.Item($table, $schema).Script($options) `
    | ForEach-Object -Process { $_ + "`nGO"}
Р. Хорбер
источник
2

Попробуйте хранимую процедуру sp_help.

sp_help <>

dotnetster
источник
2

В дополнение к ответу Барри. Процедуру sp_help также можно использовать отдельно для перебора всех объектов в конкретной базе данных. У вас также есть sp_helptext для вашего арсенала, который выполняет сценарии программных элементов, таких как хранимые процедуры.

Грегори А Бимер
источник
2

Другой способ - выполнить процедуру sp_columns .

EXEC sys.sp_columns @TABLE_NAME = 'YourTableName'

источник
0
SELECT ORDINAL_POSITION, COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH
       , IS_NULLABLE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'EMPLOYEES'
Махмуд Салех
источник
-5

«Обратите внимание, что мне действительно нужен DDL, определяющий таблицу».

используйте pg_dump:

pg_dump -s -t tablename dbname

Он дает вам определение таблицы ( -sэто только схема, без данных) определенной таблицы (имя таблицы -t) в базе данных "dbname"на простом SQL. Дополнительно вы получите информацию о последовательности, первичном ключе и ограничениях. Результат, который вы можете - возможно, после проверки и редактирования в соответствии с вашими потребностями - снова загрузить в (ту же или другую) базу данных Postgres:

pg_dump -s -t tablename dbname1  > /tmp/foo.sql
psql -e dbname2 < /tmp/foo.sql

Это для UNIX / Linux, но я уверен, что pg_dump существует и для Windows.

Норберт Поельманн
источник
1
Нет! это для postgres, а не для Microsoft SQL Server.
Марк
3
Игнорирование всей платформы и движка базы данных, указанных в вопросе. Ницца.
Джереми