2008-08-22 99 views

回答

99

我修改了上面的版本以運行所有表並支持新的SQL 2005數據類型。它還保留了主鍵名稱。僅適用於SQL 2005(使用交叉應用)。


select 'create table [' + so.name + '] (' + o.list + ')' + CASE WHEN tc.Constraint_Name IS NULL THEN '' ELSE 'ALTER TABLE ' + so.Name + ' ADD CONSTRAINT ' + tc.Constraint_Name + ' PRIMARY KEY ' + ' (' + LEFT(j.List, Len(j.List)-1) + ')' END 
from sysobjects so 
cross apply 
    (SELECT 
     ' ['+column_name+'] ' + 
     data_type + case data_type 
      when 'sql_variant' then '' 
      when 'text' then '' 
      when 'ntext' then '' 
      when 'xml' then '' 
      when 'decimal' then '(' + cast(numeric_precision as varchar) + ', ' + cast(numeric_scale as varchar) + ')' 
      else coalesce('('+case when character_maximum_length = -1 then 'MAX' else cast(character_maximum_length as varchar) end +')','') end + ' ' + 
     case when exists ( 
     select id from syscolumns 
     where object_name(id)=so.name 
     and name=column_name 
     and columnproperty(id,name,'IsIdentity') = 1 
     ) then 
     'IDENTITY(' + 
     cast(ident_seed(so.name) as varchar) + ',' + 
     cast(ident_incr(so.name) as varchar) + ')' 
     else '' 
     end + ' ' + 
     (case when IS_NULLABLE = 'No' then 'NOT ' else '' end) + 'NULL ' + 
      case when information_schema.columns.COLUMN_DEFAULT IS NOT NULL THEN 'DEFAULT '+ information_schema.columns.COLUMN_DEFAULT ELSE '' END + ', ' 

    from information_schema.columns where table_name = so.name 
    order by ordinal_position 
    FOR XML PATH('')) o (list) 
left join 
    information_schema.table_constraints tc 
on tc.Table_name  = so.Name 
AND tc.Constraint_Type = 'PRIMARY KEY' 
cross apply 
    (select '[' + Column_Name + '], ' 
    FROM information_schema.key_column_usage kcu 
    WHERE kcu.Constraint_Name = tc.Constraint_Name 
    ORDER BY 
     ORDINAL_POSITION 
    FOR XML PATH('')) j (list) 
where xtype = 'U' 
AND name NOT IN ('dtproperties') 

更新:對XML數據類型

更新2的添加處理:固定例1)存在具有相同名稱但具有不同的架構的多個表的情況下,2)有多個具有PK約束的表具有相同的名稱

33

這是我想出的腳本。它處理標識列,默認值和主鍵。它不處理外鍵,索引,觸發器或任何其他聰明的東西。它適用於SQLServer 2000,2005和2008.

declare @table varchar(100) 
set @table = 'MyTable' -- set table name here 
declare @sql table(s varchar(1000), id int identity) 

-- create statement 
insert into @sql(s) values ('create table [' + @table + '] (') 

-- column list 
insert into @sql(s) 
select 
    ' ['+column_name+'] ' + 
    data_type + coalesce('('+cast(character_maximum_length as varchar)+')','') + ' ' + 
    case when exists ( 
     select id from syscolumns 
     where object_name(id)[email protected] 
     and name=column_name 
     and columnproperty(id,name,'IsIdentity') = 1 
    ) then 
     'IDENTITY(' + 
     cast(ident_seed(@table) as varchar) + ',' + 
     cast(ident_incr(@table) as varchar) + ')' 
    else '' 
    end + ' ' + 
    (case when IS_NULLABLE = 'No' then 'NOT ' else '' end) + 'NULL ' + 
    coalesce('DEFAULT '+COLUMN_DEFAULT,'') + ',' 

from INFORMATION_SCHEMA.COLUMNS where table_name = @table 
order by ordinal_position 

-- primary key 
declare @pkname varchar(100) 
select @pkname = constraint_name from INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
where table_name = @table and constraint_type='PRIMARY KEY' 

if (@pkname is not null) begin 
    insert into @sql(s) values(' PRIMARY KEY (') 
    insert into @sql(s) 
     select ' ['+COLUMN_NAME+'],' from INFORMATION_SCHEMA.KEY_COLUMN_USAGE 
     where constraint_name = @pkname 
     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 
else begin 
    -- remove trailing comma 
    update @sql set s=left(s,len(s)-1) where [email protected]@identity 
end 

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

-- result! 
select s from @sql order by id 
+0

大量的系統將不能夠因爲這個運行動態SQL 。在你的本地盒子上可能不是問題,但只是想指出。 – 2008-10-10 01:15:42

+4

什麼是動態sql?這個腳本生成sql - 它不執行它。 – Blorgbeard 2008-10-15 23:57:47

+0

很希望看到這個分解成步驟,因此可以用一系列可以用C++編寫的查詢來執行。 – 2011-04-30 08:58:41

