object_definition et sp_helptext renvoient tous les deux le code source d'une procédure stockée - mais comment puis-je utiliser object_definition
et obtenez le code source, y compris les sauts de ligne, comme sp_helptext
le fait actuellement?
par exemple dans le code ci-dessous je crée une procédure stockée:
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
en utilisant sp_helptext j'obtiens une belle vue du code source:
sp_helptext 'usp_radhe'
en utilisant définition_objet j'obtiens le code source sur une seule ligne et ce n'est pas bon pour moi:
select OBJECT_DEFINITION(object_id('usp_radhe'))
Puisque vous utilisez SQL Server 2016, vous pouvez utiliser STRING_SPLIT
et un astuce d'Aaron Bertrand à partager sur retour chariot/saut de ligne.
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);
J'ai eu un problème similaire. Activez d'abord cette option de SSMS - elle est désactivée par défaut:
SSMS/Tools/Options/Query results/SQL Server/Results to grid/Retain CR/LF on copy or save
Fermez SSMS et exécutez-le à nouveau pour le faire fonctionner.
J'utilise cette requête pour obtenir le texte intégral des définitions d'objet:
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
J'aime afficher LEN du texte sp, de sorte que je suis sûr qu'il n'est pas recadré.
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, c'est ainsi que le fait sp_helptext. Envelopper les résultats sont une fonction de table renvoyant des lignes pour les caractères CRLF renvoyés par la définition_objet.
Si cela ne vous dérange pas une ligne supplémentaire tout en haut et en bas qui doit être ignorée, vous pouvez utiliser ce qui suit pour afficher le texte intégral, sous forme de texte et non comme un ensemble de résultats:
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;
Il fonctionne de la même manière dans toutes les versions à partir de SQL Server 2005 (enfin, je suppose qu'en voyant qu'il a fonctionné sur 2005, 2017 et 2019 CTP 2.2). J'ai utilisé une section "CDATA" (qui, à son tour, nécessite l'utilisation du mode EXPLICIT
de FOR XML
) pour que les caractères XML "spéciaux" <
, >
, &
, et "
ne serait pas échappé en tant que <
, >
, &
, et "
, respectivement.
Si vous exécutez le T-SQL illustré ci-dessus, vous récupérerez un jeu de résultats d'une ligne et d'une colonne d'une valeur XML. Cliquez sur la valeur XML soulignée et elle s'ouvrira dans un nouvel onglet affichant le texte complet et correctement formaté (avec une première ligne de <Code><![CDATA[
et une dernière ligne de ]]></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>
Selon la taille de l'élément que vous "affichez", vous devrez peut-être augmenter le paramètre SSMS pour la quantité de données XML qu'il extrait (sinon vous pourriez voir des résultats tronqués). Aller à:
Outils | Options | Résultats de la requête | SQL Server | Résultats vers la grille
Ensuite, sous "Nombre maximal de caractères récupérés", définissez "Données XML" sur (les options sont: 1 Mo, 2 Mo, 5 Mo et Illimité). Cliquez ensuite sur le bouton "OK".
Pour MSSQL Server 2012, vous pouvez utiliser une fonction récursive. Par exemple.:
/* 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);