2009-02-13 16 views
4

如何搜索模式的所有存儲過程,然後打開要編輯的存儲過程?在所有存儲過程中搜索模式然後打開它以進行更改的方法

SQL Server 2005內建什麼東西嗎?

或者是否有任何第三方插件將執行此搜索?

我也使用紅門的SQL提示,但我沒有注意到這個選項。

目前我使用下面的命令來執行搜索

SELECT ROUTINE_SCHEMA, ROUTINE_NAME, ROUTINE_DEFINITION 
    FROM INFORMATION_SCHEMA.ROUTINES 
    WHERE ROUTINE_DEFINITION LIKE '%tblVacationAllocationItem%' 
    AND ROUTINE_TYPE='PROCEDURE' 
    ORDER BY ROUTINE_SCHEMA, ROUTINE_NAME 

這工作不錯,但它返回的存儲過程在列,這是難以閱讀的一個內容。所以我必須使用Object Explorer來查找並打開存儲過程才能看到完整的內容。

編輯: SQL Dependency Tracker允許您使用一系列圖形佈局動態探索所有數據庫對象依賴關係。這看起來會在搜索模式時回答一些問題。任何其他類似於SQL Dependency Tracker的軟件?

編輯: SQL Search作者:Redgate是用於搜索的工具。它會在您鍵入時進行搜索(類似於Bing或Google)。這也是快!價格現在仍然是免費的(2/24/2011),但我認爲他們會開始爲它收費。

回答

1

不幸的是,除了查詢以外,SQL Server 2005中沒有任何功能可以根據其內容查找存儲過程。你唯一能做的就是在對象瀏覽器中按名稱過濾。

我使用Visual Studio數據庫版來完成此任務。

7

有一個名爲sp_grep的開源存儲過程,它允許您根據其makup的DDL /代碼查找數據庫對象。我始終使用此過程來查找符合特定條件的對象。這在數據庫重構中非常有用。

要以編程方式打開和修改SQL對象,可以在任何.Net應用程序中使用SQLDMO對象。 Here是一些使用SQLDMO的例子。

實施例:EXEC sp_grep '可樂='

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER OFF 
GO 

/********************************************************************* 
* Stored procedure sp_grep 
* SQL Server: Microsoft SQL Server 6.0, 4.21 for Windows NT, 
*    Microsoft SQL Server 4.2 for OS/2. 
* Author:  Andrew Zanevsky, AZ Databases, Inc. 
* Version/Date: Version 1.1, October 26, 1995 
* Description: Searches syscomments table in the current database 
*    for occurences of a combination of strings. 
*    Correclty handles cases when a substring begins in 
*    one row of syscomments and continues in the next. 
* Parameters: - @parameter describes the search: 
*    string1 {operation1 string2} {operation2 string 3} ... 
*    where - stringN is a string of characters enclosed in 
*      curly brackets not longer than 80 characters. 
*      Brackets may be omitted if stringN does not 
*      contain spaces or characters: +,-,&; 
*      - operationN is one of the characters: +,-,&. 
*    Parameter is interpreted as follows: 
*    1.Compose the list of all objects where string1 occurs. 
*    2.If there is no more operations in the parameter, 
*     then display the list and stop. Otherwise continue. 
*    3.If the next operation is + then add to the list all 
*     objects where the next string occurs; 
*     else if the next operation is - then delete from the 
*     list all objects where the next string occurs; 
*     else if the next operation is & then delete from the 
*     list all objects where the next string does not 
*     occur (leave in the list only those objects where 
*     the next string occurs); 
*    4.Goto step 2. 
*    Parameter may be up to 255 characters long, and may not 
*    contain <CarriageReturn> or <LineFeed> characters. 
*    Please note that operations are applied in the order 
*    they are used in the parameter string (left to right). 
*    There is no other priority of executing them. Every 
*    operation is applied to the list combined as a result 
*    of all previous operations. 
*    Number of spaces between words of a string matters in a 
*    search (e.g. "select *" is not equal to "select *"). 
*    Short or frequently used strings (such as "select") may 
*    produce a long result set. 
* 
*    - @case: i = insensitive/s = sensitive (default) 
*    Insensitive search is performed regardless of this parameter 
*    if SQL Server is set up with case insensitive sort order. 
* 
* Examples:  sp_grep employee 
*     list all objects where string 'employee' occurs; 
*    sp_grep employee, i 
*     list all objects where string 'employee' occurs in 
*     any case (upper, lower, or mixed), such as 
*     'EMPLOYEE', 'Employee', 'employee', etc.; 
*    sp_grep 'employee&salary+department-trigger' 
*     list all objects where either both strings 'employee' 
*     and 'salary' occur or string 'department' occurs, and 
*     string 'trigger' does not occur; 
*    sp_grep '{select FirstName + LastName}' 
*     list all objects where string 
*     "select FirstName + LastName" occurs; 
*    sp_grep '{create table}-{drop table}' 
*     list all objects where tables are created and not 
*     dropped. 
*     
**********************************************************************/ 

