【问题标题】:SQL Server: How to list all CLR functions/procedures/objects for assemblySQL Server:如何列出所有 CLR 函数/过程/对象以进行汇编
【发布时间】:2011-03-10 11:47:52
【问题描述】:

问题:在 SQL Server 2005 中,如何列出所有使用程序集 xy(例如 MyFirstUdp)的 SQL CLR 函数/过程?

例如一个为查询参数 MyFirstUdp 列出 HelloWorld 的函数

CREATE PROCEDURE HelloWorld
AS EXTERNAL NAME MyFirstUdp.[SQL_CLRdll.MySQLclass].HelloWorld
GO

我跑了之后

CREATE ASSEMBLY MyFirstUdp FROM 'C:\Users\username\Documents\Visual Studio 2005\Projects\SQL_CLRdll\SQL_CLRdll\bin\Debug\SQL_CLRdll.dll

我可以列出所有程序集和所有功能/程序, 但我似乎无法将程序集与功能/程序相关联...

【问题讨论】:

    标签: sql-server sql-server-2005 sqlclr


    【解决方案1】:

    查看sys.assembly_modules 视图:

    select * from sys.assembly_modules
    

    这应该列出所有函数和定义它们的程序集。请参阅Books Online help page 了解它。

    为每个函数返回一行, 定义的过程或触发器 通过公共语言运行时 (CLR) 组装。

    【讨论】:

    • 仅供参考:用户定义类型 (UDT) 位于 sys.assembly_types 而不是 sys.assembly_modules
    【解决方案2】:

    我使用以下 SQL:

    SELECT      so.name AS [ObjectName],
                so.[type],
                SCHEMA_NAME(so.[schema_id]) AS [SchemaName],
                asmbly.name AS [AssemblyName],
                asmbly.permission_set_desc,
                am.assembly_class, 
                am.assembly_method
    FROM        sys.assembly_modules am
    INNER JOIN  sys.assemblies asmbly
            ON  asmbly.assembly_id = am.assembly_id
            AND asmbly.is_user_defined = 1 -- if using SQL Server 2008 or newer
    --      AND asmbly.name NOT LIKE 'Microsoft%' -- if using SQL Server 2005
    INNER JOIN  sys.objects so
            ON  so.[object_id] = am.[object_id]
    UNION ALL
    SELECT      at.name AS [ObjectName],
                'UDT' AS [type],
                SCHEMA_NAME(at.[schema_id]) AS [SchemaName], 
                asmbly.name AS [AssemblyName],
                asmbly.permission_set_desc,
                at.assembly_class,
                NULL AS [assembly_method]
    FROM        sys.assembly_types at
    INNER JOIN  sys.assemblies asmbly
            ON  asmbly.assembly_id = at.assembly_id
            AND asmbly.is_user_defined = 1 -- if using SQL Server 2008 or newer
    --      AND asmbly.name NOT LIKE 'Microsoft%' -- if using SQL Server 2005
    ORDER BY    [AssemblyName], [type], [ObjectName]
    

    请注意:

    1. 用户定义类型 (UDT) 位于:sys.assembly_types

    2. 您只能列出已在CREATE { PROCEDURE | FUNCTION | AGGREGATE | TRIGGER | TYPE } 语句中使用的 SQLCLR 引用。您找不到尚未被​​ CREATE 引用的 SQLCLR 方法。意思是,你不能说:“给我这个程序集中的方法列表,我可以为其创建 T-SQL 对象”。

    有关使用 SQLCLR 的更多信息,请访问:SQLCLR Info

    【讨论】:

      【解决方案3】:

      这是在sqlhint.com 上找到的脚本:

      SELECT
              SCHEMA_NAME(O.schema_id) AS [Schema], O.name,
              A.name AS assembly_name, AM.assembly_class, 
              AM.assembly_method,
              A.permission_set_desc,
              O.[type_desc]
      FROM
              sys.assembly_modules AM
              INNER JOIN sys.assemblies A ON A.assembly_id = AM.assembly_id
              INNER JOIN sys.objects O ON O.object_id = AM.object_id
      ORDER BY
              A.name, AM.assembly_class
      

      此外,您还可以选择查看CLR object is used 所在的所有位置。

      【讨论】:

        【解决方案4】:

        这是 srutzky 查询(上图)的概括,它使用游标遍历服务器上的所有数据库。很抱歉格式化,但如果您必须搜索您继承的 500 个 DB,这很方便。

        set nocount on
        declare @cmd nvarchar(4000)
        
        declare curDBs cursor read_only for 
            SELECT name FROM MASTER.sys.sysdatabases
        declare @NameDB nvarchar(100)
        
        create table #tmpResults (
              DatabaseName nvarchar(128)
            , ObjectName nvarchar(128)
            , ObjectType char(2)
            , SchemaName nvarchar(128)
            , AssemblyName nvarchar(128)
            , PermissionSet nvarchar(60)                        
            , AssemblyClass nvarchar(128)
            , AssemblyMethod nvarchar(128));
        
        open curDBs; while (1=1)
            begin
                fetch next from curDBs into @NameDB
                if @@fetch_status <> 0 break
                set @cmd = N'
                    USE [' + @NameDB + N'];
                    begin try
                    insert into #tmpResults
                        SELECT      ''' + @NameDB + N''',
                                    so.name AS [ObjectName],
                                    so.[type],
                                    SCHEMA_NAME(so.[schema_id]) AS [SchemaName],
                                    asy.name AS [AssemblyName],
                                    asy.permission_set_desc,
                                    am.assembly_class,  
                                    am.assembly_method  
                            FROM sys.assembly_modules am
                                INNER JOIN  sys.assemblies asy
                                    ON  asy.assembly_id = am.assembly_id
                                        AND asy.is_user_defined = 1 
                                INNER JOIN  sys.objects so
                                    ON  so.[object_id] = am.[object_id]
                    UNION ALL
                        SELECT      ''' + @NameDB + N''',
                                    at.name AS [ObjectName],
                                    ''UDT'' AS [type],
                                    SCHEMA_NAME(at.[schema_id]) AS [SchemaName], 
                                    asy.name AS [AssemblyName],
                                    asy.permission_set_desc,
                                    at.assembly_class,
                                    NULL AS [assembly_method]
                            FROM  sys.assembly_types at
                                INNER JOIN  sys.assemblies asy
                                    ON  asy.assembly_id = at.assembly_id
                                        AND asy.is_user_defined = 1 
                            ORDER BY    [AssemblyName], [type], [ObjectName]
                        print ''' + @NameDB + N'  ' +  cast(@@rowcount as nvarchar) + N'''
                    end try
                    begin catch
                        print ''Error processing ' + @NameDB  + '''
                    end catch
                '
                --print @cmd
                EXEC sp_executesql @cmd
            end
        close curDBs; deallocate curDBs
        
        select * from #tmpResults
        drop table #tmpResults
        

        【讨论】:

        • 完美。正是我需要的。
        【解决方案5】:

        或者你可以使用

        SELECT * FROM sys.dm_clr_appdomains;
        

        它返回程序集列表以及它们存储在哪个数据库中。

        【讨论】:

          【解决方案6】:
          SELECT 
                modules.assembly_class AS AssemblyClass,
                modules.assembly_method AS MethodName,
                obj.type_desc AS MethodType,
                files.name AS FilePath,
                assemb.name AS AssemblyName,
                assemb.clr_name,
                assemb.create_date,
                assemb.modify_date,
                assemb.permission_set_desc
                --,*
          FROM   
               sys.assembly_modules AS modules
               JOIN sys.assembly_files AS files ON files.assembly_id = modules.assembly_id
               JOIN sys.assemblies AS assemb ON assemb.assembly_id = modules.assembly_id
               JOIN sys.objects AS obj ON obj.object_id = modules.object_id
          

          【讨论】:

            猜你喜欢
            • 2017-11-06
            • 2018-04-29
            • 1970-01-01
            • 1970-01-01
            • 2023-03-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多