Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Numer wiersza w serwerze sql, taki jak LINE w USER_SOURCE oracle

Często to robiłem, więc poszperałem i znalazłem tę funkcję, którą napisałem wiele lat temu, właśnie w tym celu:

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) [email protected]
-- 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

Istnieje teraz szybsza wersja, ale ta jest nadal szybsza niż około 90% funkcji dzielonych, które tutaj zobaczysz. Jeśli sprawdzisz przykład testowy w komentarzach, jest to prawie dokładnie to, o co prosiłeś.

        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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Funkcja TAN() w Oracle

  2. Mapowanie pola ORACLE TIMESTAMP(9) na java.util.Date

  3. Czytanie zmiennej clob linia po linii

  4. Funkcja NLS_LOWER() w Oracle

  5. Zastąp REGEXP_SUBSTR w SQL Server