sql server查询可编程对象定义的方式对比以及整合

本文目录列表:

1、sql server查看可编程对象定义的方式对比

2、整合实现所有可编程对象定义的查看功能的存储dbo.usp_helptext2

3、dbo.helptext2的选择性测试

4、总结语

5、参考清单列表

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、参考清单列表

时间: 2024-08-08 12:17:55

sql server查询可编程对象定义的方式对比以及整合的相关文章

用SQL Server查询所有数据并显示

利用SQL Server查询数据,并把所有数据显示在页面上. <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@page import="jdbc.sqlServer"%> <%@page import="java.sql.Connection"%> <%@page imp

如何在SQL Server查询语句(Select)中检索存储过程(Store Procedure)的结果集?

如何在SQL Server查询语句(Select)中检索存储过程(Store Procedure)的结果集?(2006-12-14 09:25:36) 与这个问题具有相同性质的其他描述还包括:如何在SQL Server存储过程中获取另一存储过程的执行结果记录集?如何在存储过程中检索动态SQL语句的执行结果?如何实现类似SELECT * FROM (EXEC procedure_name @parameters_var) AS datasource ... 的功能?procedure_

SQL Server 查询性能优化 相关文章

来自: SQL Server 查询性能优化——堆表.碎片与索引(一) SQL Server 查询性能优化——堆表.碎片与索引(二) SQL Server 查询性能优化——覆盖索引(一) SQL Server 查询性能优化——覆盖索引(二) SQL Server 查询性能优化——创建索引原则(一) SQL Server 查询性能优化——创建索引原则(二) SQL Server 查询性能优化——索引与SARG(一) SQL Server 查询性能优化——索引与SARG(二) SQL Server 查

Sql Server查询性能优化之走出索引的误区

据了解绝大多数开发人员对于索引的理解都是一知半解,局限于大多数日常工作没有机会.也什么没有必要去关心.了解索引,实在哪天某个查询太慢了找到查询条件建个索引就ok,哪天又有个查询慢了,再建立个索引就是,或者干脆把整个查询SQL直接发给DBA,让DBA直接帮忙优化了,所以造成的状况就是开发人员对于索引的理解.认识很局限,以下就把我个人对于索引的理解及浅薄认识和大家分享下,希望能解除一些大家的疑惑,一起走出索引的误区 误区1.在表上建立了索引,在查询时用到了索引的列,索引就一定会生效 首先明确下这样的

SQL Server 查询分析器提供的所有键盘快捷方式(转)

下表列出 SQL Server 查询分析器提供的所有键盘快捷方式. 活动 快捷方式 书签:清除所有书签. CTRL-SHIFT-F2 书签:插入或删除书签(切换). CTRL+F2 书签:移动到下一个书签. F2 功能键 书签:移动到上一个书签. SHIFT+F2 取消查询. ALT+BREAK 连接:连接. CTRL+O 连接:断开连接. CTRL+F4 连接:断开连接并关闭子窗口. CTRL+F4 数据库对象信息. ALT+F1 编辑:清除活动的编辑器窗格. CTRL+SHIFT+DEL 编

SQL Server 查询锁表和接锁表

SQL Server 查询锁表 select request_session_id spid,OBJECT_NAME(resource_associated_entity_id) as tableName ,* from sys.dm_tran_locks where resource_type='OBJECT' and OBJECT_NAME(resource_associated_entity_id) is not null SQL Server 解锁表 declare @spid int

使用WinDbg调试SQL Server查询

上一篇文章我给你介绍了WinDbg的入门,还有你如何能附加到SQL Server.今天的文章,我们继续往前一步,我会向你展示使用WinDbg调试SQL Server查询需要的步骤.听起来很有意思?我们开始吧! 假设在你面前有个简单的查询,你想在WinDbg里调试那个特定的查询.听起来很简单,但一旦你开始考虑这个问题,就会碰到很多问题: 在我特定执行的查询上,我如何标识出正确的工作者线程? 在sqlservr.exe里,我应该在哪里设置断点? 我们来具体讲解下这2个问题. 标识出正确的工作者线程

SET STATISTICS IO和SET STATISTICS TIME 在SQL Server查询性能优化中的作用

原文:SET STATISTICS IO和SET STATISTICS TIME 在SQL Server查询性能优化中的作用 近段时间以来,一直在探究SQL Server查询性能的问题,当然也漫无目的的查找了很多资料,也从网上的大神们的文章中学到了很多,在这里,向各位大神致敬.正是受大神们无私奉献精神的影响,所以小弟也作为回报,分享一下关于SET STATISTICS IO和SET STATISTICS TIME这两条T_SQL命令,在查询优化性能中的作用. 首先我想说明一下这篇文章不是关于如何

如何找出你性能最差的SQL Server查询

原文:如何找出你性能最差的SQL Server查询 我经常会被反复问到这样的问题:”我有一个性能很差的SQL Server.我如何找出最差性能的查询?“.因此在今天的文章里一些让你很容易找到问题答案的信息和向导. 问SQL Server! SQL Server的一个优点是它本身能回答几乎所有你的问题,因为SQL Server在各个DMV和DMF里存储了很多故障排除信息.另一方面这也是个缺点,因为你必须知道各个DMV/DMF,还有如何把它们解释和关联在一起. 至于你的最差性能SQL Server查