Consulta T-SQL para mostrar a definição da tabela?

105

O que é uma consulta que me mostrará a definição completa, incluindo índices e chaves para uma tabela do SQL Server? Eu quero uma consulta pura - e sei que o SQL Studio pode fornecer isso para mim, mas geralmente estou em computadores "selvagens" que têm apenas os aplicativos mais básicos e não tenho direitos para instalar o Studio. Mas SQLCMD é sempre uma opção.

ATUALIZAÇÃO: Eu tentei sp_help, mas só produz um registro que mostra Nome, Proprietário, Tipo e Created_Datetime. Há algo mais que estou perdendo com sp_help?

Aqui está o que chamo de:

sp_help aeroportos

Observe que eu realmente quero o DDL que define a tabela.

Daniel Williams
fonte
1
O que está faltando sp_helpé que ele retorna vários conjuntos de resultados. Você está descrevendo as colunas retornadas pelo primeiro conjunto de resultados.
Joe Stefanelli
1
Boa pergunta. Vindo do MySQL, as soluções ficam muito curtas, pois não se pode ver colunas, índices, chaves estrangeiras, nomes de restrição, tudo em um só lugar. Isso é grave quando você tem muitos bancos de dados / tabelas em seu explorador de objetos. Espero que a Microsoft trate disso no futuro. Não usei nenhuma ferramenta de produtividade, mas SSMSBoost parece promissor.
Pedro, n
1
@Microsoft, adicione DESC TABLE como MySQL. Fácil. Simples. Feito.
Pete Alvin

Respostas:

127

Não existe uma maneira fácil de devolver o DDL. No entanto, você pode obter a maioria dos detalhes nas Visualizações do esquema de informações e nas Visualizações do sistema .

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')
Anthony Faull
fonte
1
Obrigado. Eu estava começando a suspeitar que a única maneira de conseguir isso seria consultar várias tabelas separadas, e que é o que o SQL Studio faz quando você diz para "gerar DDL". Só estou surpreso por não haver um SP geral que faça isso por você.
Daniel Williams
6
Isto é. Se você quiser apenas as informações da coluna, execute sp_columnscomo mencionei na minha resposta. Se você quiser informações sobre a execução de FKs sp_fkeys. Se você quiser saber os índices, execute sp_statistics.
69

Você já tentou sp_help?

sp_help 'TableName'
SQLMenace
fonte
1
Isso mostra a estrutura, as restrições, os tipos de restrição, etc. Apenas uma coisa a ser observada: você deve escrever o nome completo da tabela de dados. Schema.TableName. Caso contrário, resolve completamente o problema e dá todas as informações sobre a mesa.
FrenkyB,
1
Não retorna o DDL da tabela, mesmo com o caminho completo escrito.
CoveGeek
25

Visite http://www.stormrage.com/SQLStuff/sp_GetDDL_Latest.txt .

Você encontrará o código de sp_getddlprocedimento do SQL Server. O objetivo do procedimento é criar um script de qualquer tabela, tabela temporária ou objeto.

USO:

exec sp_GetDDL GMACT

ou

exec sp_GetDDL 'bob.example'

ou

exec sp_GetDDL '[schemaname].[tablename]'

ou

exec sp_GetDDL #temp

Eu testei no SQL Server 2012 e ele faz um excelente trabalho.

Não sou o autor do procedimento. Qualquer melhoria que você fizer envie para Lowell Izaguirre ([email protected]).

Dexter Vaca
fonte
Obrigado por este script e compartilhamento! Eu perguntaria, você tem um post onde possamos discutir sobre este script?
Bellash,
Excelente! A MSFT deve ter essa função dentro do Management Studio
Tertium
19

A maneira mais fácil e rápida que posso imaginar seria usar sp_help

sp_help 'TableName'

codingbadger
fonte
18

