sql server 中的行号,如 USER_SOURCE oracle 中的 LINE

2024-01-28

我试图找出更改一些存储过程代码的影响。

在甲骨文中我曾经这样做过

select NAME,TEXT,LINE from USER_SOURCE where upper(TEXT) like '%SEARCH_STRING%'

在sql server中我尝试过

 SELECT DISTINCT so.name,sc.TEXT 
    FROM syscomments sc 
    INNER JOIN sysobjects so ON sc.id=so.id 
    WHERE sc.TEXT LIKE '%SEARCH_STRING%'

有没有办法从sql server中的存储过程中获取文本的行号?


我实际上曾经经常这样做,所以我四处寻找并发现了我多年前为此目的编写的这个函数:

CREATE function [dbo].[fnSplit3]( 
                @parameter varchar(Max)                -- the string to split
                , @Seperator Varchar(64)        -- the string to use as a seperator
        ) 
        RETURNS @Items TABLE(
                ID INT                                                -- the element number
                , item VARCHAR(8000)                -- the split-out string element
                , OffSet int                                -- the original offest
                --( not entirley accurate if LEN(@Seperator) > 1 because of the Replace() )
        ) 
AS
BEGIN 
/*
"Monster" Split in SQL Server 2005; From Jeff Moden, 2008/05/22

BYoung, 2008/06/18: Modified to be a Table-Valued Function
                    And to handle CL/LF or LF-only line breaks
  (Note: making it inline made it slower, not faster)

Test: (scripts all triggers in your database)

        Select Lines.Item
         From sys.sql_modules M
          Join sys.objects O on O.object_id = M.object_id
          cross apply dbo.fnSplit1(M.definition, char(13)+char(10)) Lines
         Where O.Type = 'TR' 
         Order by O.create_date, Lines.ID
*/
Declare @Sep char(1)
Set @Sep = char(10)        --our seperator character (convenient, doesn't affect performance)
--NOTE: we make the @Sep character LF so that we will automatically
-- parse out rogue LF-only line breaks.

--===== Add start and end seprators to the Parameter so we can handle
        -- all the elements the same way
        --  Also change the seperator expressions to our seperator
        -- character to keep all offsets = 1
SET @Parameter = @Sep+ Replace(@Parameter,@Seperator,@Sep) +@Sep
-- This reduces run-time about 10%

;WITH cteTally AS
(--==== Create a Tally CTE from 1 to whatever the length
        -- of the parameter is
 SELECT TOP (LEN(@Parameter))
        ROW_NUMBER() OVER (ORDER BY t1.ID) AS N
  FROM Master.sys.sysColumns t1
   CROSS JOIN Master.sys.sysColumns t2
)
INSERT into @Items
        SELECT ROW_NUMBER() OVER (ORDER BY N) AS Number,
                SUBSTRING(@Parameter, N+1, CHARINDEX(@Sep, @Parameter, N+1)-N-1) AS Value
                , N+1
         FROM cteTally
         WHERE N < LEN(@Parameter)
          AND SUBSTRING(@Parameter, N, 1) = @Sep --Notice how we find the seperator

        Return 
END

现在有更快的版本,但这个版本仍然比您在这里看到的大约 90% 的 split 函数要快。如果您查看评论中的测试示例,它几乎正是您所要求的。

        Select O.name, Lines.Item, Lines.ID As LineNo
         From sys.sql_modules M
          Join sys.objects O on O.object_id = M.object_id
          cross apply dbo.fnSplit1(M.definition, char(13)+char(10)) Lines
         Where O.Type = 'P' 
           And Lines.Item LIKE '%SEARCH_STRING%'
         Order by O.name, Lines.ID
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

sql server 中的行号,如 USER_SOURCE oracle 中的 LINE 的相关文章

随机推荐