-- sp_grep v1.0 03/16/1995, v1.1 10/26/1995 
-- Author: Andrew Zanevsky, AZ Databases, Inc. 
-- E-mail: [email protected] 
ALTER proc [dbo].[sp_grep] @parameter varchar(255) = null, @case char(1) = 's' 
as 

declare @str_no   tinyint, 
     @msg_str_no  varchar(3), 
     @operation  char(1), 
     @string   varchar(80), 
     @oper_pos  smallint, 
     @context   varchar(255), 
     @i    tinyint, 
     @longest   tinyint, 
     @msg    varchar(255) 

if @parameter is null /* provide instructions */ 
begin 
    print 'Execute sp_grep "{string1}operation1{string2}operation2{string3}...", [case]' 
    print '- stringN is a string of characters up to 80 characters long, ' 
    print ' enclosed in curly brackets. Brackets may be omitted if stringN ' 
    print ' does not contain leading and trailing spaces or characters: +,-,&.' 
    print '- operationN is one of the characters: +,-,&. Interpreted as or,minus,and.' 
    print ' Operations are executed from left to right with no priorities.' 
    print '- case: specify "i" for case insensitive comparison.' 
    print 'E.g. sp_grep "alpha+{beta gamma}-{delta}&{+++}"' 
    print '  will search for all objects that have an occurence of string "alpha"' 
    print '  or string "beta gamma", do not have string "delta", ' 
    print '  and have string "+++".' 
    return 
end 

/* Check for <CarriageReturn> or <LineFeed> characters */ 
if charindex(char(10), @parameter) > 0 or charindex(char(13), @parameter) > 0 
begin 
    print 'Parameter string may not contain <CarriageReturn> or <LineFeed> characters.' 
    return 
end 

if lower(@case) = 'i' 
     select @parameter = lower(ltrim(rtrim(@parameter))) 
else 
     select @parameter = ltrim(rtrim(@parameter)) 

create table #search (str_no tinyint, operation char(1), string varchar(80), last_obj int) 
create table #found_objects (id int, str_no tinyint) 
create table #result (id int) 