4

因@Blorgbeard分享他的腳本而致。我一定會收藏它,以防我需要它。

是的,你可以在「右鍵」在桌子上,腳本CREATE TABLE腳本,但:(?感興趣的擴展屬性的人)

  • 該腳本將包含負載克魯夫特的
  • 如果您的架構中有超過200個表格,則需要半天時間手動編寫該表格。

有了這個腳本轉換成一個存儲過程,並用包裝腳本相結合,你將有一個很好的自動化的方式來轉儲你的表設計成源控制等

你的數據庫代碼的其餘部分(SP的,FK索引,觸發器等)無論如何都會受到源代碼控制;)

4

我注意到的一些東西 - 在INFORMATION_SCHEMA.COLUMNS視圖中,CHARACTER_MAXIMUM_LENGTH給出字段類型的大小2147483647(2^31-1),例如圖像和文字。 ntext是2^30-1(是雙字節unicode和全部)。

該大小包含在此查詢的輸出中,但它對於CREATE語句中的這些數據類型無效(它們不應具有最大大小值)。因此,除非手動更正這些結果,否則CREATE腳本將無法使用這些數據類型。

我想可以修復腳本來解決這個問題,但這超出了我的SQL功能。

-1

如果您正在使用management studio並打開查詢分析器窗口,則可以將表名稱拖動到查詢分析器窗口並... bingo!你得到表格腳本。 我還沒有在SQL2008中試過這個

8

如果您正在生成腳本的應用程序是.NET應用程序,則可能需要使用SMO(Sql管理對象)進行調查。參考SQL Team link關於如何使用SMO來編寫腳本對象。

4

- 或者你可以創建一個存儲過程...先用ID創建

USE [db] 
GO 

/****** Object: StoredProcedure [dbo].[procUtils_InsertGeneratorWithId] Script Date: 06/13/2009 22:18:11 ******/ 
SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 


create PROC [dbo].[procUtils_InsertGeneratorWithId]  
( 
@domain_user varchar(50),  
@tableName varchar(100)  
)  


as  

--Declare a cursor to retrieve column specific information for the specified table  
DECLARE cursCol CURSOR FAST_FORWARD FOR  
SELECT column_name,data_type FROM information_schema.columns WHERE table_name = @tableName  
OPEN cursCol  
DECLARE @string nvarchar(3000) --for storing the first half of INSERT statement  
DECLARE @stringData nvarchar(3000) --for storing the data (VALUES) related statement  
DECLARE @dataType nvarchar(1000) --data types returned for respective columns  
DECLARE @IDENTITY_STRING nvarchar (100)  
SET @IDENTITY_STRING = ' '  
select @IDENTITY_STRING  
SET @string='INSERT '[email protected]+'('  
SET @stringData=''  

DECLARE @colName nvarchar(50)  

FETCH NEXT FROM cursCol INTO @colName,@dataType  

IF @@fetch_status<>0  
begin  
print 'Table '[email protected]+' not found, processing skipped.'  
close curscol  
deallocate curscol  
return  
END  

WHILE @@FETCH_STATUS=0  
BEGIN  
IF @dataType in ('varchar','char','nchar','nvarchar')  
BEGIN  
--SET @[email protected]+'''''''''+isnull('[email protected]+','''')+'''''',''+'  
SET @[email protected]+''''+'''+isnull('''''+'''''+'[email protected]+'+'''''+''''',''NULL'')+'',''+'  
END  
ELSE  
if @dataType in ('text','ntext') --if the datatype is text or something else  
BEGIN  
SET @[email protected]+'''''''''+isnull(cast('[email protected]+' as varchar(2000)),'''')+'''''',''+'  
END  
ELSE  
IF @dataType = 'money' --because money doesn't get converted from varchar implicitly  
BEGIN  
SET @[email protected]+'''convert(money,''''''+isnull(cast('[email protected]+' as varchar(200)),''0.0000'')+''''''),''+'  
END  
ELSE  
IF @dataType='datetime'  
BEGIN  
--SET @[email protected]+'''convert(datetime,''''''+isnull(cast('[email protected]+' as varchar(200)),''0'')+''''''),''+'  
--SELECT 'INSERT Authorizations(StatusDate) VALUES('+'convert(datetime,'+isnull(''''+convert(varchar(200),StatusDate,121)+'''','NULL')+',121),)' FROM Authorizations  
--SET @[email protected]+'''convert(money,''''''+isnull(cast('[email protected]+' as varchar(200)),''0.0000'')+''''''),''+'  
SET @[email protected]+'''convert(datetime,'+'''+isnull('''''+'''''+convert(varchar(200),'[email protected]+',121)+'''''+''''',''NULL'')+'',121),''+'  
    --        'convert(datetime,'+isnull(''''+convert(varchar(200),StatusDate,121)+'''','NULL')+',121),)' FROM Authorizations  
