这个问题很老了,但互联网上没有其他来源,只是说明如何使用 SSMS 脚本。
作为 Alex Castillo,我还对 SSMS 脚本程序进行了概要分析和逆向工程,然后为了方便起见将它们全部组合到一个 T-SQL 查询中。这是我得到的:
SELECT
'DROP ' +
CASE o.[type]
WHEN 'FT' THEN 'FUNCTION'
WHEN 'FS' THEN 'FUNCTION'
WHEN 'PC' THEN 'PROCEDURE'
END + ' [' + SCHEMA_NAME(ao.[schema_id]) + '].[' + o.[name] + '];' AS [drop_statement]
,'CREATE ' +
CASE o.[type]
WHEN 'FT' THEN 'FUNCTION'
WHEN 'FS' THEN 'FUNCTION'
WHEN 'PC' THEN 'PROCEDURE'
END + ' [' + SCHEMA_NAME(ao.[schema_id]) + '].[' + o.[name] + '] ' +
CASE o.[type]
WHEN 'FT' THEN '(' + COALESCE(inp.[params_def], '') + ') RETURNS TABLE (' + oc.[columns_def] + ')'
WHEN 'FS' THEN '(' + COALESCE(inp.[params_def], '') + ') RETURNS ' + t.[name] + CASE WHEN t.[name] IN ('char', 'varchar', 'binary', 'varbinary', 'nchar', 'nvarchar', 'datetime2') THEN '(' + CASE WHEN t.[name] IN ('nchar', 'nvarchar') AND aop.[max_length] != -1 THEN CAST(aop.[max_length] / 2 AS [varchar]) WHEN t.[name] IN ('nvarchar') AND aop.[max_length] = -1 THEN 'MAX' WHEN t.[name] = 'datetime2' THEN CAST(aop.[scale] AS [varchar]) ELSE CAST(aop.[max_length] AS [varchar]) END + ')' WHEN t.[name] IN ('numeric', 'decimal') THEN '(' + CAST(aop.[precision] AS [varchar]) + ', ' + CAST(aop.[scale] AS [varchar]) + ')' ELSE '' END
WHEN 'PC' THEN COALESCE(inp.[params_def], '')
END + ' WITH EXECUTE AS CALLER AS ' +
' EXTERNAL NAME [' + a.[name] COLLATE SQL_Latin1_General_CP1_CI_AS + '].[' + am.[assembly_class] + '].[' + am.[assembly_method] + '];' AS [create_statement]
FROM sys.assemblies a WITH(NOLOCK)
JOIN sys.assembly_modules am WITH(NOLOCK) ON a.[assembly_id] = am.[assembly_id]
JOIN sys.objects o WITH(NOLOCK) ON am.[object_id] = o.[object_id]
LEFT JOIN sys.all_parameters AS aop WITH(NOLOCK) ON aop.[object_id] = am.[object_id] AND aop.[is_output] = 1
LEFT JOIN sys.types AS t WITH(NOLOCK) ON (t.[user_type_id] = aop.[system_type_id] AND t.[user_type_id] = t.[system_type_id]) OR ((t.[system_type_id] = aop.[system_type_id]) AND (t.[user_type_id] = aop.[user_type_id]) AND (t.[is_user_defined] = 0) AND (t.[is_assembly_type] = 1))
JOIN sys.all_objects ao WITH(NOLOCK) ON o.[object_id] = ao.[object_id]
OUTER APPLY (
SELECT
SUBSTRING((SELECT
', ' + aip.[name] + ' ' + it.[name] + CASE WHEN it.[name] IN ('char', 'varchar', 'binary', 'varbinary', 'nchar', 'nvarchar', 'datetime2') THEN '(' + CASE WHEN it.[name] IN ('nchar', 'nvarchar') AND aip.[max_length] != -1 THEN CAST(aip.[max_length] / 2 AS [varchar]) WHEN it.[name] IN ('nvarchar') AND aip.[max_length] = -1 THEN 'MAX' WHEN it.[name] = 'datetime2' THEN CAST(aip.[scale] AS [varchar]) ELSE CAST(aip.[max_length] AS [varchar]) END + ')' WHEN it.[name] IN ('numeric', 'decimal') THEN '(' + CAST(aip.[precision] AS [varchar]) + ', ' + CAST(aip.[scale] AS [varchar]) + ')' ELSE '' END AS [params_def]
FROM sys.all_parameters AS aip WITH(NOLOCK)
LEFT JOIN sys.types AS it WITH(NOLOCK) ON (it.[user_type_id] = aip.[system_type_id] AND it.[user_type_id] = it.[system_type_id]) OR ((it.[system_type_id] = aip.[system_type_id]) AND (it.[user_type_id] = aip.[user_type_id]) AND (it.[is_user_defined] = 0) AND (it.[is_assembly_type] = 1))
WHERE 1 = 1
AND aip.[is_output] = 0
AND aip.[object_id] = am.[object_id]
ORDER BY aip.[parameter_id]
FOR XML PATH, TYPE).value('.[1]', 'nvarchar(MAX)'), 3, 2147483647) AS [params_def]
) AS inp
OUTER APPLY (
SELECT
SUBSTRING((SELECT
', [' + ac.[name] + '] ' + ct.[name] + CASE WHEN ct.[name] IN ('char', 'varchar', 'binary', 'varbinary', 'nchar', 'nvarchar', 'datetime2') THEN '(' + CASE WHEN ct.[name] IN ('nchar', 'nvarchar') AND ac.[max_length] != -1 THEN CAST(ac.[max_length] / 2 AS [varchar]) WHEN ct.[name] IN ('nvarchar') AND ac.[max_length] = -1 THEN 'MAX' WHEN ct.[name] = 'datetime2' THEN CAST(ac.[scale] AS [varchar]) ELSE CAST(ac.[max_length] AS [varchar]) END + ')' WHEN ct.[name] IN ('numeric', 'decimal') THEN '(' + CAST(ac.[precision] AS [varchar]) + ', ' + CAST(ac.[scale] AS [varchar]) + ')' ELSE '' END + CASE ac.[is_nullable] WHEN 0 THEN ' NOT' ELSE '' END + ' NULL'
FROM sys.all_columns ac
LEFT JOIN sys.types AS ct WITH(NOLOCK) ON (ct.[user_type_id] = ac.[system_type_id] AND ct.[user_type_id] = ct.[system_type_id]) OR ((ct.[system_type_id] = ac.[system_type_id]) AND (ct.[user_type_id] = ac.[user_type_id]) AND (ct.[is_user_defined] = 0) AND (ct.[is_assembly_type] = 1))
WHERE 1 = 1
AND ac.[object_id] = am.[object_id]
ORDER BY ac.[column_id]
FOR XML PATH, TYPE).value('.[1]', 'nvarchar(MAX)'), 3, 2147483647) AS [columns_def]
) AS oc
WHERE 1 = 1
AND a.[name] = <'your assembly name'>
AND SCHEMA_NAME(ao.[schema_id]) = <'your schema name'>
只需执行查询并将相应输出行中的值复制粘贴到新的查询窗口中并执行。该查询涵盖了很多方面,但不包括用户定义类型(如果您的 SQL CLR 例程中有任何类型)。调整起来并不难,我只是不在我的代码中使用 SQL CLR UDT。我希望有人会发现它有用。