/* Parse the parameter string */ 
select @str_no = 0 
while datalength(@parameter) > 0 
begin 
    /* Get operation */ 
    select @str_no = @str_no + 1, @msg_str_no = rtrim(convert(char(3), @str_no + 1)) 
    if @str_no = 1 
    select @operation = '+' 
    else 
    begin 
    if substring(@parameter, 1, 1) in ('+', '-', '&') 
     select @operation = substring(@parameter, 1, 1), 
       @parameter = ltrim(right(@parameter, datalength(@parameter) - 1)) 
    else 
    begin 
     select @context = rtrim(substring( 
         @parameter + space(255 - datalength(@parameter)), 1, 20)) 
     select @msg = 'Incorrect or missing operation sign before "' + @context + '".' 
     print @msg 
     select @msg = 'Search string ' + @msg_str_no + '.' 
     print @msg 
     return 
    end 
    end 

    /* Get string */ 
    if datalength(@parameter) = 0 
    begin 
     print 'Missing search string at the end of the parameter.' 
     select @msg = 'Search string ' + @msg_str_no + '.' 
     print @msg 
     return 
    end 
    if substring(@parameter, 1, 1) = '{' 
    begin 
     if charindex('}', @parameter) = 0 
     begin 
      select @context = rtrim(substring( 
         @parameter + space(255 - datalength(@parameter)), 1, 200)) 
      select @msg = 'Bracket not closed after "' + @context + '".' 
      print @msg 
      select @msg = 'Search string ' + @msg_str_no + '.' 
      print @msg 
      return 
     end 
     if charindex('}', @parameter) > 82 
     begin 
      select @context = rtrim(substring( 
         @parameter + space(255 - datalength(@parameter)), 2, 20)) 
      select @msg = 'Search string ' + @msg_str_no + ' is longer than 80 characters.' 
      print @msg 
      select @msg = 'String begins with "' + @context + '".' 
      print @msg 
      return 
     end   
     select @string = substring(@parameter, 2, charindex('}', @parameter) - 2), 
       @parameter = ltrim(right(@parameter, 
           datalength(@parameter) - charindex('}', @parameter))) 
    end 
    else 
    begin 
     /* Find the first operation sign */ 
     select @oper_pos = datalength(@parameter) + 1 
     if charindex('+', @parameter) between 1 and @oper_pos 
      select @oper_pos = charindex('+', @parameter) 
     if charindex('-', @parameter) between 1 and @oper_pos 
      select @oper_pos = charindex('-', @parameter) 
     if charindex('&', @parameter) between 1 and @oper_pos 
      select @oper_pos = charindex('&', @parameter) 

     if @oper_pos = 1 
     begin 
      select @context = rtrim(substring( 
         @parameter + space(255 - datalength(@parameter)), 1, 20)) 
      select @msg = 'Search string ' + @msg_str_no + 
         ' is missing, before "' + @context + '".' 
      print @msg 
      return 
     end   
     if @oper_pos > 81 
     begin 
      select @context = rtrim(substring( 
         @parameter + space(255 - datalength(@parameter)), 1, 20)) 
      select @msg = 'Search string ' + @msg_str_no + ' is longer than 80 characters.' 
      print @msg 
      select @msg = 'String begins with "' + @context + '".' 
      print @msg 
      return 
     end   

     select @string = substring(@parameter, 1, @oper_pos - 1), 
       @parameter = ltrim(right(@parameter, 
           datalength(@parameter) - @oper_pos + 1)) 
    end 
    insert #search values (@str_no, @operation, @string, 0) 

end 
select @longest = max(datalength(string)) - 1 
from #search 
/* ------------------------------------------------------------------ */ 
/* Search for strings */ 
if @case = 'i' 
begin 
    insert #found_objects 
    select a.id, c.str_no 
    from syscomments a, #search c 
    where charindex(c.string, lower(a.text)) > 0 

    insert #found_objects 
    select a.id, c.str_no 
    from syscomments a, syscomments b, #search c 
    where a.id  = b.id 
    and a.number = b.number 
    and a.colid + 1 = b.colid 
    and charindex(c.string, 
       lower(right(a.text, @longest) + 
/*      space(255 - datalength(a.text)) +*/ 
         substring(b.text, 1, @longest))) > 0 
end 
else 
begin 
    insert #found_objects 
    select a.id, c.str_no 
    from syscomments a, #search c 
    where charindex(c.string, a.text) > 0 

    insert #found_objects 
    select a.id, c.str_no 
    from syscomments a, syscomments b, #search c 
    where a.id  = b.id 
    and a.number = b.number 
    and a.colid + 1 = b.colid 
    and charindex(c.string, 
       right(a.text, @longest) + 
/*    space(255 - datalength(a.text)) +*/ 
       substring(b.text, 1, @longest)) > 0 
end 
/* ------------------------------------------------------------------ */ 
select distinct str_no, id into #dist_objects from #found_objects 
create unique clustered index obj on #dist_objects (str_no, id) 

