Finding stored procedures containing %string%
November 9th, 200917
Finding stored procedures containing %string%
November 9th, 200917
 

Having just returned from PASS, I needed to play catch up on a few things in a stored procedure that was being developed before I left.  Being a little frazzled still, I could not for the life of me remember the name of the stored procedure where those things existed.  I constantly find myself manually writing queries like this to find all references to a column, table, variable or concept:

    SELECT [name] 
    FROM sys.procedures 
    WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%string%';

or

    SELECT OBJECT_NAME([object_id])
    FROM sys.sql_modules 
    WHERE [definition] LIKE '%string%';

Yes, I could rely on dependencies *sometimes* – but even when they are not broken, I am not always trying to find things that show up in a dependency chain.

Now the queries above are a little tedious to write, but not too bad.  But there are other complications that can often add a little bit of effort:

  • When dealing with multiple owners/schema this can be more complex, so I would always add:
    SELECT OBJECT_SCHEMA_NAME([object_id]) 
    + '.' + [name] ...
  • And in the case of poorly chosen identifiers (hey, this isn't always against my own systems!), I would add QUOTENAME:
    SELECT QUOTENAME(OBJECT_SCHEMA_NAME([object_id]) 
    + '.' + QUOTENAME([name]) ...
  • And of course I would want the results to allow me to quickly get at the definition for those stored procedures, so I would want sp_helptext as part of the results:
    SELECT 'EXEC sp_helptext ''' 
    + QUOTENAME(OBJECT_SCHEMA_NAME([object_id]) 
    + '.' + QUOTENAME([name]) + '''' ...

This all gets very tedious to type, so a while back I decided to implement a set of stock, utility procedures in all of my databases (and don't tell my clients, but I've added it to some of their systems, too).  I wanted one for procedures specifically, and then one that will search sql_modules so that it picks up functions and triggers as well.

    CREATE PROCEDURE dbo.Find_InSP
   @string NVARCHAR(MAX)
AS
BEGIN
   SET NOCOUNT ON;
 
   SELECT
       cmd = N'EXEC sp_helptext ''' 
           + QUOTENAME(OBJECT_SCHEMA_NAME([object_id]))
           + '.' + QUOTENAME([name]) + ''';'
   FROM
       sys.procedures
   WHERE
       OBJECT_DEFINITION([object_id]) LIKE N'%' + @string + '%'
   ORDER BY
       cmd;
END
GO
 
CREATE PROCEDURE dbo.Find_InModule
   @string NVARCHAR(MAX)
AS
BEGIN
   SET NOCOUNT ON;
 
   SELECT
       cmd = N'EXEC sp_helptext ''' 
           + QUOTENAME(OBJECT_SCHEMA_NAME([object_id]))
           + '.' + QUOTENAME(OBJECT_NAME([object_id])) + ''';'
   FROM
       sys.sql_modules
   WHERE
       [definition] LIKE N'%' + @string + '%'
   ORDER BY
       cmd;
END
GO

Now when I run:

    EXEC msdb.dbo.Find_InSP 'agent';

I get the following results (and as an added bonus, I can use CTRL in the grid results to copy the sp_helptext commands only for the procedures I am interested in):

I have also added the procedures to the model database, so that they exist in all future databases that are created as well.  Does this save me a ton of time on any given day?  Of course not.  But every shortcut helps, right?  I hope these procedures are useful for you.

By: Aaron Bertrand

I am a passionate technologist with industry experience dating back to Classic ASP and SQL Server 6.5. I am a long-time Microsoft MVP, write at Simple Talk, SQLPerformance, and MSSQLTips, and have had the honor of speaking at more conferences than I can remember. In non-tech life, I am a husband, a father of two, a huge hockey and football fan, and my pronouns are he/him.

17 Responses

  1. Bhoopendra Sharma says:

    Very useful Article, Saved my lot of time.
    Thanks a ton!!!

  2. Bikram Pattanayak says:

    Awaesome…

  3. Shawkat says:

    Wow!! Indeed a Fantastic Article..!!
    Now I know- I don't know a loooot.. 😛
    First step of learning..!!!

  4. Stork says:

    I build my utility scripts in the master database so I can execute them from any database.  Use the undocumented "exec sp_MS_marksystemobject your_procedure_name".  If you want to get way crazy, see how synonyms (new in 2005) let you run your utilities on any server\instance you have access to (so you don't have to muck-up production code with utility scripts)

  5. David says:

    You can also search for text in objects using SQLMetaTool which also has a lot of other functions such as table & index info. http://www.aldexsoftware.co.uk/SQLMetaTool

  6. Raj says:

    I have the habit of using syscomments for 2k. Useful to track down triggers as well.
    I understand that sys.procedures is safer way to access as it is a catalog view and its not likely to change with patch installations.
    Any other adv favouring sys.procedures.

  7. Aaron Bertrand says:

    Sure John, I have two reasons:
    1. the joins tend to create much more verbose code.  In more complicated queries I can easily see the need to go to those tables several times.
    2. When I'm coding against instance-wide DMVs (e.g. missing index details) it is much easier to add the optional database_id parameter than to hardcode databasename.sys.objects, etc.
    HTH,
    Aaron

  8. John Vanda says:

    Thanks for the great article Aaron!  I find myself using queries just like that all the time.  Any reason you prefer object_schema_name and object_name functions over joining to sys.schemas and sys.objects for the name columns?

  9. AaronBertrand says:

    Red-Gate just announced a new add-in that handles searching objects for %string%:
    http://www.red-gate.com/products/sql_search/index.htm

  10. Madhivanan says:

    I agree with Aaron. Most of the times, you dont need any add-ons when the things can be done easily with queries

  11. AaronBertrand says:

    Add-ins are an option for a lot of people.  Sometimes though you cannot install add-ins on all machines.

  12. Smitha Reddy says:

    Thanks for sharing Aaron – I've added to my collection.  I always keep my queries aka DBA toolset in one folder/organized so I don't have to run around when I really need them. The version I use:
    SELECT OBJECT_SCHEMA_NAME ([object_id]),object_name([object_id])
    FROM sys.sql_modules
    WHERE [definition] LIKE '%SearchPhrase%'

  13. casm says:

    As Albert says, there's a couple of free tools than can be installed as an Add-On on SSMS to do this kind of things.
    Take a look at Quick Find (http://ssmsaddins.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=18363) or Object Finder (http://ssmsaddins.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=18135)

  14. Alberto says:

    Thanks for the scripts.
    I use a free tool from xSQL software called SQL Server Object Search (http://www.xsqlsoftware.com/Product/Sql_Database_Object_Search.aspx) which works well both in 2005 and 2008.

  15. Chris says:

    Any chance you would share your utility procs.  I would be very interested.  I use AutoHotKey to store things like:
    select column_name, data_type, character_maximum_length, is_nullable from information_schema.columns
     where table_name = "
       and column_name like '%%'
         order by ordinal_position, column_name

  16. Uri Dimant says:

    Thanks Aaron,
    very nice script.