T-SQL: Show stored procedures related to tables, cyclically - sql

I'm using the following t-sql code:
USE [my_database]
SELECT DISTINCT so.name
FROM syscomments sc
INNER JOIN sysobjects so ON sc.id=so.id
WHERE sc.TEXT LIKE '%table_name%'
in order to show all the Stored Procedures that use the table table_name.
I want do this work for all tables in my database.
How can I perform this task and organize the output?

This uses information schema for both tables, and stored procedures. You can change or get rid of ROUTINE_TYPE condition to add functions, and you can change table type to return views.
This answer produces its results by checking what tables a stored procedure depends on. I think this will be a much more accurate result then checking if a name is in the query text. If the procedure refers to a table in a comment section, then this result will not be returned in the first query, but will be in the second and other answers given.
SELECT t.TABLE_NAME, s.ROUTINE_NAME
FROM INFORMATION_SCHEMA.TABLES t
INNER JOIN INFORMATION_SCHEMA.ROUTINES s ON
s.ROUTINE_NAME IN (SELECT referencing_entity_name
FROM sys.dm_sql_referencing_entities(TABLE_SCHEMA + '.' + TABLE_NAME, 'OBJECT'))
AND s.ROUTINE_TYPE = 'PROCEDURE'
WHERE t.TABLE_TYPE = 'BASE TABLE'
edit: Here's how to get the dependencies without the function. (I like this method the best)
SELECT DISTINCT t.name [TableName], p.name [ProcedureName]
FROM sys.objects t
LEFT JOIN sys.sql_dependencies d ON
d.referenced_major_id = t.object_id
LEFT JOIN sys.objects p ON
p.object_id = d.object_id
AND p.type = 'p'
WHERE t.type = 'u'
If your specific use is to just find any string that matches a table name, below will work:
SELECT t.TABLE_NAME, s.ROUTINE_NAME
FROM INFORMATION_SCHEMA.TABLES t
INNER JOIN INFORMATION_SCHEMA.ROUTINES s
ON CHARINDEX(t.TABLE_NAME, s.ROUTINE_DEFINITION) > 0
AND s.ROUTINE_TYPE = 'PROCEDURE'
WHERE t.TABLE_TYPE = 'BASE TABLE'

You could do a JOIN on LIKE:
select * from INFORMATION_SCHEMA.TABLES t
join
(
SELECT DISTINCT so.name
FROM syscomments sc
INNER JOIN sysobjects so ON sc.id=so.id
) x on x.name like '%' + t.TABLE_NAME + '%'
Note that your query doesn't restrict to procs - you'll also get views, defaults, and other objects too. If you just want procs, you can add where so.xtype = 'P' to your inner query.

Another version that uses sys tables only:
select t.name as TableName, p.name as SPName
from sys.objects t
join sys.syscomments c
on c.text like '%' + t.name + '%'
join sys.objects p
on p.object_id = c.id
where t.type = 'U' -- user table
and p.type = 'P' -- procedure

You can also use the built in function that's been around at least since SQL 2005 and works for tables, views, and stored procedures. I get the same number of results as Daniel's answer above when checking dependencies on a table in a fairly enterprisy database.
sp_depends [TableName]
sp_depends [TableName.Column]
sp_depends [StoredProcedureName]
http://msdn.microsoft.com/en-us/library/ms189487(v=sql.90).aspx

Related

How to get the TARGET tables from a stored procedure

I am aware of this query that can pull referenced tables from a SQL Server stored procedure.
For example, if I have this stored procedure:
UPDATE tbl1
SET symbol = tbl2.symbol, symbol2 = tbl2.symbol2
FROM tbl1
JOIN tbl2 ON tbl1.PK = tbl2.PK
This query:
SELECT Name
FROM sys.procedures
WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%TableNameOrWhatever%'
and this one:
SELECT
o.name
FROM
sys.sql_modules sm
INNER JOIN sys.objects o ON
o.object_id = sm.object_id
WHERE
sm.definition LIKE '%<table name>%'
both return tbl1 & tbl2 as the response.
My question is this: tb11 is ReadWrite as the SQL shows, and tbl2 is ReadOnly.
How do I update my queries to make the distinction?
So my output should be:
Response
========
tbl1, ReadWrite
tbl2, ReadOnly
Thanks!
Try sys.sql_dependencies, eg
select object_name(d.referenced_major_id) referenced_object,
object_name(d.object_id) referenced_by,
max(cast(d.is_updated as int)) is_updated
from sys.sql_dependencies d
join sys.objects o
on d.object_id = o.object_id
where o.type_desc = 'SQL_STORED_PROCEDURE'
group by d.referenced_major_id, d.object_id
order by d.object_id
But beware that procedures with deferred name resolution and stored procedures that access tables with dynamic SQL won't be tracked
The DMV sys.dm_sql_referenced_entities contains this information.
The following query should get you exactly what you need
SELECT
name,
referenced_entity_name,
is_updated
FROM sys.procedures p
CROSS APPLY sys.dm_sql_referenced_entities(SCHEMA_NAME(p.schema_id) + '.' + p.name,'OBJECT') r
WHERE referenced_minor_name IS NULL;
db<>fiddle

Trying to get the triggers associated with the table with a different schema name

I am trying to get the triggers of the table using this SQL statement:
SELECT c.text
FROM dbo.sysobjects s, dbo.syscomments c
WHERE s.name = 'redgate.tablecampare'
AND s.id = c.id
This works for dbo but not for different schema names
Assuming you're on SQL Server 2005 or greater, this should work:
select m.definition
from sys.triggers as t
join sys.sql_modules as m
on m.object_id = t.object_id
where t.parent_id = object_id('schema.object')
You can use below system catalog to find out triggers containing a specific table.
SELECT OBJECT_NAME(id)
FROM SYSCOMMENTS
WHERE [text] LIKE '%redgate.tablecampare%'
AND OBJECTPROPERTY(id, 'IsTrigger') = 1
GROUP BY OBJECT_NAME(id)
SELECT OBJECT_NAME(object_id)
FROM sys.sql_modules
WHERE OBJECTPROPERTY(object_id, 'IsTrigger') = 1
AND definition LIKE '%redgate.tablecampare%'

find all tables not referenced in stored procedures

I have sql server database with numerous tables, some no longer used so I want to remove them. All database interactivity is via stored procedure to these tables.
Is there a database sql script that I can use that will list all tables not referenced in any of the stored procedures in the database?
If SQL Server 2008 then the dependencies information is now reliable.
SELECT SCHEMA_NAME(t.schema_id),
t.name
FROM sys.tables t
WHERE is_ms_shipped = 0
AND NOT EXISTS (SELECT *
FROM sys.sql_expression_dependencies d
WHERE d.referenced_entity_name = t.name
AND (( is_ambiguous = 1 or is_caller_dependent=1)
OR
d.referenced_id = t.object_id) )
You can't do this if you use any dynamic T-SQL. Dynamic T-SQL won't show up in any investigation of object dependencies.
Instead, you can use the DMV sys.dm_db_index_usage_stats to find what objects haven't been referenced by any queries. Here's a query I did on SQLServerPedia for that:
http://sqlserverpedia.com/wiki/Find_Indexes_Not_In_Use
The query is designed for performance tuning indexes, so you'll need to tweak a few lines. Here's the modified query:
SELECT
o.name
, indexname=i.name
, i.index_id
, reads=user_seeks + user_scans + user_lookups
, writes = user_updates
, rows = (SELECT SUM(p.rows) FROM sys.partitions p WHERE p.index_id = s.index_id AND s.object_id = p.object_id)
, CASE
WHEN s.user_updates < 1 THEN 100
ELSE 1.00 * (s.user_seeks + s.user_scans + s.user_lookups) / s.user_updates
END AS reads_per_write
, 'DROP INDEX ' + QUOTENAME(i.name)
+ ' ON ' + QUOTENAME(c.name) + '.' + QUOTENAME(OBJECT_NAME(s.object_id)) as 'drop statement'
FROM sys.dm_db_index_usage_stats s
INNER JOIN sys.indexes i ON i.index_id = s.index_id AND s.object_id = i.object_id
INNER JOIN sys.objects o on s.object_id = o.object_id
INNER JOIN sys.schemas c on o.schema_id = c.schema_id
WHERE OBJECTPROPERTY(s.object_id,'IsUserTable') = 1
AND s.database_id = DB_ID()
ORDER BY reads
Keep in mind that this catches all indexes, and you'll need to sift through - some of your objects may be heaps, some may have clustered indexes, etc. I'll leave this as a wiki so someone more ambitious than me can edit it to build a deduped list. :-D
Check this discussion tsql script to find tables not being used by stored procedures, views, functions, etc?
And this article(listed from above discussion) http://www.mssqltips.com/tip.asp?tip=1294 discusses about SQL object dependencies.
Perhaps something along these lines:
select t.table_name
from INFORMATION_SCHEMA.TABLES t
where not exists (
select 1 from INFORMATION_SCHEMA.ROUTINES r
where object_definition(object_id(r.ROUTINE_NAME)) like '%'+t.TABLE_NAME+'%'
) order by t.TABLE_NAME
The first query lists table with the stored proc name that uses it.
The second query lists table with the number of stored procs using it.
-- list all tables / sprocs
select t.name [Table], p.name [StoredProc]
from sys.tables t
left join sys.procedures p on (OBJECT_DEFINITION(p.object_id)) like '%' + t.name + '%'
where t.type = 'U'
order by t.name, p.name
-- count stored procs using table
select t.name [Table], count(p.name) [Count]
from sys.tables t
left join sys.procedures p on (OBJECT_DEFINITION(p.object_id)) like '%' + t.name + '%'
where t.type = 'U'
group by t.name
order by t.name
Here's one you might try:
select
name
from
sys.tables t
left join
sys.sql_dependencies d
on
t.object_id =
d.referenced_major_id
where
d.referenced_major_id is null
Otherwise, here's a reference I've used in the past:
http://www.mssqltips.com/tip.asp?tip=1294
If performace isnt to much of a problem you could try the following.
Select Distinct Object_Name(ID)
From syscomments
Where ID Not In (Select ID From syscomments Where Text Like '%<TableName>%')
This will check each view, rule, default, trigger, CHECK constraint, DEFAULT constraint, and stored procedure within your database
Most of this code doesn't work if there are schemas other than "dbo", or if the user's default schema is not "dbo". Here's an update to one of the scripts to fix that:
select t.Table_Schema + '.' + t.table_name
from INFORMATION_SCHEMA.TABLES t
where not exists (
select 1 from INFORMATION_SCHEMA.ROUTINES r
where object_definition(object_id(r.routine_schema + '.' + r.ROUTINE_NAME)) like '%'+t.TABLE_NAME+'%'
) order by t.TABLE_NAME

Sql Query to list all views in an SQL Server 2005 database