/* Apply one operation at a time */ 
select @i = 0 
while @i < @str_no 
begin 
    select @i = @i + 1 
    select @operation = operation from #search where str_no = @i 

    if @operation = '+' 
     insert #result 
     select id 
     from #dist_objects 
     where str_no = @i 
    else if @operation = '-' 
     delete #result 
     from #result a, #dist_objects b 
     where b.str_no = @i 
     and a.id = b.id 
    else if @operation = '&' 
     delete #result 
     where not exists 
       (select 1 
        from #dist_objects b 
        where b.str_no = @i 
        and b.id = #result.id) 
end 

/* Select results */ 
select distinct id into #dist_result from #result 

/* The following select has been borrowed from the sp_help 
** system stored procedure, and modified. */ 
select Name  = o.name, 
     /* Remove 'convert(char(15)' in the following line 
     ** if user names on your server are longer. */ 
     Owner  = convert(char(15), user_name(uid)), 
     Object_type = substring(v.name + x.name, 1, 16) 
from #dist_result   d, 
     sysobjects    o, 
     master.dbo.spt_values v, 
     master.dbo.spt_values x 
where d.id = o.id 
/* SQL Server version 6.x uses 15, prior versions use 7 in expression below */ 
and  o.sysstat & (7 + 8 * sign(charindex('6.', @@version))) = v.number 
and  v.type = "O" 
and  x.type = "R" 
and  o.userstat & -32768 = x.number 
order by Object_type desc, Name asc 
+0

它的工作原理! :-)好東西 – 2009-02-13 08:03:37

3

要查詢的對象的定義,可以使用syscomments中。例如:

select * from syscomments where text like '%tblVacationAllocationItem%' 

雖然這對於大多數情況工作,如果該定義是超過4000個字符長,就會有存在多個syscomment行鍼對單個對象。儘管不太可能,但您的搜索短語可能跨越多個syscomment行。

1

不回答你的問題,但我們保存所有的存儲過程作爲單獨的文件 - 更容易在全球範圍內使用的程序編輯器的變化,他們很容易陷入版本管理信息庫(SVN在我們的例子)

2

我已經在下面的文章中發佈了一個適用於SQL 2000及更高版本的存儲過程中的代碼,它可以全面搜索(跨Proc,函數,視圖,默認,作業等),並可以忽略註釋並可以忽略字符串文字。你可以在SQLServerCentral.com找到它:

http://www.sqlservercentral.com/articles/Stored+Procedure/62975/

它不會自動打開任何編輯,但確實給了它在哪裏的文本相匹配的行號,並考慮到4000個字符塊作爲由Cadaeic提到。我打算很快更新文章,以便在所有數據庫中包含一個循環,甚至包括我的一些RegEx函數(用於對象名稱匹配以及搜索字符串)。

+0

謝謝所羅門。我實際上使用SQL#。 (非常好的產品!)使用正則表達式的任何增強將是最令人滿意的。 – 2009-03-23 18:02:03

1
begin 
--select column_name from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='Products' 
--Declare the Table variable 
DECLARE @GeneratedStoredProcedures TABLE 
(
     Number INT IDENTITY(1,1), --Auto incrementing Identity column 
     name VARCHAR(300) --The string value 
) 

--Decalre a variable to remember the position of the current delimiter 
DECLARE @CurrentDelimiterPositionVar INT 
declare @sqlCode varchar(max) 
--Decalre a variable to remember the number of rows in the table 
DECLARE @Count INT 

--Populate the TABLE variable using some logic 
INSERT INTO @GeneratedStoredProcedures SELECT name FROM sys.procedures where name like 'procGen_%' 

--Initialize the looper variable 
SET @CurrentDelimiterPositionVar = 1 

--Determine the number of rows in the Table 
SELECT @Count=max(Number) from @GeneratedStoredProcedures 

--A variable to hold the currently selected value from the table 
DECLARE @CurrentValue varchar(300); 

--Loop through until all row processing is done 
WHILE @CurrentDelimiterPositionVar <= @Count 
BEGIN 
    --Load current value from the Table 
    SELECT @CurrentValue = name FROM @GeneratedStoredProcedures WHERE Number = @CurrentDelimiterPositionVar 
    --Process the current value 
    --print @CurrentValue 
    set @sqlCode = 'drop procedure ' + @CurrentValue 
    print @sqlCode 
    --exec (@sqlCode) 


    --Increment loop counter 
    SET @CurrentDelimiterPositionVar = @CurrentDelimiterPositionVar + 1; 
END 

end 
0

晚一個,但希望有用。

這裏還有兩個工具,我成功地用於搜索數據庫對象和數據:

  • ApexSQL Search - 免費SSMS的所有版本。有一些額外的功能,如檢查依賴關係等。

  • SSMS Tools pack - 除SQL 2012之外的所有版本均爲免費版。除搜索功能外,還提供更多有用的功能。

基本上你不能出差錯與任何第三方工具,因爲所有這些都是免費的,並會爲你節省大量的時間相比,一些執行存儲過程。

相關問題