Ever wanted a function you can use to extract a function or sp's text?Well here you go... (udfGetObjectText)Used like:SELECT [ObjectText] FROM tools.udfGetObjectText(OBJECT_ID('tools.udfGetObjectText')) ORDER BY [LineNumber]
Results:/* udfGetObjectText ******************************************************************************* * * Extracts the object text from an object. Returns a table with the text split into lines * Inlineable for efficient CROSS APPLYing... * * Transact Charlie * *************************************************************************************************/ CREATE FUNCTION tools.udfGetObjectText ( @objectID INT ) RETURNS TABLE AS RETURN SELECT so.[name] AS [ObjectName] , cs.[RowID] AS [LineNumber] , cs.[SplitText] AS [ObjectText] FROM sys.objects AS so CROSS APPLY ( SELECT CAST([text] AS NVARCHAR(MAX)) FROM syscomments AS sc WHERE sc.[id] = so.[object_id] ORDER BY sc.[number] FOR XML PATH('') ) AS comments ([c]) CROSS APPLY tools.udfSplit(comments.[c], '#x0D;') AS cs WHERE so.[Object_Id] = @objectID
For free, you also get:A tools schemaA number table (with a quarter of a million rows in it)A *fast* string splitter function (udfSplit)If you already have your own number table and string splitter you want to use then edit to suit.EnjoySET NOCOUNT ON/* Tools SCHEMA **********************************************************************************/IF NOT EXISTS ( SELECT 1 FROM sys.schemas WHERE [name] = 'tools' )BEGIN RAISERROR('Creating tools schema....', 0, 1) WITH NOWAIT EXEC ('CREATE SCHEMA tools') -- Dynamic because Needs to be the only statement in a batchENDGO/* Number Table **********************************************************************************/IF NOT EXISTS ( SELECT 1 FROM sys.tables WHERE [name] = 'tbNumber' AND [schema_id] = SCHEMA_ID('tools'))BEGIN RAISERROR('Creating Number Table....', 0, 1) WITH NOWAIT CREATE TABLE tools.tbNumber ( [n] [int] NOT NULL , CONSTRAINT [PK_tbNumber] PRIMARY KEY CLUSTERED ([n]) )ENDGO/* Number Table Population ***********************************************************************/RAISERROR('Populating Number Table (1/4 Million Numbers Should be enough)....', 0, 1) WITH NOWAITTRUNCATE TABLE tools.tbNumber; WITH number (n) -- 1 Million Numbers AS ( SELECT ROW_NUMBER() OVER (ORDER BY a.[n]) FROM ( SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 ) AS a ([n]) CROSS JOIN ( SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 ) AS b ([n]) CROSS JOIN ( SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 ) AS c ([n]) CROSS JOIN ( SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 ) AS d ([n]) CROSS JOIN ( SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 ) AS e ([n]) CROSS JOIN ( SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 ) AS f ([n]) CROSS JOIN ( SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 ) AS g ([n]) CROSS JOIN ( SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 ) AS h ([n]) CROSS JOIN ( SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 ) AS i ([n]) )INSERT tools.tbNumber ([n])SELECT [n]FROM numberGO/* udfSplit **************************************************************************************/RAISERROR('Creating udfSplit Function....', 0, 1) WITH NOWAITIF NOT EXISTS (SELECT 1 FROM sys.objects WHERE [object_id] = object_id('tools.udfSplit'))BEGIN -- Create a dynamic dummy function to alter EXEC('CREATE FUNCTION tools.udfSplit() RETURNS TABLE AS RETURN (SELECT NULL AS [FOO])')ENDGO/* udfSplit (A Fast String Splitter) ************************************************************** * * Uses a number table to *very* quickly split the text (@text). Splits on the delimiter (@d) * Returns Table of ( [RowID], [SplitText] ). Inlineable for CROSS APPLY etc. * * Transact Charlie * *************************************************************************************************/ALTER FUNCTION tools.udfSplit (@text NVARCHAR(MAX), @d NVARCHAR(50))RETURNS TABLE AS RETURN (SELECT [RowID] = ROW_NUMBER() OVER ( ORDER BY [n] ASC ) , [SplitText] = SUBSTRING( @d + @text + @d , [n] + LEN(@d) , CHARINDEX(@d, @d + @text + @d, [n] + LEN(@d)) - [n] - LEN(@d) )FROM tools.tbNumber AS nWHERE [n] <= LEN(@d + @text + @d) - LEN(@d) AND SUBSTRING(@d + @text + @d, [n], LEN(@d)) = @d)GO/* udfGetObjectText ******************************************************************************/RAISERROR('Creating udfGetObjectText Function....', 0, 1) WITH NOWAITIF NOT EXISTS (SELECT 1 FROM sys.objects WHERE [object_id] = object_id('tools.udfGetObjectText'))BEGIN -- Create a dynamic dummy function to alter EXEC('CREATE FUNCTION tools.udfGetObjectText() RETURNS TABLE AS RETURN (SELECT NULL AS [FOO])')ENDGO/* udfGetObjectText ******************************************************************************* * * Extracts the object text from an object. Returns a table with the text split into lines * Inlineable for efficient CROSS APPLYing... * * Transact Charlie * *************************************************************************************************/ ALTER FUNCTION tools.udfGetObjectText ( @objectID INT ) RETURNS TABLE AS RETURN SELECT so.[name] AS [ObjectName] , cs.[RowID] AS [LineNumber] , cs.[SplitText] AS [ObjectText]FROM sys.objects AS so CROSS APPLY ( SELECT CAST([text] AS NVARCHAR(MAX)) FROM syscomments AS sc WHERE sc.[id] = so.[object_id] ORDER BY sc.[number] FOR XML PATH('') ) AS comments ([c]) CROSS APPLY tools.udfSplit(comments.[c], '#x0D;') AS csWHERE so.[Object_Id] = @objectIDGO/* Testing ***************************************************************************************/SELECT [ObjectText] FROM tools.udfGetObjectText(OBJECT_ID('tools.udfGetObjectText')) ORDER BY [LineNumber]
I hope it's self explanatory.Charlie===============================================================Msg 3903, Level 16, State 1, Line 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION