在SQL中,使用动态SQL是很常见的。有些复杂的计算,或是存储过程,代码很长,中间可能有多次执行SQL语句。而调试拼串的SQL语句却是件痛苦的事,很难看出来运行的语句是什么。所以我会经常使用print这个命令把运行前的语句打印到屏幕上,然后复制出来到另一个窗口进行调试、修改,这样就比较方便了。但是这个print命令有一些限制,在单字节符集下,最大只能打印打印8000个字符的长度,而在双字节字符集是4000个。
以下存储过程可以打印完整的信息,不受长度的限制。代码如下:
IF OBJECT_ID(N'sp_print_all') IS NOT NULL BEGIN DROP PROCEDURE sp_print_all END GO CREATE PROCEDURE sp_print_all (@dynamic_sql NVARCHAR(MAX)) AS DECLARE @start INT DECLARE @len INT SET @start = 1 SET @len = 4000 WHILE (@start < LEN(@dynamic_sql)) BEGIN PRINT SUBSTRING(@dynamic_sql, @start, @len) SET @start = @start + @len END PRINT SUBSTRING(@dynamic_sql, @start, @len) GO
code-1
还有一个存储sp_helptext,可以查询存储过程,函数等代码,使用起来也比较方便,但也有长度的限制,而且打印出来的格式跟源代码的格式有些对应不上。写了一个自定义存储过程来代替,代码如下:
IF OBJECT_ID(N'sp_helptext_user') IS NOT NULL BEGIN DROP PROCEDURE sp_helptext_user END GO CREATE PROCEDURE sp_helptext_user(@obj_name NVARCHAR(200) = '') AS SET NOCOUNT ON; DECLARE @text NVARCHAR(MAX) ,@i INT ,@text2 NVARCHAR(MAX) ,@db_name SYSNAME ,@obj_id BIGINT SET @db_name = PARSENAME(@obj_name ,3) IF @db_name IS NULL SET @db_name = DB_NAME() ELSE IF @db_name <> DB_NAME() BEGIN RAISERROR(15250 ,-1 ,-1) RETURN (1) END SET @obj_id = OBJECT_ID(@obj_name) IF @obj_id IS NULL BEGIN RAISERROR(15009 ,-1 ,-1 ,@obj_name ,@db_name) RETURN (1) END SELECT @text = [definition] FROM sys.all_sql_modules WHERE [object_id] = @obj_id WHILE LEN(@text) > 2000 BEGIN SET @i = CHARINDEX(CHAR(13) ,@text ,2000) SET @text2 = LEFT(@text ,@i) SET @text = SUBSTRING(@text ,@i + 2 ,LEN(@text)) PRINT @text2 END PRINT @text SET NOCOUNT OFF; GO
code-2
当然,查看源代码有多种方法,可以在SSMS上操作等,看个人习惯或方便操作了。
详解sp_helptext
显示规则、默认值、未加密的存储过程、用户定义函数、触发器或视图的文本。
语法
sp_helptext [ @objname = ] 'name'
参数
[@objname =] 'name'
对象的名称,将显示该对象的定义信息。对象必须在当前数据库中。name 的数据类型为 nvarchar(776),没有默认值。
返回代码值
0(成功)或 1(失败)
注释
sp_helptext 在多个行中显示用来创建对象的文本,其中每行有 Transact-SQL 定义的 255 个字符。这些定义只驻留在当前数据库的 syscomments 表的文本中。
权限
执行权限默认授予 public 角色。
示例
下面的示例显示 employee_insupd 触发器的文本,该触发器在数据库 pubs 中。
USE pubs EXEC sp_helptext 'employee_insupd'
问题内容: 我试图限制以下SQL语句。 我想做的是限制“父”行的数量。IE。如果我执行LIMIT 1,我将只收到一个费用项目,但仍获得与其相关的所有交易。 这将如何实现? 在此阶段,如果我执行LIMIT 1,我将获得一笔费用,并且只有一笔交易。 问题答案: 因此,假设我们可以排除用户表,则可以将其重写为: 现在,如果您想应用一个限制,您可以这样做: 那会做你想要的吗?显然,您需要对您的Expens
问题内容: 可以扩展Swift函数的功能吗?我想在程序中的每个print()函数上附加一个字符,而不必创建全新的函数并重命名print()的每个实例。是否可以创建将在每个打印实例后附加“ *”的扩展名? 这样做的目的是创建一种清除XCODE添加到调试器中的所有额外信息的方法。我使用打印语句来检查代码不同部分的进度和成功,但是XCODE在几秒钟内填写了数千行多余信息,这些信息很快掩盖了我的特定语句。
问题内容: 我正在查看SQL Server中的FILESTREAM属性,以在其中存储文件。我了解它将文件存储在硬盘驱动器上,并将文件指针/路径信息存储在DB中。同样,在此过程中保持事务的一致性。 对于FILESTREAM属性,似乎还存在一个限制:“ FILESTREAM数据只能存储在本地磁盘卷上”。 如果我预计自己的Web应用程序将存储200,000张每个1-2mb的图像,那么我将需要大约200g
提前感谢你的帮助
问题内容: 所有,我都有一个大型(不可避免的)动态SQL查询。由于选择标准中字段的数量,包含动态SQL的字符串的长度超过4000个字符。现在,我知道为设置了最大4000 ,但是在Server Profiler中查看了已执行的SQL语句 似乎可以正常工作(!?),对于另一个也很大的查询,它抛出与此4000极限(!?)相关的错误,它基本上会在此4000极限之后修剪所有SQL,并给我留下语法错误。尽管在
本文向大家介绍Microsoft SQL Server TOP限制,包括了Microsoft SQL Server TOP限制的使用技巧和注意事项,需要的朋友参考一下 示例 本示例将SELECT结果限制为100行。 也可以使用变量来指定行数: