it-swarm.com.de

Wie formatiere ich die Ausgabe von OBJECT_DEFINITION so, dass sie mit sp_helptext identisch ist?

object_definition und sp_helptext geben beide den Quellcode einer gespeicherten Prozedur zurück - aber wie kann ich object_definition verwenden und den Quellcode einschließlich der Zeilenumbrüche als sp_helptext Derzeit?

zum Beispiel erstelle ich im folgenden Code eine gespeicherte Prozedur:

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 

using sp_helptext Ich bekomme eine schöne Ansicht des Quellcodes:

sp_helptext 'usp_radhe'

(enter image description here

using object_definition Ich erhalte den Quellcode in einer einzigen Zeile und das ist nicht gut für mich:

select OBJECT_DEFINITION(object_id('usp_radhe'))

(enter image description here

5

Da Sie SQL Server 2016 verwenden, können Sie STRING_SPLIT und ein Trick von Aaron Bertrand zum Teilen bei Wagenrücklauf/Zeilenvorschub.

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);
2
Scott Hodgin

Ich hatte ein ähnliches Problem. Aktivieren Sie zuerst diese Option von SSMS - sie ist standardmäßig deaktiviert:

SSMS/Tools/Options/Query results/SQL Server/Results to grid/Retain CR/LF on copy or save

Schließen Sie SSMS und führen Sie es erneut aus, damit es funktioniert.

Ich benutze diese Abfrage, um den vollständigen Text der Objektdefinitionen zu erhalten:

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

Ich mag es, LEN des SP-Textes anzuzeigen, damit ich sicher bin, dass er nicht beschnitten ist.

5
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 + @[email protected] + @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, @[email protected] + @LFCR), N'')  
        select @BasePos = @CurrentPos+2  
        INSERT #CommentText VALUES( @LineId, @Line )  
        select @LineId = @LineId + 1  
        select @Line = NULL  
    end  

K, so macht es sp_helptext. Die Ergebnisse sind eine Tabellenfunktion, die Zeilen für CRLF-Zeichen zurückgibt, die von der object_definition zurückgegeben werden.

3
Alocyte

Wenn Ihnen eine zusätzliche Zeile ganz oben und ganz unten nichts ausmacht, die ignoriert werden sollte, können Sie Folgendes verwenden, um den vollständigen Text als Text und nicht als Ergebnismenge anzuzeigen:

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;

Es funktioniert in allen Versionen ab SQL Server 2005 gleich (ich gehe davon aus, dass es in den CTP 2.2-Versionen 2005, 2017 und 2019 funktioniert hat). Ich habe einen Abschnitt "CDATA" verwendet (für den wiederum der Modus EXPLICIT von FOR XML Erfordert wird), damit XML-Sonderzeichen <, >, & Und " Werden nicht als &lt;, &gt;, &amp; Und &quot; Enthalten. beziehungsweise.

Wenn Sie das oben gezeigte T-SQL ausführen, erhalten Sie eine Ergebniszeile mit einer Zeile und einer Spalte eines XML-Werts zurück. Klicken Sie auf den unterstrichenen XML-Wert. Daraufhin wird eine neue Registerkarte mit dem vollständigen, ordnungsgemäß formatierten Text angezeigt (zusammen mit einer ersten Zeile von <Code><![CDATA[ Und einer letzten Zeile von ]]></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>

Abhängig von der Größe des Elements, das Sie "anzeigen", müssen Sie möglicherweise die SSMS-Einstellung für die Anzahl der abgerufenen XML-Daten erhöhen (andernfalls werden möglicherweise abgeschnittene Ergebnisse angezeigt). Gehe zu:

Extras | Optionen | Abfrageergebnisse | SQL Server | Ergebnisse zum Raster

Stellen Sie dann unter "Maximal abgerufene Zeichen" "XML-Daten" auf ein (Optionen sind: 1 MB, 2 MB, 5 MB und Unbegrenzt). Klicken Sie dann auf die Schaltfläche "OK".

0
Solomon Rutzky

Für MSSQL Server 2012 können Sie eine rekursive Funktion verwenden. Z.B.:

/* 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);
0
Erwin Anema