September 19, 2007 at 10:30 am
I need to extract data from the sysobjects and syscomments tables for all of the user defined functions and user defined stored procedures in a given database. I am using the code below, which mostly works fine (the name of the selected database has been previously SET into @CurrentDb). However, I have noticed that recently created stored procedures in recently created databases are not being captured by this code, even though their records are present in the sysobjects and syscomments tables. I've also noticed that these "missing" stored procedures have sysobjects.status set to 0. I cannot find any documentation for that field, nor will SQL Server allow me to manually edit it. Does anyone know how I can get around this problem, so that my routine will capture all of the user defined functions and user defined stored procedures?
TRUNCATE TABLE _EmbeddedSearchRoutines
SET @sql =
'INSERT INTO _EmbeddedSearchRoutines
SELECT O.[id], C.number, C.colid, O.[name], O.xtype, O.crdate,
ObjectType =
CASE
WHEN O.xtype = ''P'' THEN ''Stored Procedure''
ELSE ''Function''
END,
LEN(C.[text]) AS LenText, LenReal = DATALENGTH(c.[Text]), [Text] = CAST(c.[Text] AS VARCHAR(4000))
FROM ' + @CurrentDb + '..sysobjects AS O
INNER JOIN syscomments AS C
ON O.[id] = C.[id]
WHERE (O.xtype IN (''P'', ''FN'', ''IF'', ''TF''))
AND (OBJECTPROPERTY(O.ID,''IsMsShipped'') = 0)
ORDER BY ObjectType DESC, O.[name], O.[id], C.number, C.colid'
EXEC (@SQL)
September 19, 2007 at 11:56 am
Where does the code run from? Since there is no "USE" in the @sql string, I'm guessing that this runs from a single location, and if that's the case, I see at least one issue, your join on syscomments. While you fully qualify sysobjects, you don't do the same with syscomments.
September 19, 2007 at 12:10 pm
You've once again proved the value of a second pair of eyes. As soon I added the qualification to syscomments, the code picked up the "missing" stored procedure. Thank you, David!
September 19, 2007 at 12:22 pm
No problem at all.
You probably want to redo the ones you've already done, as the comments and objects, even though they found a match, aren't necessarily a correct match.
September 19, 2007 at 12:38 pm
Oops - I spoke too soon - making both tables qualified did cause a stored procedure to show up, but on closer examination it is NOT the user defined one I was looking for, but "dt_whocheckedout_u" which is apparently created by the system. So, I'm back to square one. Any other ideas?
September 19, 2007 at 1:29 pm
Are these databases, including the new ones, all on the same server? If so, is that server 2000 or 2005? Also, are these stored procedures owned by "dbo"?
September 19, 2007 at 1:34 pm
At this point, I'll be thrilled if I can get this working on a single server. All of our servers are SQL 2000. As far as I know (I'm pretty new here), all objects are owned by dbo.
September 19, 2007 at 2:21 pm
Take one of the stored proc that's not returning from your query, and find it in sysobjects and syscomments. Post the two rows here (you can trim the two columns with the proc text in them if you'd like, since they are nvarchar(4000).
September 19, 2007 at 3:15 pm
The two rows are below. I've found a workaround mentioned several places on the web, that seems to give me correct results, but I feel uneasy about it as it relies on an undocumented column (sysobjects.category). Basically, I changed:
WHERE (O.xtype IN ('P', 'FN', 'IF', 'TF'))
AND (OBJECTPROPERTY(O.ID, 'IsMsShipped') = 0)
to this:
WHERE (O.xtype IN ('P', 'FN', 'IF', 'TF'))
AND (O.category = 0)
row from sysobjects:
SP201977058079P 10016002007-09-19 11:36:36.5730160P 0402007-09-19 11:36:36.5730000000
row from syscomments:
19770580791120x4352454154452070726F63656475726520535032300D0A61730D0A73656C656374202A0D0A66726F6D207379736F626A656374732001CREATE procedure SP20 as select * from sysobjects
September 19, 2007 at 4:21 pm
That's a bit strange. Just for fun, try changing the line...
(OBJECTPROPERTY(O.ID, 'IsMsShipped') = 0)
to
(OBJECTPROPERTY(O.ID, 'IsMsShipped') <> 1)
I'm wondering if somehow a Null (or other non 0/1) value is slipping into that property. Alternatively, SELECT the ones equal to 1 and see if it shows up.
September 19, 2007 at 6:21 pm
Just curious... why names like "SP20" ... not exactly "self documenting"...
--Jeff Moden
Change is inevitable... Change for the better is not.
September 20, 2007 at 7:31 am
SP20 is just the name of a test stored procedure I threw together in about 45 seconds. Any objects not intended strictly for testing have appropriately self-documenting names.
September 20, 2007 at 7:38 am
David:
Changing
(OBJECTPROPERTY(O.ID, 'IsMsShipped') = 0)
to
(OBJECTPROPERTY(O.ID, 'IsMsShipped') 1)
produces the same results as before. I'm not sure what you mean by "Alternatively, SELECT the ones equal to 1", as I'm already doing that - the expression here is in the WHERE clause so it is already filtering the records to be selected.
September 20, 2007 at 7:58 am
I meant test if IsMSShipped is equal to 1 and see if your proc shows up. Since it's showing up when you remove the filter based on the IsMSShipped property, but doesn't show up when you test for 0 nor when you test for not equal to 1, it just about has to be set to 1 (or perhaps Null). I wanted to verify that that is the case.
September 20, 2007 at 8:02 am
Ok... thanks! I'll put my soapbox away
--Jeff Moden
Change is inevitable... Change for the better is not.
Viewing 15 posts - 1 through 15 (of 18 total)
You must be logged in to reply to this topic. Login to reply