I need an sql query to enumerate all views (I only need the view names) of a specific database in SQL Server 2005.
To finish the set off (with what has already been suggested):
SELECT * FROM sys.views
This gives extra properties on each view, not available from sys.objects (which contains properties common to all types of object) or INFORMATION_SCHEMA.VIEWS. Though INFORMATION_SCHEMA approach does provide the view definition out-of-the-box.
SELECT SCHEMA_NAME(schema_id) AS schema_name
,name AS view_name
,OBJECTPROPERTYEX(OBJECT_ID,'IsIndexed') AS IsIndexed
,OBJECTPROPERTYEX(OBJECT_ID,'IsIndexable') AS IsIndexable
FROM sys.views
SELECT *
FROM sys.objects
WHERE type = 'V'
Run this adding DatabaseName in where condition.
SELECT TABLE_NAME, ROW_NUMBER() OVER(ORDER BY TABLE_NAME) AS 'RowNumber'
FROM INFORMATION_SCHEMA.VIEWS
WHERE TABLE_CATALOG = 'DatabaseName'
or remove where condition adding use.
use DataBaseName
SELECT TABLE_NAME, ROW_NUMBER() OVER(ORDER BY TABLE_NAME) AS 'RowNumber'
FROM INFORMATION_SCHEMA.VIEWS
select v.name
from INFORMATION_SCHEMA.VIEWS iv
join sys.views v on v.name = iv.Table_Name
where iv.Table_Catalog = 'Your database name'
Some time you need to access with schema name,as an example you are using AdventureWorks Database you need to access with schemas.
SELECT s.name +'.'+v.name FROM sys.views v inner join sys.schemas s on s.schema_id = v.schema_id
Necromancing.
Since you said ALL views, technically, all answers to date are WRONG.
Here is how to get ALL views:
SELECT
sch.name AS view_schema
,sysv.name AS view_name
,ISNULL(sysm.definition, syssm.definition) AS view_definition
,create_date
,modify_date
FROM sys.all_views AS sysv
INNER JOIN sys.schemas AS sch
ON sch.schema_id = sysv.schema_id
LEFT JOIN sys.sql_modules AS sysm
ON sysm.object_id = sysv.object_id
LEFT JOIN sys.system_sql_modules AS syssm
ON syssm.object_id = sysv.object_id
-- INNER JOIN sys.objects AS syso ON syso.object_id = sysv.object_id
WHERE (1=1)
AND (sysv.type = 'V') -- seems unnecessary, but who knows
-- AND sch.name = 'INFORMATION_SCHEMA'
/*
AND sysv.is_ms_shipped = 0
AND NOT EXISTS
(
SELECT * FROM sys.extended_properties AS syscrap
WHERE syscrap.major_id = sysv.object_id
AND syscrap.minor_id = 0
AND syscrap.class = 1
AND syscrap.name = N'microsoft_database_tools_support'
)
*/
ORDER BY
view_schema
,view_name
This is old, but I thought I'd put this out anyway since I couldn't find a query that would give me ALL the SQL code from EVERY view I had out there. So here it is:
SELECT SM.definition
FROM sys.sql_modules SM
INNER JOIN sys.Objects SO ON SM.Object_id = SO.Object_id
WHERE SO.type = 'v'

List of Stored Procedure from Table

I have a huge database with 100's of tables and stored procedures. Using SQL Server 2005, how can I get a list of stored procedures that are doing an insert or update operation on a given table.
sys.sql_dependencies has a list of entities with dependencies, including tables and columns that a sproc includes in queries. See this post for an example of a query that gets out dependencies. The code snippet below will get a list of table/column dependencies by stored procedure
select sp.name as sproc_name
,t.name as table_name
,c.name as column_name
from sys.sql_dependencies d
join sys.objects t
on t.object_id = d.referenced_major_id
join sys.objects sp
on sp.object_id = d.object_id
join sys.columns c
on c.object_id = t.object_id
and c.column_id = d.referenced_minor_id
where sp.type = 'P'
select
so.name,
sc.text
from
sysobjects so inner join syscomments sc on so.id = sc.id
where
sc.text like '%INSERT INTO xyz%'
or sc.text like '%UPDATE xyz%'
This will give you a list of all stored procedure contents with INSERT or UPDATE in them for a particular table (you can obviously tweak the query to suit). Also longer procedures will be broken across multiple rows in the returned recordset so you may need to do a bit of manual sifting through the results.
Edit: Tweaked query to return SP name as well. Also, note the above query will return any UDFs as well as SPs.
Use sys.dm_sql_referencing_entities
Note that sp_depends is obsoleted.
MSDN Reference
You could try exporting all of your stored procedures into a text file and then use a simple search.
A more advanced technique would be to use a regexp search to find all SELECT FROM and INSERT FROM entries.
If you download sp_search_code from Vyaskn's website it will allow you to find any text within your database objects.
http://vyaskn.tripod.com/sql_server_search_stored_procedure_code.htm
This seems to work:
select
so.name as [proc],
so2.name as [table],
sd.is_updated
from sysobjects so
inner join sys.sql_dependencies sd on so.id = sd.object_id
inner join sysobjects so2 on sd.referenced_major_id = so2.id
where so.xtype = 'p' -- procedure
and is_updated = 1 -- proc updates table, or at least, I think that's what this means
SELECT Distinct SO.Name
FROM sysobjects SO (NOLOCK)
INNER JOIN syscomments SC (NOLOCK) on SO.Id = SC.ID
AND SO.Type = 'P'
AND (SC.Text LIKE '%UPDATE%' OR SC.Text LIKE '%INSERT%')
ORDER BY SO.Name
This link was used as a resource for the SP search.