Use este pequeno aplicativo de linha de comando do Windows que obtém o CREATE TABLEscript (com restrições) para qualquer tabela. Eu escrevi em C #. Basta compilá-lo e carregá-lo em um cartão de memória. Talvez alguém possa transferi-lo para o 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);
        }
    }
}
Anthony Faull
fonte
2
No entanto, isso não é T-SQL
ivan_pozdeev
Eu me pergunto o que você veria se usasse o SQL Profiler para capturar os comandos que isso iniciou. : ->
Paul Smith
Só queria acrescentar que isso não fará script de nenhuma tabela CDC :( já que atualmente não é compatível com SMO.
H. Abraham Chavez
Adicionei uma resposta com uma porta PowerShell. Espero que isso ajude alguém.
R. Horber
11

sp_help 'YourTableName'
Joe Stefanelli
fonte
6

Isso retornará colunas, tipos de dados e índices definidos na tabela:

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

--Table Definition
sp_help TableName

Isso retornará os gatilhos definidos na tabela:

--Triggers in SQL Table
select * from sys.triggers where parent_id = object_id(N'SQLTableName') 
Siva
fonte
6

Desde o SQL 2012, você pode executar a seguinte instrução:

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

Se você inserir uma instrução select complexa (junções, subseleções, etc), ela fornecerá a definição do conjunto de resultados. Isso é muito útil se você precisar criar uma nova tabela (ou tabela temporária) e não quiser verificar cada definição de campo manualmente.

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

Dan Stef
fonte
4

Basta digitar o nome da tabela e selecioná-lo e pressionar ATL + F1

Digamos que o nome da sua tabela Customerabra uma nova janela de consulta , digite e selecione o nome da tabela e pressione ALT + F1

Ele irá mostrar a definição completa de mesa.

Ali Adravi
fonte
Boa)) Mas para mim, mostra dados para todo o banco de dados. Tentei novas janelas de consulta apenas com o nome da tabela e não funcionou - sempre mostra tudo. Caso contrário, boa dica :)
FrenkyB
Eu usei com 2008 e 2012, não tenho certeza sobre as versões anteriores, e sempre funciona para mim, apenas o nome da tabela e ALT + F1, se quiser usar o esquema então 'schema.table'.
Ali Adravi,
É o atalho de sp_help 'schema.tablename'
Ali Adravi,
2
Funcionou quando selecionei \ destaquei o nome da tabela. Mostra o banco de dados inteiro, se houver algo mais na janela de consulta.
DB Tech
3

Uma variação da resposta de @Anthony Faull para quem usa o LINQPad:

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

Você precisará fazer referência a 2 assemblies:

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

E adicione referências de namespace conforme mencionado no snippet de Anthony.

Taras Strypko
fonte
3

Eu sei que é uma pergunta antiga, mas exatamente o que eu estava procurando. Como quero criar scripts em lote para algumas tabelas, reescrevi o código C # de Anthony Faull para PowerShell.

Este usa Segurança Integrada:

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"}

E aqui com nome de usuário e senha:

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"}
R. Horber
fonte
2

Experimente o procedimento armazenado sp_help.

sp_help <>

dotnetster
fonte
2

Como complemento à resposta de Barry. O sp_help também pode ser usado sozinho para iterar todos os objetos em um banco de dados específico. Você também tem sp_helptext para seu arsenal, que cria scripts de elementos programáticos, como procedimentos armazenados.

Gregory A Beamer
fonte
2

Outra maneira é executar o procedimento sp_columns .

EXEC sys.sp_columns @TABLE_NAME = 'YourTableName'

fonte
0
SELECT ORDINAL_POSITION, COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH
       , IS_NULLABLE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'EMPLOYEES'
Mahmoud Saleh
fonte
-5

"Observe que eu realmente quero o DDL que define a tabela."

use pg_dump:

pg_dump -s -t tablename dbname

Ele fornece a definição de tabela ( -sé apenas o esquema, sem dados) de uma determinada tabela ( -ttablename) no banco de dados "dbname"em SQL simples. Além disso, você obterá informações de sequência, chave primária e restrição. A saída que você pode - talvez após verificar e editar de acordo com suas necessidades - ser alimentada novamente no banco de dados Postgres (o mesmo ou outro):

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

Isso é para UNIX / Linux, mas tenho certeza de que também existe um pg_dump para Windows.

Norbert Poellmann
fonte
1
Não! isso é para postgres, não para Microsoft SQL Server.
Marcos
3
Ignorando toda a plataforma e mecanismo de banco de dados especificado na pergunta. Agradável.
Jeremy