如何格式化 OBJECT_DEFINITION 的输出,使其看起来与 sp_helptext 相同?

Mar*_*lli 7 sql-server metadata scripting sql-server-2016

object_definitionsp_helptext都返回存储过程的源代码 - 但是如何object_definitionsp_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)

在此处输入图片说明

Prz*_*min 5

我有类似的问题。首先打开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,因此我确定它没有被裁剪。


Sol*_*zky 5

更新

随着 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“特殊”字符<>&"不会分别转义为&lt;&gt;&amp;&quot;

如果执行上面所示的 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 和无限制)。然后单击“确定”按钮。


Erw*_*ema 1

对于 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)