11

使用 SQL Server 2000,有没有办法在所有触发过程中全局搜索模式?

调用存储过程的地方对我隐藏。

这是我的第一篇文章,所以请善待。

4

3 回答 3

24

这将搜索 SQL Server 2000 上的触发器、过程、函数和视图(建议不要在较新版本上使用此方法;请参阅此博客文章以获得更好的方法):

SELECT o.name
 FROM syscomments AS c
 INNER JOIN sysobjects AS o
 ON c.id = o.id
 WHERE c.text LIKE '%procedurename%';

当然,这里有一些危险:

  1. syscomments将采用 > 4000 行的程序并将它们分成多行。因此,大型程序可能只在边界点提及您的搜索字符串,而根本没有出现。也有可能这样的过程可能会出现在列表中两次(您可以添加一个GROUP BY来消除它)。
  2. 谨防误报。您的搜索字符串可以包含在评论中。或者,如果您有一个名为GetAuthorSubscriptions并且正在查找的存储过程%GetAuthors%,它仍然会出现。对子句使用区分大小写的搜索COLLATE可能会有所帮助,但不一定会消除它。

更多信息在这里:

我强烈建议不要使用 SQL Server 2000。如果不是为了其他 80 亿个好处,在更现代的版本中这项任务要容易得多。

请注意,您的存储过程可能不会从数据库中被调用 - 它可能是来自应用程序的临时调用、某人的 Management Studio 的打开副本,甚至是工作。要搜索工作,您可以使用:

SELECT 
  job_name = j.name, 
  s.step_name
FROM msdb.dbo.sysjobs AS j
INNER JOIN msdb.dbo.sysjobsteps AS s
ON j.job_id = s.job_id
WHERE s.command LIKE '%procedurename%';

还没转起来?TextData LIKE '%procedurename%'在...上运行服务器端跟踪过滤

于 2013-03-22T18:04:19.777 回答
5

使用 SQL Server 2017使用 SQL Server Management Studio

在对象资源管理器中查看过程的依赖关系

  • 在对象资源管理器中,连接到数据库引擎实例,然后展开该实例
  • 实例。
  • 展开 Databases,展开过程所属的数据库,然后展开 Programmability。
  • 展开存储过程,右键单击该过程,然后单击查看依赖关系。
  • 查看依赖于过程的对象列表。
  • 查看过程所依赖的对象列表。
  • 单击确定。

使用 Transact-SQL
,您可以按照此处的步骤操作

有关更多信息,请查看
https://docs.microsoft.com/en-us/sql/relational-databases/stored-procedures/view-the-dependencies-of-a-stored-procedure?view=sql-上的原始文章服务器-2017

于 2018-06-29T13:49:04.037 回答
0

这是我编写的一个程序,它从系统表中获取源代码,并将其逐行放入表中。这将更容易扫描文本并处理可能在系统表中被截断的字符串,因为换行文本。如果您每天或每小时运行一次,它将为您提供接近实时的结果。

您可以扫描 v$source 表以获取不同的过程名称列表,但认为将整个解决方案放在这里会很有用。

如果有任何错误请告诉我,因为它尚未经过详尽的测试。

