3

(1) Is there a good/reliable way to query the system catalogue in order
to find all stored procedures which create some temporary tables in their
source code bodies but which don't drop them at the end of their bodies?

(2) In general, can creating temp tables in a SP and not dropping
them in the same SP cause some problems and if so, what problems?

I am asking this question in the contexts of
SQL Server 2008 R2 and SQL Server 2012 mostly.

Many thanks in advance.

peter.petrov
  • 38,363
  • 16
  • 94
  • 159
  • for 2 - http://stackoverflow.com/questions/7348428/explicitly-drop-temp-table-or-let-sql-server-handle-it – Kritner Sep 18 '14 at 12:21
  • 1
    You could search for SPs where count of "create table" doesn't equal count of "drop table", but not sure if that would miss anything. – DavidG Sep 18 '14 at 12:23
  • @DavidG Yes, this is the kind of thing/query I am looking for. Even better if I can query for SPs which contain "create table #A" but which don't contain "drop table #A" in their bodies. – peter.petrov Sep 18 '14 at 12:30
  • Also, if possible, I want the query to not take into account `create table #A` and `drop table #A` statements which are within SQL comments (as these are not real `create`/`drop` occurrences after all). – peter.petrov Sep 18 '14 at 13:09

3 Answers3

2

1) probably no good / reliable way -- though you can extract the text of sp's using some arcane ways that you can find in other places.

