Zapytanie T-SQL, aby wyświetlić definicję tabeli?

105

Jakie zapytanie pokaże mi pełną definicję, w tym indeksy i klucze dla tabeli SQL Server? Chcę czystego zapytania - i wiem, że SQL Studio może mi to dać, ale często pracuję na „dzikich” komputerach, które mają tylko najbardziej podstawowe aplikacje i nie mam uprawnień do instalowania studia. Ale SQLCMD jest zawsze opcją.

AKTUALIZACJA: Próbowałem sp_help, ale daje tylko jeden rekord, który pokazuje nazwę, właściciela, typ i utworzony_datime. Czy jest coś, czego mi brakuje w sp_help?

Oto, co nazywam:

sp_help lotniska

Zauważ, że naprawdę chcę DDL, który definiuje tabelę.

Daniel Williams
źródło
1
Brakuje Ci sp_helptego, że zwraca wiele zestawów wyników. Opisujesz kolumny zwrócone przez pierwszy zestaw wyników.
Joe Stefanelli
1
Dobre pytanie. Pochodzące z MySQL rozwiązania są zbyt krótkie, ponieważ nie widać kolumn, indeksów, kluczy obcych, nazw ograniczeń w jednym miejscu. Jest to poważne, gdy w eksploratorze obiektów znajduje się wiele baz danych / tabel. Mam nadzieję, że firma Microsoft zajmie się tym w przyszłości. Nie korzystałem z żadnych narzędzi zwiększających produktywność, ale SSMSBoost wygląda obiecująco.
Piotr n
1
@Microsoft proszę dodać DESC TABLE, np. MySQL. Łatwo. Prosty. Gotowe.
Pete Alvin

Odpowiedzi:

127

Nie ma łatwego sposobu na zwrócenie DDL. Jednak większość szczegółów można uzyskać z widoków schematu informacji i widoków systemu .

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
źródło
1
Dziękuję Ci. Zacząłem podejrzewać, że jedynym sposobem na uzyskanie tego byłoby wysłanie zapytań do kilku oddzielnych tabel i że to właśnie robi SQL Studio, gdy powiesz mu „generowanie DDL”. Jestem tylko zaskoczony, że nie ma ogólnego SP, który zrobi to za Ciebie.
Daniel Williams
6
To jest. Jeśli chcesz tylko informacje o kolumnie, możesz wykonać, sp_columnsjak wspomniałem w mojej odpowiedzi. Jeśli chcesz uzyskać informacje o biegu FK sp_fkeys. Jeśli chcesz poznać indeksy, wykonaj sp_statistics.
69

Czy próbowałeś sp_help?

sp_help 'TableName'
SQLMenace
źródło
1
Pokazuje strukturę, ograniczenia, typy ograniczeń itp. Należy tylko zwrócić uwagę: musisz wpisać pełną nazwę bazy danych. Schema.TableName. W przeciwnym razie całkowicie rozwiązuje problem i podaje wszystkie informacje o stole.
FrenkyB
1
Nie zwraca DDL tabeli, nawet po zapisaniu pełnej ścieżki.
CoveGeek
25

Odwiedź http://www.stormrage.com/SQLStuff/sp_GetDDL_Latest.txt .

Znajdziesz kod sp_getddlprocedury dla SQL Server. Celem procedury jest skrypt dowolnej tabeli, tabeli tymczasowej lub obiektu.

STOSOWANIE:

exec sp_GetDDL GMACT

lub

exec sp_GetDDL 'bob.example'

lub

exec sp_GetDDL '[schemaname].[tablename]'

lub

exec sp_GetDDL #temp

Przetestowałem go na SQL Server 2012 i wykonuje świetną robotę.

Nie jestem autorem procedury. Wszelkie ulepszenia, które wprowadzisz, wyślij do Lowell Izaguirre ([email protected]).

Dexter Vaca
źródło
Dziękuję za ten skrypt i udostępnienie! Chciałbym zapytać, czy masz post, w którym możemy omówić ten skrypt?
Bellash
Doskonały! MSFT musi mieć taką funkcję w Management Studio
Tertium
19

Najłatwiejszym i najszybszym sposobem, jaki przychodzi mi do głowy, byłoby użycie sp_help

sp_help 'TableName'

codingbadger
źródło
18