CREATE TABLE [dbo].[v$source](
            [theDb] [varchar](100) NULL,
            [theLineNo] [int] NULL,
            [theName] [varchar](1000) NULL,
            [theText] [varchar](8000) NULL,
            [theType] [varchar](100) NULL,
            [theCreateDate] [datetime] NULL,
            [theOrderNum] [int] NULL,
            [DateCreated] [datetime] NULL,
            [DateUpdated] [datetime] NULL
        ) ON [PRIMARY]

    CREATE TABLE [dbo].[v$source_unsplit](
        [theDb] [varchar](100) NULL,
        [theName] [varchar](1000) NULL,
        [theText] [varchar](8000) NULL,
        [theType] [varchar](100) NULL,
        [theCreateDate] [datetime] NULL,
        [theOrderNum] [int] NULL,
        [DateCreated] [datetime] NULL,
        [DateUpdated] [datetime] NULL
    ) ON [PRIMARY]
    GO


    CREATE FUNCTION [dbo].[GetLHS]
    (
        @p_delim   varchar(1),
        @p_string  varchar(max)
    )
    RETURNS varchar(max)
    AS
    BEGIN
       declare @l_pos int;
       set @l_pos = charindex(@p_delim,@p_string,1);

       --if (@l_pos = 0)
       --   return @p_string;

       return substring(@p_string,1,iif(@l_pos=0,len(@p_string),@l_pos-1));

    END

    CREATE FUNCTION [dbo].[GetRHS]
    (
        @p_delim   varchar(1),
        @p_string  varchar(max)
    )
    RETURNS varchar(max)
    AS
    BEGIN
       declare @l_pos int;
       set @l_pos = charindex(@p_delim,@p_string,1);

       if (@l_pos = 0)
          return '';

       return substring(@p_string,@l_pos+1,len(@p_string));

    END



CREATE PROCEDURE sp_bld_v$source
    AS
    BEGIN
        delete from v$source_unsplit


        EXEC sp_MSforeachdb
        'USE ?; 
         insert into dict..v$source_unsplit (TheDB,TheName,TheText,TheType,TheCreateDate,TheOrderNum)
         SELECT ''?'' thedb, o.name, substring(c.Text,1,8000),xtype,crdate,colid
         FROM syscomments AS c
         INNER JOIN sysobjects AS o
         ON c.id = o.id'

        delete from v$source

        DECLARE @C_TEXT_CURSOR as CURSOR;
        DECLARE @l_thedb       varchar(1000)
        DECLARE @l_thename     varchar(1000)
        DECLARE @l_theordernum int
        DECLARE @l_text        varchar(max)
        DECLARE @l_lhs         varchar(max) = 'NULL'
        DECLARE @l_line_no     int
        DECLARE @l_createDate  datetime
        declare @l_thetype     varchar(10)

        SET @C_TEXT_CURSOR = CURSOR FOR
         select   theDb,TheName,theOrderNum,thetext,theCreateDate,thetype--,replace(theText,char(10),'@^@') 
         from     v$source_unsplit
         order by theDb,TheName,theOrderNum

        OPEN @C_TEXT_CURSOR;
        FETCH NEXT FROM @C_TEXT_CURSOR INTO @l_thedb,@l_thename,@l_theordernum,@l_text,@l_createDate,@l_thetype

        WHILE @@FETCH_STATUS = 0
        BEGIN
           if @l_theordernum = 1 
           begin
              set @l_line_no = 1
              if @l_lhs <> 'NULL'
              begin
                  insert into v$source (TheDB,TheLineNo,TheName,TheText,TheType,TheCreateDate,TheOrderNum)
                  select @l_thedb,@l_line_no,@l_thename,@l_lhs,@l_thetype,@l_createDate,@l_theordernum
              end
           end
           else
           begin
              set @l_text = @l_lhs+@l_text -- reconstuct previous line
           end

           while charindex(char(10),@l_text)>0 
           begin
              set @l_lhs  = lib.dbo.GetLHS(char(10),@l_text)
              set @l_text = lib.dbo.GetRHS(char(10),@l_text)

              insert into v$source (TheDB,TheLineNo,TheName,TheText,TheType,TheCreateDate,TheOrderNum)
              select @l_thedb,@l_line_no,@l_thename,@l_lhs,@l_thetype,@l_createDate,@l_theordernum

              --print(@l_text)
              set @l_line_no = @l_line_no+1


           end
           set @l_lhs = @l_text

           FETCH NEXT FROM @C_TEXT_CURSOR INTO @l_thedb,@l_thename,@l_theordernum,@l_text,@l_createDate,@l_thetype
        END

        CLOSE @C_TEXT_CURSOR;
        DEALLOCATE @C_TEXT_CURSOR;

    END
    GO
于 2017-11-03T03:02:19.580 回答