2) In general - no this causes no problems -- temp tables (#tables) are scope limited and will be flagged for removal when their scope disappears.

and table variables likewise

an exception is for global temp tables (##tables) which are cleaned up when no scope holds a reference to them. Avoid those guys -- there are usually (read almost always) better ways to do something than with a global temp table.

Sigh -- if you want to go down the (1) path then be aware that there are lots of pitfalls in looking at code inside sql server -- many of the helper functions and information tables will truncate the actual code down to a NVARCHAR(4000)

If you look at the code of sp_helptext you'll see a really horrible cursor that pulls the actual text..

I wrote this a long time ago to look for strings in code - you could run it on your database -- look for 'CREATE TABLE #' and 'DROP TABLE #' and compare the outputs....

DECLARE @SearchString VARCHAR(255) = 'DELETE FROM'

SELECT
    [ObjectName]
    , [ObjectText]
FROM
    (
    SELECT
        so.[name] AS [ObjectName]
        , REPLACE(comments.[c], '#x0D;', '') AS [ObjectText]
    FROM
        sys.objects AS so
        CROSS APPLY ( 
            SELECT CAST([text] AS NVARCHAR(MAX))
            FROM syscomments AS sc
            WHERE sc.[id] = so.[object_id]
            FOR XML PATH('')
            )
            AS comments ([c])
    WHERE
        so.[is_ms_shipped] = 0
        AND so.[type] = 'P'
    )
    AS spText
WHERE
    spText.[ObjectText] LIKE '%' + @SearchString + '%'

Or much better - use whatever tool of choice you like on your codebase - you've got all your sp's etc scripted out into source control somewhere, right.....?

Transact Charlie
  • 2,195
  • 17
  • 14
  • 3
    Sorry, but how is pointing to `some arcane ways` helping? why not just write about it explicitly [like DavidG did](http://stackoverflow.com/a/25912859/2186023)? – DrCopyPaste Sep 18 '14 at 12:43
  • If you read all the comments below you can see that opening that can of worms leads to.... lots of worms.... Having had to parse sql text in the past inside sql server I didn't want to try and provide a 'solution' for (1) that I just don't think is useful -- if its not a problem (which it probably isn't as the temp tables are cleaned up after scope exit) then don't bother doing it. Or if you absolutely have to use some source control tool on your code base -- you've got a codebase right -- not just a bunch of code in the db and nowhere else. – Transact Charlie Sep 18 '14 at 13:53
  • but the fact it releases `lots of worms` is due to different possibilities how `CREATE` and `DROP` statements can be embedded into code not due to the fact that pulling data from sys-tables might be considered arcane ;) – DrCopyPaste Sep 18 '14 at 13:59
  • well yes there is that aspect of it -- but also that you can get an incorrect view of what your code is if you look at some of the views like INFORMATION_SCHEMA.ROUTINES for example. if you have long sp's you'll silently only get back the first 4000 characters.... I just don't think it's a great plan to do it unless there is a compelling reason. also -- if your code was sourcecontrolled somewhere you could probably write a really simple little script to scan all your files and check for unmatched create and drops – Transact Charlie Sep 18 '14 at 14:06
2

Not 100% sure if this is accurate as I don't have a good set of test data to work with. First you need a function to count occurrences of a string (shamelessly stolen from here):

CREATE FUNCTION dbo.CountOccurancesOfString
(
    @searchString nvarchar(max),
    @searchTerm nvarchar(max)
)
RETURNS INT
AS
BEGIN
    return (LEN(@searchString)-LEN(REPLACE(@searchString,@searchTerm,'')))/LEN(@searchTerm)
END

Next make use of the function like this. It searches the procedure text for the strings and reports when the number of creates doesn't match the number of drops:

WITH CreatesAndDrops AS (
SELECT  procedures.name,
        dbo.CountOccurancesOfString(UPPER(syscomments.text), 'CREATE TABLE #') AS Creates,
        dbo.CountOccurancesOfString(UPPER(syscomments.text), 'DROP TABLE #') AS Drops
FROM sys.procedures
JOIN sys.syscomments
    ON procedures.object_id = syscomments.id
    )

SELECT * FROM CreatesAndDrops
WHERE Creates <> Drops
Community
  • 1
  • 1
DavidG
  • 113,891
  • 12
  • 217
  • 223
  • I think this goes into the right direction, but for counting the occurences it might be a bit too naive. (what about tabs instead of spaces in statements for example? I think you should normalize the input data before applying `CountOccurancesOfString` like replacing all multiple consecutive occurences of tab and space by a single space; one might also argue that you would also not find create/drop statements hidden in binary form, but maybe that is taking it too far :D) – DrCopyPaste Sep 18 '14 at 12:48
  • 1
    @DrCopyPaste Absolutely. Also need to worry about SPs that have more than 4k characters and span multiple `syscomments` rows. – DavidG Sep 18 '14 at 12:50
  • Oh that's an interesting point; though I must say I am not sure if you're being ironic now or not, that actually seems important to me :D – DrCopyPaste Sep 18 '14 at 12:52
  • @DrCopyPaste Haha! I'm serious, though it's highly unlikely that the `CREATE` statement would span the boundary. – DavidG Sep 18 '14 at 12:54
  • Na, I disagree, especially when it comes to tasks where you want to check things that might not exist due to your own responsibility, I would be REALLY hesitant to call such a thing unlikely. – DrCopyPaste Sep 18 '14 at 13:01
  • @DavidG Thanks +1. This sounds close to what I need if not exactly the thing I need. I will see if I can give it a try soon. Does that procedure make sure the `create`/`drop` statements are not within comments? Even if not, it's close to my need so thanks again. – peter.petrov Sep 18 '14 at 13:04
  • @peter.petrov Yeah, this counts comments too unfortunately. You'd need a parsing system of some sort to get any cleverer, probably have to build a CLR procedure. – DavidG Sep 18 '14 at 13:11
1

I think SQL Search tool from red-gate would come handy in this case. You can download from here. This tool will find the sql text within stored procedures, functions, views etc...

Just install this plugin and you can find sql text easily from SSMS.

Krishnraj Rana
  • 6,516
  • 2
  • 29
  • 36
  • Thanks. Is this tool free? I was more like asking whether there's a SQL SELECT statement to do this job for me. – peter.petrov Sep 18 '14 at 12:32
  • @peter.petrov: yes its absolutely free tool. Of-course there is select statement is there. But i would prefer this tool. But its up-to you... – Krishnraj Rana Sep 18 '14 at 12:51