Użyj tej małej aplikacji wiersza poleceń systemu Windows, która pobiera CREATE TABLEskrypt (z ograniczeniami) dla dowolnej tabeli. Napisałem to w C #. Po prostu skompiluj go i przenieś na kartę pamięci. Być może ktoś może przenieść to na 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
źródło
2
To nie jest jednak T-SQL
ivan_pozdeev
Zastanawiam się, co byś zobaczył, gdybyś użył SQL Profiler do przechwycenia poleceń, które się zaczęły. : ->
Paul Smith
Chciałem tylko dodać, że to nie spowoduje skryptu żadnych tabel CDC :( ponieważ obecnie nie jest obsługiwane w SMO.
H. Abraham Chavez
Dodałem odpowiedź z portem PowerShell. Mam nadzieję, że to komuś pomoże.
R. Horber
11

sp_help 'YourTableName'
Joe Stefanelli
źródło
6

To zwróci kolumny, typy danych i indeksy zdefiniowane w tabeli:

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

--Table Definition
sp_help TableName

To zwróci wyzwalacze zdefiniowane w tabeli:

--Triggers in SQL Table
select * from sys.triggers where parent_id = object_id(N'SQLTableName') 
Siva
źródło
6

Od SQL 2012 można uruchomić następującą instrukcję:

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

Jeśli wprowadzisz złożoną instrukcję wyboru (łączenia, podselekcje itp.), Poda ona definicję zestawu wyników. Jest to bardzo przydatne, jeśli chcesz utworzyć nową tabelę (lub tabelę tymczasową) i nie chcesz ręcznie sprawdzać każdej definicji pola.

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

Dan Stef
źródło
4

Po prostu wpisz nazwę tabeli, wybierz ją i naciśnij ATL + F1

Powiedz, że nazwa twojej tabeli jest, Customera następnie otwórz nowe okno zapytania , wpisz i wybierz nazwę tabeli i naciśnij ALT + F1

Pokaże pełną definicję tabeli.

Ali Adravi
źródło
Dobry)) Ale dla mnie pokazuje dane dla całej bazy danych. Próbowałem nowych okien zapytań zawierających tylko nazwę tabeli i nie działa - zawsze pokazuje wszystko. W przeciwnym razie miła wskazówka :)
FrenkyB
Użyłem go z 2008 i 2012, nie jestem pewien co do starszych wersji i zawsze działa dla mnie, tylko nazwa tabeli i ALT + F1, jeśli chcesz użyć schematu, to „schema.table”.
Ali Adravi
To jest skrót do sp_help 'schema.tablename'
Ali Adravi
2
Działało, gdy wybrałem \ podświetliłem nazwę tabeli. Pokazano całą bazę danych, jeśli w oknie zapytania było coś jeszcze.
DB Tech,
3

Odmiana odpowiedzi @Anthony Faull dla osób korzystających z LINQPad:

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

Będziesz musiał odwołać się do 2 zestawów:

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

I dodaj odwołania do przestrzeni nazw, jak wspomniano we fragmencie Anthony'ego.

Taras Strypko
źródło
3

Wiem, że to stare pytanie, ale dokładnie to, czego szukałem. Ponieważ chcę wsadowo skryptować niektóre tabele, przepisałem kod C # od Anthony'ego Faulla dla PowerShell.

Ten wykorzystuje zintegrowane zabezpieczenia:

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

A tutaj z nazwą użytkownika i hasłem:

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
źródło
2

Wypróbuj procedurę składowaną sp_help.

sp_help <>

dotnetster
źródło
2

Jako dodatek do odpowiedzi Barry'ego. Sp_help może być również używany samodzielnie do iteracji wszystkich obiektów w określonej bazie danych. Masz również sp_helptext dla swojego arsenału, który tworzy skrypty elementów programistycznych, takich jak procedury składowane.

Gregory A Beamer
źródło
2

Innym sposobem jest wykonanie procedury sp_columns .

EXEC sys.sp_columns @TABLE_NAME = 'YourTableName'

źródło
0
SELECT ORDINAL_POSITION, COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH
       , IS_NULLABLE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'EMPLOYEES'
Mahmoud Saleh
źródło
-5

„Zauważ, że naprawdę chcę DDL, który definiuje tabelę”.

użyj pg_dump:

pg_dump -s -t tablename dbname

Daje ci definicję tabeli ( -sjest tylko schematem, brak danych) określonej tabeli (nazwa tabeli -t) w bazie danych "dbname"w zwykłym języku SQL. Dodatkowo otrzymasz sekwencję, klucz podstawowy i informacje o ograniczeniach. Wynik, który możesz - po sprawdzeniu i edycji zgodnie z własnymi potrzebami - zostać ponownie wprowadzony do (tej samej lub innej) bazy danych Postgres:

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

To jest dla UNIX / Linux, ale jestem pewien, że pg_dump istnieje również dla Windows.

Norbert Poellmann
źródło
1
Nie! to jest dla postgres, a nie dla Microsoft SQL Server.
Mark
3
Zignorowanie całej platformy i silnika bazy danych określonego w pytaniu. Miły.
Jeremy