END  
ELSE  
IF @dataType='image'  
BEGIN  
SET @[email protected]+'''''''''+isnull(cast(convert(varbinary,'[email protected]+') as varchar(6)),''0'')+'''''',''+'  
END  
ELSE --presuming the data type is int,bit,numeric,decimal  
BEGIN  
--SET @[email protected]+'''''''''+isnull(cast('[email protected]+' as varchar(200)),''0'')+'''''',''+'  
--SET @[email protected]+'''convert(datetime,'+'''+isnull('''''+'''''+convert(varchar(200),'[email protected]+',121)+'''''+''''',''NULL'')+'',121),''+'  
SET @[email protected]+''''+'''+isnull('''''+'''''+convert(varchar(200),'[email protected]+')+'''''+''''',''NULL'')+'',''+'  
END  

SET @[email protected][email protected]+','  

FETCH NEXT FROM cursCol INTO @colName,@dataType  
END  
DECLARE @Query nvarchar(4000)  

SET @query ='SELECT '''+substring(@string,0,len(@string)) + ') VALUES(''+ ' + substring(@stringData,0,len(@stringData)-2)+'''+'')'' FROM '[email protected]  
exec sp_executesql @query  
--select @query  

CLOSE cursCol  
DEALLOCATE cursCol  


    /* 
USAGE 

*/ 

GO 

- 和第二不進行身份INSERTION

USE [db] 
GO 

/****** Object: StoredProcedure [dbo].[procUtils_InsertGenerator] Script Date: 06/13/2009 22:20:52 ******/ 
SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 

CREATE PROC [dbo].[procUtils_InsertGenerator]   
(  
@domain_user varchar(50),   
@tableName varchar(100)   
)   


as   

--Declare a cursor to retrieve column specific information for the specified table   
DECLARE cursCol CURSOR FAST_FORWARD FOR   


-- SELECT column_name,data_type FROM information_schema.columns WHERE table_name = @tableName   
/* NEW  
SELECT c.name , sc.data_type FROM sys.extended_properties AS ep     
INNER JOIN sys.tables AS t ON ep.major_id = t.object_id     
INNER JOIN sys.columns AS c ON ep.major_id = c.object_id AND ep.minor_id     
= c.column_id     
INNER JOIN INFORMATION_SCHEMA.COLUMNS sc ON t.name = sc.table_name and     
c.name = sc.column_name     
WHERE t.name = @tableName and c.is_identity=0  
    */  

select object_name(c.object_id) "TABLE_NAME", c.name "COLUMN_NAME", s.name "DATA_TYPE"  
    from sys.columns c   
    join sys.systypes s on (s.xtype = c.system_type_id)   
    where object_name(c.object_id) in (select name from sys.tables where name not like 'sysdiagrams')   
    AND object_name(c.object_id) in (select name from sys.tables where [name][email protected] ) and c.is_identity=0 and s.name not like 'sysname' 




OPEN cursCol   
DECLARE @string nvarchar(3000) --for storing the first half of INSERT statement   
DECLARE @stringData nvarchar(3000) --for storing the data (VALUES) related statement   
DECLARE @dataType nvarchar(1000) --data types returned for respective columns   
DECLARE @IDENTITY_STRING nvarchar (100)   
SET @IDENTITY_STRING = ' '   
select @IDENTITY_STRING   
SET @string='INSERT '[email protected]+'('   
SET @stringData=''   

DECLARE @colName nvarchar(50)   

FETCH NEXT FROM cursCol INTO @tableName , @colName,@dataType   

IF @@fetch_status<>0   
begin   
print 'Table '[email protected]+' not found, processing skipped.'   
close curscol   
deallocate curscol   
return   
END   

WHILE @@FETCH_STATUS=0   
BEGIN   
IF @dataType in ('varchar','char','nchar','nvarchar')   
BEGIN   
--SET @[email protected]+'''''''''+isnull('[email protected]+','''')+'''''',''+'   
SET @[email protected]+''''+'''+isnull('''''+'''''+'[email protected]+'+'''''+''''',''NULL'')+'',''+'   
END   
ELSE   
if @dataType in ('text','ntext') --if the datatype is text or something else   
BEGIN   
SET @[email protected]+'''''''''+isnull(cast('[email protected]+' as varchar(2000)),'''')+'''''',''+'   
END   
ELSE   
IF @dataType = 'money' --because money doesn't get converted from varchar implicitly   
BEGIN   
SET @[email protected]+'''convert(money,''''''+isnull(cast('[email protected]+' as varchar(200)),''0.0000'')+''''''),''+'   
END   
ELSE   
IF @dataType='datetime'   
BEGIN   
--SET @[email protected]+'''convert(datetime,''''''+isnull(cast('[email protected]+' as varchar(200)),''0'')+''''''),''+'   
--SELECT 'INSERT Authorizations(StatusDate) VALUES('+'convert(datetime,'+isnull(''''+convert(varchar(200),StatusDate,121)+'''','NULL')+',121),)' FROM Authorizations   
--SET @[email protected]+'''convert(money,''''''+isnull(cast('[email protected]+' as varchar(200)),''0.0000'')+''''''),''+'   
SET @[email protected]+'''convert(datetime,'+'''+isnull('''''+'''''+convert(varchar(200),'[email protected]+',121)+'''''+''''',''NULL'')+'',121),''+'   
    --        'convert(datetime,'+isnull(''''+convert(varchar(200),StatusDate,121)+'''','NULL')+',121),)' FROM Authorizations   
