设为首页 收藏本站
查看: 774|回复: 0

[经验分享] sql server查询可编程对象定义的方式对比以及整合

[复制链接]

尚未签到

发表于 2017-7-13 07:15:28 | 显示全部楼层 |阅读模式
本文目录列表:

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的选择性测试






用户定义检查约束测试:

DSC0000.png

DSC0001.png

用户定义约束测试:

DSC0002.png

DSC0003.png

系统定义存储测试:

DSC0004.png

DSC0005.png

用户定义计算列测试:







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





  • https://msdn.microsoft.com/en-us/library/ms176112.aspx




  • https://msdn.microsoft.com/en-us/library/ms175081.aspx




  • https://msdn.microsoft.com/en-us/library/ms188034.aspx




  • https://msdn.microsoft.com/en-us/library/ms184389.aspx




  • https://msdn.microsoft.com/en-us/library/ms176090.aspx




  • https://msdn.microsoft.com/en-us/library/ms188746.aspx




  • https://msdn.microsoft.com/en-us/library/ms176054.aspx




  • https://msdn.microsoft.com/en-us/library/ms187794.aspx


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-393345-1-1.html 上篇帖子: SQL Server取datetime的日期部分 下篇帖子: SQL SERVER大话存储结构(5)_SQL SERVER 事务日志解析
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表