zoukankan      html  css  js  c++  java
  • sql server查询可编程对象定义的方式对比以及整合

    1、sql server查看可编程对象定义的方式对比
     
    上一篇博文重构sql server的sys.helptext存储中写了sys.helptext的限制和输出格式每行自带char(13)和char(10)这两个字符。为了将可编程对象定义查询方式研究透彻,以下表格列出了查询可编程对象定义的不同方式的却别和对可编程对象定义查看的支持程度。
    对象类型描述 对象类型简写
    sys.sp_helptext
    sys.sql_modules
    sys.system_sql_modules
    sys.all_sql_modules
    object_definition
    CHECK_CONSTRAINT
    C
    支持 不支持
    不支持
    不支持
    支持
    DEFAULT_CONSTRAINT(contraint,stand-alone)
    D
    支持 支持
    不支持
    支持
    支持
    SQL_SCALAR_FUNCTION
    FN
    支持
    支持
    支持
    支持
    支持
    SQL_INLINE_TABLE_VALUED_FUNCTION
    IF
    支持
    支持
    支持
    支持
    支持
    SQL_STORED_PROCEDURE
    P
    支持
    支持 支持
    支持
    支持
    RULE(old-style,stand-alone)
    R
    支持
    支持
    不支持
    支持
    支持
    REPLICATION FILTER PROCEDURE
    RF
    支持
    支持
    支持
    支持
    支持
    SQL_TABLE_VALUED_FUNCTION
    TF
    支持
    支持
    支持
    支持
    支持
    SQL_TRIGGER
    TR
    支持(除数据库DDL触发器和服务器触发器外)
    支持(除服务器触发器外)
    不支持
    支持(除服务器触发器外)
    支持(除服务器触发器外)
    USER_TABLE
    U
    computed_column
    支持
    不支持
    不支持
    不支持
    不支持
    VIEW
    V
    支持
    支持
    支持
    支持
    支持

    注意:

    1、带有_modules的是系统提供的目录视图类。
    2、sys.sql_modules包括所有用户定义的可编程对象的,当然也不支持计算列和服务器触发器的。
    3、sys.system_sql_modules不支持系统定义的类型为C、D、R、TR的对象。
    4、sys.all_sql_modules就是sys.sql_modules和sys.system_sql_modules这个视图的并集结果的,当然也不支持系统定义的类型为C、D、R、TR类型的对象。
    5、sys.sp_helptext虽然支持以上表格中除数据库DDL触发器和服务器触发器之外的可编程对象,但是其输出格式有限制:1、每行最多225双字节字符号,这样有可能造成输出将一个标识符分割为前后两行的。
    6、object_definition函数支持以上表格中除服务器除触发器和计算列外的可以变成对象。
    7、sys.sp_helpttext和object_definition有个功能的限制:1、在SSMS客户端中如果使用字符串类型变量接收返回的而结果,有可能受制于SSMS客户端针对字符串变量的最大限制(sql server 2012中的最大限制是43679双字节字符长度)不能全部输出到客户端,这个缺点可以从通过程序编码实现得到完美体现。
     
    2、整合实现所有可编程对象定义的查看功能的存储dbo.usp_helptext2
     
    通过以上几种方式的对比,我们可以看到那个方式都不能将以上表格中列出的对象类型的定义全部都满足,为了解决这个不足,我们将整合这些功能来封装在一个存储(其名称为dbo.usp_helptext2)。需要注意的一点就是服务器触发器本来不是某个数据库中的对象的,服务器触发器和数据库中可编程对象分开更好的理解,也能简单些的,不过为了查询的便利性,我们这次封装的存储实现服务器触发器定义查看。
     
    功能整合的存储过程T-SQL代码如下:
    IF OBJECT_ID(N'[dbo].[usp_helptext2]', 'P') IS NOT NULL
    BEGIN
        DROP PROCEDURE [dbo].[usp_helptext2];
    END
    GO
     
    --==================================
    -- 功能: 查看可编程对象定义
    -- 说明: 支持用户定义类型,可以运行于SQL Server 2005+
    -- 创建: yyyy-MM-dd hh:mm-hh:mm XXX 创建内容描述
    -- 修改: yyyy-MM-dd hh:mm-hh:mm XXX 修改内容描述
    --==================================
    CREATE PROCEDURE [dbo].[usp_helptext2]
    (
         @nvcObjectName AS NVARCHAR(776)                    -- 对象名称,可以支持的对象类型为(C、D、FN、IF、P、R、RF、TF、TR、U、V)
        ,@nvcComputedColumnName AS NVARCHAR(128) = NULL        -- 计算列名称(如果@nvcObjectName的对象类型为U,则该参数表示计算列名称)
    )
    AS
    BEGIN
        SET NOCOUNT ON;
     
        SET @nvcObjectName = ISNULL(@nvcObjectName, N'');
        IF (@nvcObjectName = N'')
        BEGIN
            RAISERROR(16902, -1, -1,N'usp_helptext2', N'@nvcObjectName');
            RETURN(1);
        END
     
        SET @nvcComputedColumnName = ISNULL(@nvcComputedColumnName, N'');
     
        DECLARE @tntRetVal AS TINYINT;
        SET @tntRetVal = 0;
     
        DECLARE @tblObjDef AS TABLE (
            [Text] NVARCHAR(1000) NULL
        );
     
        DECLARE
             @intObjectID AS INT
            ,@chaType AS CHAR(2)
            ,@nvcText AS NVARCHAR(MAX);
        SELECT
             @intObjectID = 0
            ,@chaType = ''
            ,@nvcText = N'';
        SELECT
             @intObjectID = [object_id]
            ,@chaType = [type]        
        FROM [sys].[all_objects]
        WHERE 
            [type] IN ('C', 'D', 'FN', 'IF', 'P', 'R', 'RF', 'TF', 'TR', 'U', 'V')
            AND [name] = PARSENAME(@nvcObjectName, 1);
     
        IF (@nvcComputedColumnName > N'')    -- 获取计算列定义
        BEGIN
            IF (@chaType NOT IN ('S', 'U', 'TF'))
            BEGIN
                RAISERROR(15218, -1, -1, @nvcObjectName);
                RETURN(1);
            END
     
            INSERT INTO @tblObjDef ([Text])        
            EXEC [sys].[sp_helptext]
                 @objname = @nvcObjectName                -- nvarchar(776)
                ,@columnname = @nvcComputedColumnName    -- sysname
     
            IF(@@ROWCOUNT = 0)
            BEGIN
                SET @tntRetVal = 1;
            END
     
            SELECT 
                @nvcText = ISNULL([Text], N'')
            FROM @tblObjDef;            
        END
        ELSE IF (@intObjectID <> 0)    -- 获取除计算列和服务器触发器以外的所有对象类型的定义
        BEGIN
            SET @nvcText = OBJECT_DEFINITION(@intObjectID);
     
            IF(@@ROWCOUNT = 0)
            BEGIN
                SET @tntRetVal = 1;
            END
        END
        ELSE IF (@intObjectID = 0)    -- 尝试获取服务器触发器定义
        BEGIN
            SELECT 
                @nvcText = T1.[definition]
            FROM [sys].[server_sql_modules] AS T1
                INNER JOIN [sys].[server_triggers] AS T2
                    ON [T1].[object_id] = [T2].[object_id]
            WHERE T2.[name] = @nvcObjectName;
     
            IF(@@ROWCOUNT = 0)
            BEGIN
                SET @tntRetVal = 1;
            END
        END
     
        SELECT 
            @nvcText AS [Text];
     
        RETURN(@tntRetVal);
    END
    GO
     
    以上存储dbo.usp_helptext2可以完全实现以上表格的所有可编程对象定义查看,不论是系统定义的还是用户定义的,前提是以上表格中的可编程对象类型定义。当然也存在缺点就是可编程对象定义输出到SSMS客户端超过最大限制(SQL Server 2012环境中的时43679双字节字符长度)就要出现截断,这个缺点可以通过代码编程来完美解决这个缺点。
     
    3、dbo.helptext2的选择性测试
     
    用户定义检查约束测试:
    用户定义约束测试:
    系统定义存储测试:
    用户定义计算列测试:
     
    数据库DDL触发器测试
    服务器触发器测试:
    其他对象类型的测试不在全部列举。
     
    4、总结语
     
    在这次的学习和研究,sql server系统自带的视图以及存储过程针对可编程对象的实现很很完善的,不过叶分散在不同的地方,这次整合也就是将分散在不同地方的聚合在一起提供统一入口来处理。如果不想查看计算列和服务器触发器的定义以外的所有可编程对象类型的定义,建议使用object_definition函数,该函数几乎提供了很完善的功能。这次学习也发现数据库DDL触发器在sys.object是无法查看到的,需要在sys.triggers或sys.all_objects目录视图中查看到,这个也在object_id函数做了限制的。由于服务器触发器本身属于服务器的,这个sql server团队本身也是用了系统表sys.sysschobjs、sys.syspalnames 、sys.syspalvalues,虽然sys.all_objects也是用了系统表sys.syscheobjs,但是却在sys.all_objects中无法查询到的,也在object_id函数中做了限制,只能在sys.server_triggers查询到,这从逻辑上进行了分离,也符合服务器触发器的归属性质。
     
    希望这个整合的查看可编程对象定义的存储,可以帮助到需要的人。继续精进,继续探究sql server。
     
    5、参考清单列表
  • 相关阅读:
    mvc
    拦截器
    使用HttpWebRequest和HtmlAgilityPack抓取网页(拒绝乱码,拒绝正则表达式)
    编译和解释的区别是什么?
    15 个最佳的 jQuery 表格插件
    编程小白必备——主流语言C语言知识点
    妹子找你修电脑,按照这几步操作,你就是黑客大佬!
    网络管理监视很重要!学编程的你知道哪些不错的网络监控工具?2020 最好的Linux网络监控工具分享给你
    为什么程序员要跳槽,钱并非第一位
    代码编写行为准则,编码是一个认真思考的过程,如何有效提高代码的可读性?
  • 原文地址:https://www.cnblogs.com/dzy863/p/5913682.html
Copyright © 2011-2022 走看看