END   
ELSE   
IF @dataType='image'   
BEGIN   
SET @[email protected]+'''''''''+isnull(cast(convert(varbinary,'[email protected]+') as varchar(6)),''0'')+'''''',''+'   
END   
ELSE --presuming the data type is int,bit,numeric,decimal   
BEGIN   
--SET @[email protected]+'''''''''+isnull(cast('[email protected]+' as varchar(200)),''0'')+'''''',''+'   
--SET @[email protected]+'''convert(datetime,'+'''+isnull('''''+'''''+convert(varchar(200),'[email protected]+',121)+'''''+''''',''NULL'')+'',121),''+'   
SET @[email protected]+''''+'''+isnull('''''+'''''+convert(varchar(200),'[email protected]+')+'''''+''''',''NULL'')+'',''+'   
END   

SET @[email protected][email protected]+','   

FETCH NEXT FROM cursCol INTO @tableName , @colName,@dataType   
END   
DECLARE @Query nvarchar(4000)   

SET @query ='SELECT '''+substring(@string,0,len(@string)) + ') VALUES(''+ ' + substring(@stringData,0,len(@stringData)-2)+'''+'')'' FROM '[email protected]   
exec sp_executesql @query   
--select @query  

CLOSE cursCol   
DEALLOCATE cursCol   


    /*  

use poc  
go  

DECLARE @RC int  
DECLARE @domain_user varchar(50)  
DECLARE @tableName varchar(100)  

-- TODO: Set parameter values here.  
set @domain_user='yorgeorg'  
set @tableName = 'tbGui_WizardTabButtonAreas'  

EXECUTE @RC = [POC].[dbo].[procUtils_InsertGenerator]  
    @domain_user  
    ,@tableName  

*/ 
GO 
3

Show create table in classic asp(處理約束,主鍵,複製表結構和/或數據...)

sql server show create table Mysql風格的「Show create table」和「show create database」命令來自Microsoft sql server。 腳本編寫是微軟ASP的語言,是很容易的移植到另一種語言*

12

有埋在msdb論壇一個PowerShell腳本,將腳本所有表和相關對象:

# Script all tables in a database 
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") 
    | out-null 

$s = new-object ('Microsoft.SqlServer.Management.Smo.Server') '<Servername>' 
$db = $s.Databases['<Database>'] 

$scrp = new-object ('Microsoft.SqlServer.Management.Smo.Scripter') ($s) 
$scrp.Options.AppendToFile = $True 
$scrp.Options.ClusteredIndexes = $True 
$scrp.Options.DriAll = $True 
$scrp.Options.ScriptDrops = $False 
$scrp.Options.IncludeHeaders = $False 
$scrp.Options.ToFileOnly = $True 
$scrp.Options.Indexes = $True 
$scrp.Options.WithDependencies = $True 
$scrp.Options.FileName = 'C:\Temp\<Database>.SQL' 

foreach($item in $db.Tables) { [email protected]($item) } 
$scrp.Script($tablearray) 

Write-Host "Scripting complete" 
9

支持模式:

這是修訂大衛偉大的答案的更新版本等。增加了對命名模式的支持。應該指出的是,如果在各種模式中存在實際上具有相同名稱的表,則這可能會中斷。另一個改進是使用官方的QuoteName()函數。

SELECT 
    t.TABLE_CATALOG, 
    t.TABLE_SCHEMA, 
    t.TABLE_NAME, 
    'create table '+QuoteName(t.TABLE_SCHEMA)+'.' + QuoteName(so.name) + ' (' + LEFT(o.List, Len(o.List)-1) + '); ' 
     + CASE WHEN tc.Constraint_Name IS NULL THEN '' 
      ELSE 
      'ALTER TABLE ' + QuoteName(t.TABLE_SCHEMA)+'.' + QuoteName(so.name) 
      + ' ADD CONSTRAINT ' + tc.Constraint_Name + ' PRIMARY KEY ' + ' (' + LEFT(j.List, Len(j.List)-1) + '); ' 
      END as 'SQL_CREATE_TABLE' 
FROM sysobjects so 

CROSS APPLY (
    SELECT 
      ' ['+column_name+'] ' 
      + data_type 
      + case data_type 
       when 'sql_variant' then '' 
       when 'text' then '' 
       when 'ntext' then '' 
       when 'decimal' then '(' + cast(numeric_precision as varchar) + ', ' + cast(numeric_scale as varchar) + ')' 
       else 
       coalesce(
       '('+ case when character_maximum_length = -1 
        then 'MAX' 
        else cast(character_maximum_length as varchar) end 
       + ')','') 
      end 
     + ' ' 
     + case when exists ( 
      SELECT id 
      FROM syscolumns 
      WHERE 
       object_name(id) = so.name 
       and name = column_name 
       and columnproperty(id,name,'IsIdentity') = 1 
     ) then 
      'IDENTITY(' + 
      cast(ident_seed(so.name) as varchar) + ',' + 
      cast(ident_incr(so.name) as varchar) + ')' 
      else '' 
      end 
     + ' ' 
     + (case when IS_NULLABLE = 'No' then 'NOT ' else '' end) 
     + 'NULL ' 
     + case when information_schema.columns.COLUMN_DEFAULT IS NOT NULL THEN 'DEFAULT '+ information_schema.columns.COLUMN_DEFAULT 
      ELSE '' 
      END 
     + ',' -- can't have a field name or we'll end up with XML 

    FROM information_schema.columns 
    WHERE table_name = so.name 
    ORDER BY ordinal_position 
    FOR XML PATH('') 
) o (list) 

LEFT JOIN information_schema.table_constraints tc on 
    tc.Table_name = so.Name 
    AND tc.Constraint_Type = 'PRIMARY KEY' 

LEFT JOIN information_schema.tables t on 
    t.Table_name = so.Name 

CROSS APPLY (
    SELECT QuoteName(Column_Name) + ', ' 
    FROM information_schema.key_column_usage kcu 
    WHERE kcu.Constraint_Name = tc.Constraint_Name 
    ORDER BY ORDINAL_POSITION 
    FOR XML PATH('') 
) j (list) 

WHERE 
    xtype = 'U' 
    AND name NOT IN ('dtproperties') 
    -- AND so.name = 'ASPStateTempSessions' 
; 

..

對於Management Studio中使用:以上

一個誹謗者的SQL代碼,如果你使用測試SSMS的,冗長的發言不容易閱讀。所以,根據this helpful post,這裏有另一個版本,點擊網格中單元格的鏈接之後,可以稍微修改它以使眼睛更容易。結果更容易被識別爲db中每個表格格式良好的CREATE TABLE語句。

-- settings 
DECLARE @CRLF NCHAR(2) 
SET @CRLF = Nchar(13) + NChar(10) 
DECLARE @PLACEHOLDER NCHAR(3) 
SET @PLACEHOLDER = '{:}' 

-- the main query 
SELECT 
    t.TABLE_CATALOG, 
    t.TABLE_SCHEMA, 
    t.TABLE_NAME, 
    CAST(
     REPLACE(
      'create table ' + QuoteName(t.TABLE_SCHEMA) + '.' + QuoteName(so.name) + ' (' + @CRLF 
      + LEFT(o.List, Len(o.List) - (LEN(@PLACEHOLDER)+2)) + @CRLF + ');' + @CRLF 
      + CASE WHEN tc.Constraint_Name IS NULL THEN '' 
       ELSE 
       'ALTER TABLE ' + QuoteName(t.TABLE_SCHEMA) + '.' + QuoteName(so.Name) 
       + ' ADD CONSTRAINT ' + tc.Constraint_Name + ' PRIMARY KEY (' + LEFT(j.List, Len(j.List) - 1) + ');' + @CRLF 
       END, 
      @PLACEHOLDER, 
      @CRLF 
     ) 
    AS XML) as 'SQL_CREATE_TABLE' 
FROM sysobjects so 

CROSS APPLY (
    SELECT 
      ' ' 
      + '['+column_name+'] ' 
      + data_type 
      + case data_type 
       when 'sql_variant' then '' 
       when 'text' then '' 
       when 'ntext' then '' 
       when 'decimal' then '(' + cast(numeric_precision as varchar) + ', ' + cast(numeric_scale as varchar) + ')' 
       else 
       coalesce(
       '('+ case when character_maximum_length = -1 
        then 'MAX' 
        else cast(character_maximum_length as varchar) end 
       + ')','') 
      end 
     + ' ' 
     + case when exists ( 
      SELECT id 
      FROM syscolumns 
      WHERE 
       object_name(id) = so.name 
       and name = column_name 
       and columnproperty(id,name,'IsIdentity') = 1 
     ) then 
      'IDENTITY(' + 
      cast(ident_seed(so.name) as varchar) + ',' + 
      cast(ident_incr(so.name) as varchar) + ')' 
      else '' 
      end 
     + ' ' 
     + (case when IS_NULLABLE = 'No' then 'NOT ' else '' end) 
     + 'NULL ' 
     + case when information_schema.columns.COLUMN_DEFAULT IS NOT NULL THEN 'DEFAULT '+ information_schema.columns.COLUMN_DEFAULT 
      ELSE '' 
      END 
     + ', ' 
     + @PLACEHOLDER -- note, can't have a field name or we'll end up with XML 

    FROM information_schema.columns where table_name = so.name 
    ORDER BY ordinal_position 
    FOR XML PATH('') 
) o (list) 

LEFT JOIN information_schema.table_constraints tc on 
    tc.Table_name = so.Name 
    AND tc.Constraint_Type = 'PRIMARY KEY' 

LEFT JOIN information_schema.tables t on 
    t.Table_name = so.Name 

CROSS APPLY (
    SELECT QUOTENAME(Column_Name) + ', ' 
    FROM information_schema.key_column_usage kcu 
    WHERE kcu.Constraint_Name = tc.Constraint_Name 
    ORDER BY ORDINAL_POSITION 
    FOR XML PATH('') 
) j (list) 

WHERE 
    xtype = 'U' 
    AND name NOT IN ('dtproperties') 
    -- AND so.name = 'ASPStateTempSessions' 
; 

不要痛打這一點,但這裏的功能相當的例子輸出進行比較:

-- 1 (scripting version) 
create table [dbo].[ASPStateTempApplications] ( [AppId] int NOT NULL , [AppName] char(280) NOT NULL); ALTER TABLE [dbo].[ASPStateTempApplications] ADD CONSTRAINT PK__ASPState__8E2CF7F908EA5793 PRIMARY KEY ([AppId]); 

-- 2 (SSMS version) 
create table [dbo].[ASPStateTempSessions] (
    [SessionId] nvarchar(88) NOT NULL , 
    [Created] datetime NOT NULL DEFAULT (getutcdate()), 
    [Expires] datetime NOT NULL , 
    [LockDate] datetime NOT NULL , 
    [LockDateLocal] datetime NOT NULL , 
    [LockCookie] int NOT NULL , 
    [Timeout] int NOT NULL , 
    [Locked] bit NOT NULL , 
    [SessionItemShort] varbinary(7000) NULL , 
    [SessionItemLong] image(2147483647) NULL , 
    [Flags] int NOT NULL DEFAULT ((0)) 
); 
ALTER TABLE [dbo].[ASPStateTempSessions] ADD CONSTRAINT PK__ASPState__C9F4929003317E3D PRIMARY KEY ([SessionId]); 

..

減損因素:

應當指出的是,我仍然相對不滿意這種由於缺乏比主鍵等的indeces支持。它仍然適合用作簡單數據導出或複製的機制。

6

還有一個變型與外鍵支持,並在一個聲明:

SELECT 
     obj.name 
     ,'CREATE TABLE [' + obj.name + '] (' + LEFT(cols.list, LEN(cols.list) - 1) + ')' 
     + ISNULL(' ' + refs.list, '') 
    FROM sysobjects obj 
    CROSS APPLY (
     SELECT 
      CHAR(10) 
      + ' [' + column_name + '] ' 
      + data_type 
      + CASE data_type 
       WHEN 'sql_variant' THEN '' 
       WHEN 'text' THEN '' 
       WHEN 'ntext' THEN '' 
       WHEN 'xml' THEN '' 
       WHEN 'decimal' THEN '(' + CAST(numeric_precision as VARCHAR) + ', ' + CAST(numeric_scale as VARCHAR) + ')' 
       ELSE COALESCE('(' + CASE WHEN character_maximum_length = -1 THEN 'MAX' ELSE CAST(character_maximum_length as VARCHAR) END + ')', '') 
      END 
      + ' ' 
      + case when exists (-- Identity skip 
      select id from syscolumns 
      where object_name(id) = obj.name 
      and name = column_name 
      and columnproperty(id,name,'IsIdentity') = 1 
      ) then 
      'IDENTITY(' + 
      cast(ident_seed(obj.name) as varchar) + ',' + 
      cast(ident_incr(obj.name) as varchar) + ')' 
      else '' 
      end + ' ' 
      + CASE WHEN IS_NULLABLE = 'No' THEN 'NOT ' ELSE '' END 
      + 'NULL' 
      + CASE WHEN information_schema.columns.column_default IS NOT NULL THEN ' DEFAULT ' + information_schema.columns.column_default ELSE '' END 
      + ',' 
     FROM 
      INFORMATION_SCHEMA.COLUMNS 
     WHERE table_name = obj.name 
     ORDER BY ordinal_position 
     FOR XML PATH('') 
    ) cols (list) 
    CROSS APPLY(
     SELECT 
      CHAR(10) + 'ALTER TABLE ' + obj.name + '_noident_temp ADD ' + LEFT(alt, LEN(alt)-1) 
     FROM(
      SELECT 
       CHAR(10) 
       + ' CONSTRAINT ' + tc.constraint_name 
       + ' ' + tc.constraint_type + ' (' + LEFT(c.list, LEN(c.list)-1) + ')' 
       + COALESCE(CHAR(10) + r.list, ', ') 
      FROM 
       information_schema.table_constraints tc 
       CROSS APPLY(
        SELECT 
         '[' + kcu.column_name + '], ' 
        FROM 
         information_schema.key_column_usage kcu 
        WHERE 
         kcu.constraint_name = tc.constraint_name 
        ORDER BY 
         kcu.ordinal_position 
        FOR XML PATH('') 
       ) c (list) 
       OUTER APPLY(
        -- // http://stackoverflow.com/questions/3907879/sql-server-howto-get-foreign-key-reference-from-information-schema 
        SELECT 
         ' REFERENCES [' + kcu1.constraint_schema + '].' + '[' + kcu2.table_name + ']' + '(' + kcu2.column_name + '), ' 
        FROM information_schema.referential_constraints as rc 
         JOIN information_schema.key_column_usage as kcu1 ON (kcu1.constraint_catalog = rc.constraint_catalog AND kcu1.constraint_schema = rc.constraint_schema AND kcu1.constraint_name = rc.constraint_name) 
         JOIN information_schema.key_column_usage as kcu2 ON (kcu2.constraint_catalog = rc.unique_constraint_catalog AND kcu2.constraint_schema = rc.unique_constraint_schema AND kcu2.constraint_name = rc.unique_constraint_name AND kcu2.ordinal_position = KCU1.ordinal_position) 
        WHERE 
         kcu1.constraint_catalog = tc.constraint_catalog AND kcu1.constraint_schema = tc.constraint_schema AND kcu1.constraint_name = tc.constraint_name 
       ) r (list) 
      WHERE tc.table_name = obj.name 
      FOR XML PATH('') 
     ) a (alt) 
    ) refs (list) 
    WHERE 
     xtype = 'U' 
    AND name NOT IN ('dtproperties') 
    AND obj.name = 'your_table_name' 

你可以嘗試是sqlfiddle:http://sqlfiddle.com/#!6/e3b66/3/0

6

我修改了公認的答案,現在它可以得到包括主鍵的命令和外鍵在某個模式中。

declare @table varchar(100) 
declare @schema varchar(100) 
set @table = 'Persons' -- set table name here 
set @schema = 'OT' -- set SCHEMA name here 
declare @sql table(s varchar(1000), id int identity) 

-- create statement 
insert into @sql(s) values ('create table ' + @table + ' (') 

-- column list 
insert into @sql(s) 
select 
    ' '+column_name+' ' + 
    data_type + coalesce('('+cast(character_maximum_length as varchar)+')','') + ' ' + 
    case when exists ( 
     select id from syscolumns 
     where object_name(id)[email protected] 
     and name=column_name 
     and columnproperty(id,name,'IsIdentity') = 1 
    ) then 
     'IDENTITY(' + 
     cast(ident_seed(@table) as varchar) + ',' + 
     cast(ident_incr(@table) as varchar) + ')' 
    else '' 
    end + ' ' + 
    (case when IS_NULLABLE = 'No' then 'NOT ' else '' end) + 'NULL ' + 
    coalesce('DEFAULT '+COLUMN_DEFAULT,'') + ',' 

from information_schema.columns where table_name = @table and table_schema = @schema 
order by ordinal_position 

-- primary key 
declare @pkname varchar(100) 
select @pkname = constraint_name from information_schema.table_constraints 
where table_name = @table and constraint_type='PRIMARY KEY' 

if (@pkname is not null) begin 
    insert into @sql(s) values(' PRIMARY KEY (') 
    insert into @sql(s) 
     select ' '+COLUMN_NAME+',' from information_schema.key_column_usage 
     where constraint_name = @pkname 
     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 
else begin 
    -- remove trailing comma 
    update @sql set s=left(s,len(s)-1) where [email protected]@identity 
end 


-- foreign key 
declare @fkname varchar(100) 
select @fkname = constraint_name from information_schema.table_constraints 
where table_name = @table and constraint_type='FOREIGN KEY' 

if (@fkname is not null) begin 
    insert into @sql(s) values(',') 
    insert into @sql(s) values(' FOREIGN KEY (') 
    insert into @sql(s) 
     select ' '+COLUMN_NAME+',' from information_schema.key_column_usage 
     where constraint_name = @fkname 
     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 (' ) REFERENCES ') 
    insert into @sql(s) 
     SELECT 
      OBJECT_NAME(fk.referenced_object_id) 
     FROM 
      sys.foreign_keys fk 
     INNER JOIN 
      sys.foreign_key_columns fkc ON fkc.constraint_object_id = fk.object_id 
     INNER JOIN 
      sys.columns c1 ON fkc.parent_column_id = c1.column_id AND fkc.parent_object_id = c1.object_id 
     INNER JOIN 
      sys.columns c2 ON fkc.referenced_column_id = c2.column_id AND fkc.referenced_object_id = c2.object_id 
     where fk.name = @fkname 
    insert into @sql(s) 
     SELECT 
      '('+c2.name+')' 
     FROM 
      sys.foreign_keys fk 
     INNER JOIN 
      sys.foreign_key_columns fkc ON fkc.constraint_object_id = fk.object_id 
     INNER JOIN 
      sys.columns c1 ON fkc.parent_column_id = c1.column_id AND fkc.parent_object_id = c1.object_id 
     INNER JOIN 
      sys.columns c2 ON fkc.referenced_column_id = c2.column_id AND fkc.referenced_object_id = c2.object_id 
     where fk.name = @fkname 
end 

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

-- result! 
select s from @sql order by id 
6

我會通過支持分區表,提高了答案:

查找分區方案和分區鍵使用以下scritps:

declare @partition_scheme varchar(100) = (
select distinct ps.Name AS PartitionScheme 
from sys.indexes i 
join sys.partitions p ON i.object_id=p.object_id AND i.index_id=p.index_id 
join sys.partition_schemes ps on ps.data_space_id = i.data_space_id 
where i.object_id = object_id('your table name') 
) 
print @partition_scheme 

declare @partition_column varchar(100) = (
select c.name 
from sys.tables   t 
join sys.indexes   i 
     on(i.object_id = t.object_id 
    and i.index_id < 2) 
join sys.index_columns ic 
    on(ic.partition_ordinal > 0 
    and ic.index_id = i.index_id and ic.object_id = t.object_id) 
join sys.columns   c 
    on(c.object_id = ic.object_id 
    and c.column_id = ic.column_id) 
where t.object_id = object_id('your table name') 
) 
print @partition_column 

然後改變一代查詢通過添加以下行在正確的地方:

+ IIF(@partition_scheme is null, '', 'ON [' + @partition_scheme + ']([' + @partition_column + '])') 
0

我包括計算列的定義

select 'CREATE TABLE [' + so.name + '] (' + o.list + ')' + CASE WHEN tc.Constraint_Name IS NULL THEN '' ELSE 'ALTER TABLE ' + so.Name + ' ADD CONSTRAINT ' + tc.Constraint_Name + ' PRIMARY KEY ' + ' (' + LEFT(j.List, Len(j.List)-1) + ')' END, name 
from sysobjects so 
cross apply 
    (SELECT 

case when comps.definition is not null then ' ['+column_name+'] AS ' + comps.definition 
else 
     ' ['+column_name+'] ' + data_type + 
     case 
     when data_type like '%text' or data_type in ('image', 'sql_variant' ,'xml') 
      then '' 
     when data_type in ('float') 
      then '(' + cast(coalesce(numeric_precision, 18) as varchar(11)) + ')' 
     when data_type in ('datetime2', 'datetimeoffset', 'time') 
      then '(' + cast(coalesce(datetime_precision, 7) as varchar(11)) + ')' 
     when data_type in ('decimal', 'numeric') 
      then '(' + cast(coalesce(numeric_precision, 18) as varchar(11)) + ',' + cast(coalesce(numeric_scale, 0) as varchar(11)) + ')' 
     when (data_type like '%binary' or data_type like '%char') and character_maximum_length = -1 
      then '(max)' 
     when character_maximum_length is not null 
      then '(' + cast(character_maximum_length as varchar(11)) + ')' 
     else '' 
     end + ' ' + 
     case when exists ( 
     select id from syscolumns 
     where object_name(id)=so.name 
     and name=column_name 
     and columnproperty(id,name,'IsIdentity') = 1 
     ) then 
     'IDENTITY(' + 
     cast(ident_seed(so.name) as varchar) + ',' + 
     cast(ident_incr(so.name) as varchar) + ')' 
     else '' 
     end + ' ' + 
     (case when information_schema.columns.IS_NULLABLE = 'No' then 'NOT ' else '' end) + 'NULL ' + 
      case when information_schema.columns.COLUMN_DEFAULT IS NOT NULL THEN 'DEFAULT '+ information_schema.columns.COLUMN_DEFAULT ELSE '' END 
end + ', ' 

    from information_schema.columns 
    left join sys.computed_columns comps 
    on OBJECT_ID(information_schema.columns.TABLE_NAME)=comps.object_id and information_schema.columns.COLUMN_NAME=comps.name 

    where table_name = so.name 
    order by ordinal_position 
    FOR XML PATH('')) o (list) 
left join 
    information_schema.table_constraints tc 
on tc.Table_name  = so.Name 
AND tc.Constraint_Type = 'PRIMARY KEY' 
cross apply 
    (select '[' + Column_Name + '], ' 
    FROM information_schema.key_column_usage kcu 
    WHERE kcu.Constraint_Name = tc.Constraint_Name 
    ORDER BY 
     ORDINAL_POSITION 
    FOR XML PATH('')) j (list) 
where xtype = 'U' 
AND name NOT IN ('dtproperties') 
1

我意識到這是一個很長的時間,但我想我會加上反正。如果你只是想表,而不是創建表語句,你可以使用

select into x from db.schema.y where 1=0 

表複製到新的DB

相關問題