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
sp_helptextを使用すると、ソースコードの見栄えが良くなります。
sp_helptext 'usp_radhe'
usingobject_definitionソースコードを1行で取得しますが、それは私には適していません。
select OBJECT_DEFINITION(object_id('usp_radhe'))
SQL Server 2016を使用しているため、STRING_SPLIT
と Aaron Bertrandからのトリック でキャリッジリターン/ラインフィードで分割します。
DECLARE
@olddelim nvarchar(32) = char(13) + Char(10),
@newdelim nchar(1) = NCHAR(9999); -- pencil (✏)
SELECT * FROM STRING_SPLIT(REPLACE(OBJECT_DEFINITION(object_id('usp_radhe')), @olddelim, @newdelim), @newdelim);
同様の問題がありました。最初にSSMSのこのオプションをオンにします-デフォルトではオフになっています。
SSMS/Tools/Options/Query results/SQL Server/Results to grid/Retain CR/LF on copy or save
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
SpテキストのLENを表示したいので、トリミングされません。
sp_helptext 'sp_helptext'
--If carriage return found
IF @CurrentPos != 0
begin
/*If new value for @Lines length will be > then the
**set length then insert current contents of @line
**and proceed.
*/
while (isnull(LEN(@Line),0) + @BlankSpaceAdded + @CurrentPos-@BasePos + @LFCR) > @DefinedLength
begin
select @AddOnLen = @DefinedLength-(isnull(LEN(@Line),0) + @BlankSpaceAdded)
INSERT #CommentText VALUES
( @LineId,
isnull(@Line, N'') + isnull(SUBSTRING(@SyscomText, @BasePos, @AddOnLen), N''))
select @Line = NULL, @LineId = @LineId + 1,
@BasePos = @BasePos + @AddOnLen, @BlankSpaceAdded = 0
end
select @Line = isnull(@Line, N'') + isnull(SUBSTRING(@SyscomText, @BasePos, @CurrentPos-@BasePos + @LFCR), N'')
select @BasePos = @CurrentPos+2
INSERT #CommentText VALUES( @LineId, @Line )
select @LineId = @LineId + 1
select @Line = NULL
end
K、これがsp_helptextが行う方法です。結果の折り返しは、object_definitionによって返されたCRLF文字の行を返すテーブル関数です。
無視する必要がある最上部と最下部の余分な行を気にしない場合は、次を使用して、結果セットではなくテキストとしてフルテキストを表示できます。
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;
SQL Server 2005以降のすべてのバージョンで同じように機能します(まあ、2005、2017、2019のCTP 2.2で機能していたことから、そう思います)。 「CDATA」セクションを使用しました(そのため、EXPLICIT
モードのFOR XML
を使用する必要があります)。これにより、XMLの「特殊」文字<
、>
、&
、"
は、それぞれ<
、>
、&
、"
としてエスケープされません。
上記のT-SQLを実行すると、XML値の1行1列の結果セットが返されます。下線が引かれたXML値をクリックすると、新しいタブが開き、適切な形式の完全なテキストが表示されます(最初の行は<Code><![CDATA[
、最後の行は]]></Code>
):
<Code><![CDATA[
create procedure sys.sp_helptext
@objname nvarchar(776)
,@columnname sysname = NULL
as
set nocount on
declare @dbname sysname
... {redacted for space} ...
select Text from #CommentText order by LineId
CLOSE ms_crs_syscom
DEALLOCATE ms_crs_syscom
DROP TABLE #CommentText
return (0) -- sp_helptext
]]></Code>
「表示」しているアイテムのサイズによっては、プルダウンするXMLデータの量についてSSMS設定を増やす必要がある場合があります(そうでない場合、切り捨てられた結果が表示される場合があります)。移動:
ツール|オプション|クエリ結果| SQL Server |グリッドへの結果
次に、[取得した最大文字数]で[XMLデータ]をに設定します(オプションは1 MB、2 MB、5 MB、無制限)。次に「OK」ボタンをクリックします。
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);