2012-06-18 23 views
2

是否有一種基於數據庫中的列/列信息快速獲取包含列聲明所需的sql數據類型的字符串?獲取用於聲明的列創建數據類型

比如我想返回的字符串,如:

varchar(200) 
datetime 
numeric(35,5) 

很顯然,我可以得到這個從SYS.COLUMNSINFORMATION_SCHEMA.COLUMNS產生自己,並開始處理這些所需的信息,但我想一個(最好是MS提供)方式將數據類型/ maxlength/precision/scale信息自動轉換爲列聲明數據類型。

我想如果有一個標準的方法來做到這一點,它會處理所有可能的數據類型,這將是一個嘗試手動覆蓋的痛苦。

編輯:對不起 - 我似乎還沒有足夠清楚我想要什麼。

例如,當您在SSMS中爲CREATE腳本編寫表時,生成的腳本包含所需格式的數據類型。有沒有辦法讓這些自動?

編輯:

OK:一是多了去了:

我要的是一個有點像這樣的問題:

Declaring variable type based on a column type

不同的是,我不介意到動態聲明變量,因爲我已經在使用動態SQL。

+1

您可以檢查這個腳本(生成與T-SQL表DDL)作爲參照,http://www.stormrage.com/SQLStuff/sp_GetDDL_Latest.txt – EricZ

+0

@EricZ:這是你自己的還是從某處其他? - 可以把它變成一個單一列的udf。 –

+0

不,這不是我的腳本。 – EricZ

回答

3

我怕我不知道正確的方式,但我已經在做INFORMATION_SCHEMA.Columns方式有一展身手。這不是很好,但確實處理數據庫默認值,可空數據等。

SELECT column_name + ' ' + DATA_TYPE + COALESCE('(' + CASE 
                 WHEN DATA_TYPE = 'XML' THEN NULL 
                 WHEN CHARACTER_MAXIMUM_LENGTH = -1 THEN 'max' 
                 ELSE Cast(CHARACTER_MAXIMUM_LENGTH AS VARCHAR(5)) 
                 END + ')', '(' + Cast(NUMERIC_PRECISION AS NVARCHAR(5)) + ',' + Cast(NUMERIC_SCALE AS NVARCHAR(5)) + ')', '') + ' ' + CASE IS_NULLABLE 
                                               WHEN 'YES' THEN 'NULL' 
                                               ELSE 'NOT NULL' 
                                              END + COALESCE(' DEFAULT' + COLUMN_DEFAULT, '') 
FROM INFORMATION_SCHEMA.Columns 
WHERE table_name = 'mytable' 
+0

這就是我編碼結束的事情。顯然,在t-sql中最接近的是'OBJECT_DEFINITION',但這對錶格不起作用。在MS Connect中有一些關於它的內容,但它被推遲了。 –

+0

@JonEgerton我一直在追蹤一些SQL Server的東西,「錯過了」SQL Server 2005,他們還沒有實現3個版本 - 所以我不會屏住呼吸!祝你好運,如果有什麼在這個答案有幫助,然後可以隨意使用它。 – Bridge

+0

有一點,它將xml cols描述爲xml(max)。 –

0
SELECT 
OBJECT_NAME(c.OBJECT_ID) TableName 
,c.name AS ColumnName 
,t.name AS TypeName 
,c.max_length 
,c.PRECISION 
,c.scale 
FROM sys.columns AS c 
JOIN sys.types AS t ON c.user_type_id=t.user_type_id 
ORDER BY c.OBJECT_ID 

我擔心無論哪種方式(information_schema.columns)或上面的查詢,您都必須「按摩」返回集以生成正確的數據類型聲明。

+0

正如我在問題中所說的,從sys.columns中獲取它很容易,而不是我感興趣的。我希望按照我的示例編譯數據類型,以便我可以使用它來聲明其他變量/列。 –

0

sp_help的第二個結果集呢?我想你可以很容易地調整輸出,以得到你想要的。

2

這是我的工具箱中的東西。請注意,它可以自由將TEXT轉換爲VARCHAR(MAX)。意見可能會有所不同,但我認爲這是一個功能,因爲我討厭TEXT類型:)

SELECT REPLACE(REPLACE(REPLACE(CASE ORDINAL_POSITION WHEN 1 THEN '' ELSE ', ' END +'['+column_name+'] ' 
    +c.DATA_TYPE 
    +ISNULL('('+CAST(c.CHARACTER_MAXIMUM_LENGTH AS VARCHAR(30))+')','') 
    +CASE WHEN c.DATA_TYPE IN ('NUMERIC','DECIMAL') THEN 
     ISNULL('('+CAST(c.NUMERIC_PRECISION AS VARCHAR(30))+','+CAST(c.NUMERIC_SCALE AS VARCHAR(30))+')','') 
     ELSE '' END 
    +' ','text(2147483647)','varchar(max)'),'(-1)','(max)') 

    -- These last two are optional 
    +isnull(CASE WHEN c.IS_NULLABLE='NO' THEN 'NOT ' ELSE NULL END,'') 
    +'NULL' 
    , 'XML(MAX)','XML') 
FROM INFORMATION_SCHEMA.COLUMNS c 
WHERE TABLE_NAME='MyTable' and TABLE_SCHEMA='dbo' 
ORDER BY ORDINAL_POSITION 

編輯:替換XML(MAX)與XML結果

+0

需要注意的一件事:它聲明xml cols爲'xml(max)'(僅僅是針對一些更多的col類型來嘗試它,所以看它如何處理)。 –

+0

是的,我不經常處理這些,所以這裏是一個快速修復.. –

0

這是我結束了(使用SQL Server 2014)

CREATE FUNCTION dbo.GetTypeDeclaration(@schema AS VARCHAR(MAX), @table AS VARCHAR(MAX), @column AS VARCHAR(MAX)) RETURNS VARCHAR(MAX) AS 
BEGIN 
    DECLARE @type as SYSNAME 
    DECLARE @typeDeclaration as VARCHAR(MAX) 
    DECLARE @maxLength AS SMALLINT 
    DECLARE @precision AS TINYINT 
    DECLARE @scale AS TINYINT 

    SELECT @type = ty.name, @maxLength = c.max_length, @precision = c.precision, @scale = c.scale 
    FROM sys.tables t 
    INNER JOIN sys.columns c ON t.object_id = c.object_id 
    INNER JOIN sys.types ty ON ty.user_type_id = c.user_type_id 
    WHERE t.schema_id = SCHEMA_ID(@schema) AND t.name = @table AND c.name = @column 

    IF @maxLength <> -1 AND @type IN ('nchar', 'nvarchar', 'nvarbinary') 
    BEGIN 
     SET @maxLength = @maxLength/2 
    END 

    IF @type IN ('binary', 'char', 'nchar') 
    BEGIN 
     SET @typeDeclaration = @type + '(' + CAST(@maxLength AS VARCHAR) + ')' 
    END 
    ELSE IF @type IN ('datetime2', 'datetimeoffset', 'time') 
    BEGIN 
     SET @typeDeclaration = @type + '(' + CAST(@scale AS VARCHAR) + ')' 
    END 
    ELSE IF @type IN ('nvarchar', 'nvarbinary', 'varchar', 'varbinary') 
    BEGIN 
     SET @typeDeclaration = @type + '(' + CASE WHEN @maxLength = -1 THEN 'max' ELSE CAST(@maxLength AS VARCHAR) END + ')' 
    END 
    ELSE IF @type IN ('decimal', 'numeric') 
    BEGIN 
     SET @typeDeclaration = @type + '(' + CAST(@precision AS VARCHAR) + ', ' + CAST(@scale AS VARCHAR) + ')' 
    END 
    ELSE 
    BEGIN 
     SET @typeDeclaration = @type 
    END 

    RETURN @typeDeclaration 
END