Mar*_*lli 7 sql-server metadata scripting sql-server-2016
object_definition和sp_helptext都返回存储过程的源代码 - 但是如何object_definition
像sp_helptext
当前那样使用和获取包含换行符的源代码?
例如在下面的代码中,我创建了一个存储过程:
if OBJECT_ID('usp_radhe') is not null
drop procedure usp_radhe
go
-- this procedure is just a test
-- it just returns a date in the past
-- how will I get its source code?
create procedure usp_radhe as
begin
select dateadd(dd,-31,GETDATE())
end
Run Code Online (Sandbox Code Playgroud)
使用sp_helptext我可以很好地查看源代码:
sp_helptext 'usp_radhe'
Run Code Online (Sandbox Code Playgroud)
使用object_definition我在一行中获得源代码,这对我不利:
select OBJECT_DEFINITION(object_id('usp_radhe'))
Run Code Online (Sandbox Code Playgroud)
我有类似的问题。首先打开SSMS的这个选项 - 默认情况下它是关闭的:
SSMS/Tools/Options/Query results/SQL Server/Results to grid/Retain CR/LF on copy or save
Run Code Online (Sandbox Code Playgroud)
关闭 SSMS,然后再次运行它以使其工作。
我使用这个查询来获取对象定义的全文:
create view v_get_text_of_objects as
select top 100000
[name]
, definition = replace(replace(object_definition(object_id),'create view','alter view'),'create proc','alter proc')
, len = len(object_definition(object_id))
, type
, type_desc
, create_date
, modify_date
from sys.objects
where object_definition(object_id) like '%your text to find in sp%'
order by type, create_date desc
Run Code Online (Sandbox Code Playgroud)
我喜欢显示 sp 文本的 LEN,因此我确定它没有被裁剪。
随着 2019 年 7 月 25 日发布SSMS 18.2,提供了一个新选项。该选项本身已经存在很长时间了,但随着此版本中所做的更改,它变得可以用于此处请求的目的。
具体的变化是增加使用“结果到文本”时检索的字符数(增加 8 倍)。文件指出(强调我的):
允许显示更多数据(结果到文本)并存储在单元格中(结果到网格)。SSMS 现在允许两者最多 2M 个字符(分别从 256 K和 64 K 增加)。这也解决了用户无法从网格单元格中获取超过 43680 个字符的问题。
现在,以下内容按预期显示在“结果到文本”中:
SET NOCOUNT ON; SELECT OBJECT_DEFINITION(OBJECT_ID(N'sys.sp_helptext'));
Run Code Online (Sandbox Code Playgroud)
默认情况下,结果是“列对齐”和“包括列标题”。通过这种选项组合,列标题和结果之间会使用一条破折号。问题在于,如果列对齐,破折号会扩展该列可能检索的全部内容,这可能是 2,097,152 个破折号(即 2 MB 的价值)。SSMS 不喜欢超长的行,并且在向上滚动以查看该行时会冻结一秒钟。
您可以通过更改上述两个选项中的一个(或两个)来摆脱该行:取消选中“在结果集中包含列标题”和/或将“输出格式”设置为“逗号分隔”。如果您希望这些更改成为新的默认值(即下次记住),那么您需要通过转到工具 -> 选项 -> -> 查询结果 -> SQL Server -> 结果到文本来进行更改。如果您希望更改只是暂时的,请右键单击查询编辑器选项卡/窗口,选择“查询选项...”,然后转到“结果”->“文本”。
我不记得“每列中显示的最大字符数”的默认值是什么,但如果它不是 2097152,那么我建议更改新的默认值(即通过“工具”菜单)。
如果代码由于超过 2,097,152 字节(大多数情况下为字符)而被截断,则 a) 哎呀!,b) 使用下面描述的 XML 方法。
如果您不介意在最顶部和最底部应忽略多余的行,则可以使用以下命令将全文显示为文本而不是结果集:
SELECT 1 AS [Tag], 0 AS [Parent], NCHAR(13) + NCHAR(10) +
OBJECT_DEFINITION(OBJECT_ID(N'sys.sp_helptext')) AS [Code!1!!CDATA]
FOR XML EXPLICIT;
Run Code Online (Sandbox Code Playgroud)
从 SQL Server 2005 开始,它在所有版本中的工作方式都是相同的(好吧,我认为它可以在 2005、2017 和 2019 CTP 2.2 上工作)。我使用了“CDATA”部分(该部分又需要使用 的EXPLICIT
模式FOR XML
),以便 XML“特殊”字符<
、>
、&
和"
不会分别转义为<
、>
、&
和"
。
如果执行上面所示的 T-SQL,您将返回 XML 值的一行一列结果集。单击带下划线的 XML 值,它将在一个新选项卡中打开,显示完整的、格式正确的文本(以及第一行<Code><![CDATA[
和最后一行]]></Code>
):
SELECT 1 AS [Tag], 0 AS [Parent], NCHAR(13) + NCHAR(10) +
OBJECT_DEFINITION(OBJECT_ID(N'sys.sp_helptext')) AS [Code!1!!CDATA]
FOR XML EXPLICIT;
Run Code Online (Sandbox Code Playgroud)
根据您“显示”的项目的大小,您可能需要增加 SSMS 设置以了解其下拉的 XML 数据量(否则您可能会看到截断的结果)。去:
工具| 选项| 查询结果 | SQL Server | 结果到网格
然后,在“检索的最大字符数”下,将“XML 数据”设置为(选项为:1 MB、2 MB、5 MB 和无限制)。然后单击“确定”按钮。
对于 MSSQL Server 2012,您可以使用递归函数。例如:
/* Recursive function, to split an object (like stored procedure) into individual lines, with line number */
declare @delimiter nvarchar(2) = char(10);
declare @objectName sysname = 'dbo.MyObject'
;with CTE as (
select
0 as linenr
, object_definition( object_id(@objectName)) as def
, convert(nvarchar(max), N'') as line
union all
select
linenr + 1
, substring(def, charindex(@delimiter, def) + len(@delimiter), len(def) - (charindex(@delimiter, def)))
, left(def, charindex(@delimiter, def)) as line
from CTE
where charindex(@delimiter, def) <> 0
)
select linenr, line
from CTE
where linenr >= 1
OPTION (MAXRECURSION 0);
Run Code Online (Sandbox Code Playgroud)