4

如何通过单个查询获取所有用户定义数据类型的脚本。

4

3 回答 3

6

尝试这个:

SET NOCOUNT ON

SELECT 'USE ' + QUOTENAME(DB_NAME(), '[') + '
GO';

SELECT '
IF  EXISTS (SELECT * FROM sys.types st JOIN sys.schemas ss ON st.schema_id = ss.schema_id WHERE st.name = N''' + st.[name] + ''' AND ss.name = N''' + ss.[name] + ''')
    DROP TYPE ' + QUOTENAME(ss.name, '[') + '.' + QUOTENAME(st.name, '[') + '
GO

CREATE TYPE ' + QUOTENAME(ss.name, '[') + '.' + QUOTENAME(st.name, '[') + ' FROM ' + 
QUOTENAME(bs.[name], '[') + 
    CASE bs.[name]
        WHEN 'char' THEN (CASE ISNULL(st.max_length, 0) WHEN 0 THEN '' WHEN -1 THEN '(MAX)' ELSE '(' + convert(varchar(10), st.max_length) + ')' END)
        WHEN 'nchar' THEN (CASE ISNULL(st.max_length, 0) WHEN 0 THEN '' WHEN -1 THEN '(MAX)' ELSE '(' + convert(varchar(10), st.max_length/2) + ')' END)
        WHEN 'varchar' THEN (CASE ISNULL(st.max_length, 0) WHEN 0 THEN '' WHEN -1 THEN '(MAX)' ELSE '(' + convert(varchar(10), st.max_length) + ')' END)
        WHEN 'nvarchar' THEN (CASE ISNULL(st.max_length, 0) WHEN 0 THEN '' WHEN -1 THEN '(MAX)' ELSE '(' + convert(varchar(10), st.max_length/2) + ')' END)
        WHEN 'numeric' THEN (CASE ISNULL(st.[precision], 0) WHEN 0 THEN '' ELSE '(' + convert(varchar(10), st.[precision]) + ', ' + convert(varchar(10), st.[scale]) + ')' END)
        WHEN 'decimal' THEN (CASE ISNULL(st.[precision], 0) WHEN 0 THEN '' ELSE '(' + convert(varchar(10), st.[precision]) + ', ' + convert(varchar(10), st.[scale]) + ')' END)
        WHEN 'varbinary' THEN (CASE st.max_length WHEN -1 THEN '(max)' ELSE '(' + convert(varchar(10), st.max_length) + ')' END)
        ELSE ''
    END + 
'
GO
'
FROM sys.types st 
    INNER JOIN sys.schemas ss ON st.[schema_id] = ss.[schema_id]
    INNER JOIN sys.types bs ON bs.[user_type_id] = st.[system_type_id]
WHERE st.[is_user_defined] = 1 -- exclude system types
ORDER BY st.[name], ss.[name]

免责声明:我不是这个脚本的作者。只是我在我的个人图书馆里有它。不幸的是,作者的名字不在其中。

于 2012-10-06T15:19:09.937 回答
1

这是一个实际工作的脚本。
为所有用户定义的标量和表类型创建一个脚本(未使用 CLR 类型进行测试):

-- http://www.sqlines.com/sql-server-to-oracle/create_type


SELECT 
      sch.name AS UDT_SCHEMA_NAME 
     ,userDefinedTypes.name AS UDT_TYPE_NAME 

    ,
    N'IF NOT EXISTS (SELECT * FROM sys.types st JOIN sys.schemas ss ON st.schema_id = ss.schema_id WHERE st.name = N''' + REPLACE(userDefinedTypes.name, '''', '''''') + N''' AND ss.name = N''' + REPLACE(sch.name, '''', '''''') + N''') '
    + NCHAR(13) + NCHAR(10) 
    +
    CASE WHEN userDefinedTypeProperties.IsTableType = 1 
        THEN N'CREATE TYPE ' + QUOTENAME(sch.name) + '.' + QUOTENAME(userDefinedTypes.name) + ' AS TABLE ( 
    ' + tAllColumns.column_definition  + N'
); ' 
        ELSE 
            + N'CREATE TYPE ' + QUOTENAME(sch.name) + '.' + QUOTENAME(userDefinedTypes.name) 
            + N' FROM ' 
            + tBaseTypeComputation.baseTypeName 
            + CASE WHEN userDefinedTypeProperties.is_nullable = 0 THEN N' NOT NULL' ELSE N'' END 
            + N'; ' 
    END AS SqlCreateUdt

FROM sys.types AS userDefinedTypes 

INNER JOIN sys.schemas AS sch 
    ON sch.schema_id = userDefinedTypes.schema_id 

LEFT JOIN sys.table_types AS userDefinedTableTypes 
    ON userDefinedTableTypes.user_type_id = userDefinedTypes.user_type_id 

LEFT JOIN sys.types AS systemType 
    ON systemType.system_type_id = userDefinedTypes.system_type_id 
    AND systemType.is_user_defined = 0 

OUTER APPLY 
    (
        SELECT 
             userDefinedTypes.is_nullable 
            ,userDefinedTypes.precision AS NUMERIC_PRECISION 
            ,userDefinedTypes.scale AS NUMERIC_SCALE 
            ,userDefinedTypes.max_length AS CHARACTER_MAXIMUM_LENGTH
            ,CASE WHEN userDefinedTableTypes.user_type_id IS NULL THEN 0 ELSE 1 END AS IsTableType 
            ,CONVERT(smallint, 
                    CASE -- datetime/smalldatetime  
                    WHEN userDefinedTypes.system_type_id IN (40, 41, 42, 43, 58, 61) THEN ODBCSCALE(userDefinedTypes.system_type_id, userDefinedTypes.scale) 
                    END
            ) AS DATETIME_PRECISION 
    ) AS userDefinedTypeProperties 


OUTER APPLY 
    (
        SELECT 
            systemType.name 
            + 
            CASE 
                WHEN systemType.name IN ('char', 'varchar', 'nchar', 'nvarchar', 'binary', 'varbinary') 
                    THEN N'(' 
                        + 
                        CASE WHEN userDefinedTypeProperties.CHARACTER_MAXIMUM_LENGTH = -1 THEN 'MAX'
                            ELSE CONVERT
                                (
                                    varchar(4)
                                    ,userDefinedTypeProperties.CHARACTER_MAXIMUM_LENGTH 
                                )
                        END 
                        + N')' 
                WHEN systemType.name IN ('decimal', 'numeric')
                    THEN N'(' + CONVERT(varchar(4), userDefinedTypeProperties.NUMERIC_PRECISION) + N', ' + CONVERT(varchar(4), userDefinedTypeProperties.NUMERIC_SCALE) + N')'
                WHEN systemType.name IN ('time', 'datetime2', 'datetimeoffset') 
                    THEN N'(' + CAST(userDefinedTypeProperties.DATETIME_PRECISION AS national character varying(36)) + N')' 
                ELSE N'' 
            END AS baseTypeName  
    ) AS tBaseTypeComputation 

OUTER APPLY 
    (
        SELECT 
            (
                SELECT 
                    -- ,clmns.is_nullable 
                    -- ,tComputedProperties.ORDINAL_POSITION
                    -- ,tComputedProperties.COLUMN_DEFAULT

                      CASE WHEN tComputedProperties.ORDINAL_POSITION = 1 THEN N' ' ELSE N',' END 
                    + QUOTENAME(clmns.name) 
                    + N' '
                    + tComputedProperties.DATA_TYPE 
                    + 
                    CASE 
                        WHEN tComputedProperties.DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar', 'binary', 'varbinary') 
                            THEN N'(' 
                                + 
                                CASE WHEN tComputedProperties.CHARACTER_MAXIMUM_LENGTH = -1 THEN 'MAX'
                                    ELSE CONVERT
                                        (
                                            varchar(4)
                                            ,tComputedProperties.CHARACTER_MAXIMUM_LENGTH 
                                        )
                                END 
                                + N')' 
                        WHEN tComputedProperties.DATA_TYPE IN ('decimal', 'numeric')
                            THEN N'(' + CONVERT(varchar(4), tComputedProperties.NUMERIC_PRECISION) + N', ' + CONVERT(varchar(4), tComputedProperties.NUMERIC_SCALE) + N')'
                        WHEN tComputedProperties.DATA_TYPE IN ('time', 'datetime2', 'datetimeoffset') 
                            THEN N'(' + CAST(tComputedProperties.DATETIME_PRECISION AS national character varying(36)) + N')' 
                        ELSE N'' 
                    END 
                    + CASE WHEN tComputedProperties.is_nullable = 0 THEN N' NOT NULL' ELSE N'' END 
                    + NCHAR(13) + NCHAR(10) 
                    AS [text()]
                FROM sys.columns AS clmns 
                INNER JOIN sys.types AS t ON t.system_type_id = clmns.system_type_id 
                LEFT JOIN sys.types ut ON ut.user_type_id = clmns.user_type_id 

                OUTER APPLY 
                    (
                        SELECT 
                             33 As bb 
                            ,COLUMNPROPERTY(clmns.object_id, clmns.name, 'ordinal')  AS ORDINAL_POSITION 
                            ,COLUMNPROPERTY(clmns.object_id, clmns.name, 'charmaxlen') AS CHARACTER_MAXIMUM_LENGTH 
                            ,COLUMNPROPERTY(clmns.object_id, clmns.name, 'octetmaxlen') AS CHARACTER_OCTET_LENGTH 
                            ,CONVERT(nvarchar(4000), OBJECT_DEFINITION(clmns.default_object_id)) AS COLUMN_DEFAULT 

                            ,clmns.is_nullable 
                            ,t.name AS DATA_TYPE

                            ,CONVERT(tinyint, 
                                CASE -- int/decimal/numeric/real/float/money  
                                    WHEN clmns.system_type_id IN (48, 52, 56, 59, 60, 62, 106, 108, 122, 127) THEN clmns.precision  
                                END
                             ) AS NUMERIC_PRECISION 

                            ,CONVERT(int, 
                                CASE -- datetime/smalldatetime  
                                    WHEN clmns.system_type_id IN (40, 41, 42, 43, 58, 61) THEN NULL  
                                    ELSE ODBCSCALE(clmns.system_type_id, clmns.scale) 
                                END
                             ) AS NUMERIC_SCALE

                            ,CONVERT(smallint, 
                                 CASE -- datetime/smalldatetime  
                                    WHEN clmns.system_type_id IN (40, 41, 42, 43, 58, 61) THEN ODBCSCALE(clmns.system_type_id, clmns.scale) 
                                 END
                            ) AS DATETIME_PRECISION 
                    ) AS tComputedProperties  

                WHERE clmns.object_id = userDefinedTableTypes.type_table_object_id 
                ORDER BY tComputedProperties.ORDINAL_POSITION 

                FOR XML PATH(''), TYPE 
            ).value('.', 'nvarchar(MAX)') AS column_definition 
    ) AS tAllColumns  

WHERE userDefinedTypes.is_user_defined = 1 
于 2019-10-29T11:52:17.230 回答
0

除了 vmvadivel 所说的(就像一个魅力!!)这是一个为你做的脚本,只需将代码转储到那里并将 sql 文件命名为 getTypesSelect.sql ,这将起作用:

    @echo off
cls

set /p SName=Server Name :
set /p UName=User Name :
set /p Pwd=Password :
set /p DbName=Database Name :

set /p choice=ARE YOU SURE TO EXECUTE SCRIPTS in %DbName% (y/n) ?

if '%choice%'=='y' goto begin
goto end

:begin
if exist addUserDefinedTypes.sql del addUserDefinedTypes.sql

@echo on

SQLCMD -S %SName% -d %DbName% -U %UName% -i "getTypesSelect.sql" -o addUserDefinedTypes.txt -P %Pwd%

rename addUserDefinedTypes.txt addUserDefinedTypes.sql

@notepad addUserDefinedTypes.sql

:end

如果您计划在不同的数据库上运行(您可能会这样做),请从上面的 sql 查询中删除以下行

SELECT 'USE ' + QUOTENAME(DB_NAME(), '[') + '
GO';
于 2013-01-10T21:59:43.387 回答