I'm in the middle of cleaning some servers. So currently this is my server (sorry for the lame diagram):
DatabaseServer00
-DatabaseA
-ViewA
-ViewB
-ViewC
-DatabaseB
-DatabaseC
I need to find if there is any sp/triger/function/etc... in DatabaseB/C that calls ViewA from DatabaseA.
I know that i can find dependencies in DatabaseA with this sp_depends
And I'm currently using this to search in other DB
Declare #Query varchar(max)
SET #Query = 'SELECT DISTINCT o.name AS Object_Name,o.type_desc FROM
sys.sql_modules m INNER JOIN sys.objects o ON m.object_id=o.object_id
WHERE m.definition like ''%ViewA%'''
EXEC sp _MSforeachdb #Query
But.... This code right here ^ does not returns me that ViewB depends on ViewC
So i'm kind of out of queries to run. Thanks in advance for your help.
Take a look at the Information Schema Views, they should be able to help you in most cases except the Triggers, which you'll probably have to rely on sys.triggers
SELECT * FROM information_schema.routines ISR
WHERE CHARINDEX('dbo.ViewA', ISR.ROUTINE_DEFINITION) > 0
SELECT * FROM INFORMATION_SCHEMA.VIEWS ISW
WHERE CHARINDEX('dbo.ViewA', ISW.VIEW_DEFINITION) > 0
SELECT
DB_NAME() AS DatabasName
, so.name as TableName
, tr.name as TriggerName
, sc.text as TriggerText
FROM sys.triggers tr
INNER JOIN sys.objects so
ON tr.parent_id = so.object_id
INNER JOIN syscomments sc
ON sc.id = tr.object_id
WHERE CHARINDEX('dbo.ViewA', sc.text) > 0
Related
I want to create a stored procedure SP1 which will have script to fetch data from sys schema. But this stored procedure would be called by users who do not have permissions on the sys schema. How can I achieve this?
I am doing this basically to mask the entire sys schema from that user but at the same time allowing him to see minimal info.
Basically I want this inside SP
--Displays Object information
SELECT m.object_id [ObjID]
,o.type_desc [ObjType]
,o.name [ObjectName]
,e.last_execution_time [LastExecutedOn]
,create_date [CreatedOn]
,modify_date [ModifiedOn]
, DEFINITION [Data]
FROM sys.SQL_MODULES m
JOIN sys.OBJECTS o
ON m.object_id=o.object_id
LEFT JOIN sys.dm_exec_procedure_stats e
ON e.object_id=o.object_id
WHERE DEFINITION LIKE '%'+#SearchStr+'%'
ORDER BY o.name
I believe you could achieve this with a View rather than an SP, as per this question.
If you need to be able to pass a parameter as well for your #SearchStr variable, you could create an SP which queries the view accordingly. So your View would be:
CREATE VIEW vwObjectInfo
AS
SELECT m.OBJECT_ID [ObjID],
o.type_desc [ObjType],
o.name [ObjectName],
e.last_execution_time [LastExecutedOn],
create_date [CreatedOn],
modify_date [ModifiedOn],
[definition] [Data]
FROM sys.SQL_MODULES m
JOIN sys.OBJECTS o ON m.OBJECT_ID = o.OBJECT_ID
LEFT JOIN sys.dm_exec_procedure_stats e ON e.OBJECT_ID = o.OBJECT_ID
and your SP would be:
CREATE PROCEDURE spSearchObjectInfo
#SearchStr NVARCHAR(MAX)
AS
BEGIN
SELECT * FROM vwObjectInfo
WHERE Data LIKE '%' + #SearchStr + '%'
ORDER BY ObjectName
END
Your user should then be able to call the SP with their desired search string and get results with just the ability to SELECT from the View and EXECUTE the SP, like so:
EXEC spSearchObjectInfo 'Some Search String'
I cannot find a way to join objects using the database_id.
I am trying to write an audit query which scans through the tables by accepting the database name as parameter.
I want to avoid dynamic queries.
Is it possible?
like
SELECT *
FROM information_schema.tables a
JOIN sys.tables b
ON a.datbase_id = b.database_id
AND b.database_name = 'testdb'
Give this a go.
select *
from
INFORMATION_SCHEMA.TABLES it
inner join sys.tables st
on st.name = it.table_name
where it.TABLE_CATALOG = 'testdb'
First of all, there is no such column as database_id in information_schema.tables. Secondly there is an undocumented stored proc called sp_msForEachDb, which iterates through all the database one by one and runs the script that you want to, which you need to pass as a string input to it.
In your case, it seems that you want to join the information_schema.tables with sys.tables and list the tables for testDB database. Try the script below for that:
--Build a temp table to store the info
select * into #a
from INFORMATION_SCHEMA.TABLES it join sys.tables st
on st.name COLLATE SQL_Latin1_General_CP1_CI_AS= it.table_name COLLATE SQL_Latin1_General_CP1_CI_AS
where 1=0
insert into #a --This script runs for each database and populates the info into #a
EXECUTE master.sys.sp_MSforeachdb
'select * from INFORMATION_SCHEMA.TABLES it join [?].sys.tables st
on st.name COLLATE SQL_Latin1_General_CP1_CI_AS= it.table_name COLLATE SQL_Latin1_General_CP1_CI_AS
where it.TABLE_CATALOG = ''testdb'''
select * from #a
In SSMS, I create a database using the following script. When the script execution completes, I would expect to see the CREATE TABLE statement in the sql_modules table. However I can't find it.
CREATE DATABASE [MyDb]
GO
USE [MyDb]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[MyTable] (
[UID] [uniqueidentifier] NOT NULL,
[DateTime] [datetime] NOT NULL
)
Here's the query I run the get the table definition. However, I get three empty result sets. Any idea why I am getting those three empty results set?
USE MyDb
GO
SELECT *
FROM sys.sql_modules
SELECT *
FROM sys.triggers
SELECT sm.object_id, OBJECT_NAME(sm.object_id) AS object_name, o.type, o.type_desc, sm.definition
FROM sys.sql_modules AS sm
JOIN sys.objects AS o ON sm.object_id = o.object_id
ORDER BY o.type;
To get columns and table information, this is a good place to start:
SELECT c.*, t.*
FROM sys.tables AS t
INNER JOIN sys.columns AS c ON t.object_id = c.object_id
INNER JOIN sys.schemas AS sch ON t.schema_id = sch.schema_id
WHERE sch.name = 'dbo'
AND t.name = 'YourTable'
I want to find all of the stored procedures where a particular table is being used. There are lots of stored procedures in the database, so it's not feasible to check each procedure.
Is there any way to use a search query so that I can find the stored procedures?
I have tried this code:
SELECT distinct so.name
FROM syscomments sc
INNER JOIN sysobjects so ON sc.id=so.id
WHERE sc.TEXT LIKE '% RejectionReason %'
Where RejectionReason is my table name, but it shows all procedures where RejectionReason is used as column name, so that doesn't work.
SELECT o.name, o.type_desc, p.name, p.type_desc
FROM sys.sql_dependencies d
INNER JOIN sys.objects o
ON d.object_id = o.object_id
INNER JOIN sys.objects p
ON d.referenced_major_id = p.object_id
AND o.name = 'RejectionReason'
or
SELECT o.name, t.TABLE_NAME, c.text
FROM syscomments c
JOIN sysobjects o
ON c.id = o.id
JOIN INFORMATION_SCHEMA.Tables t
ON c.text LIKE '%RejectionReason%'
or
EXEC sp_depends #objname = N'RejectionReason';
if none of those help you check this blog:
http://blog.sqlauthority.com/2010/02/04/sql-server-get-the-list-of-object-dependencies-sp_depends-and-information_schema-routines-and-sys-dm_sql_referencing_entities/
Try to use RedGate's free tool SQL Search.
Here is a piece of code hope it will work. Just changes the table name it depends upon your code
SELECT DISTINCT so.name
FROM syscomments sc INNER JOIN sysobjects so on sc.id=so.id
WHERE sc.text LIKE '%tablename%'
e.g.:
SELECT DISTINCT so.name
FROM syscomments sc INNER JOIN sysobjects so on sc.id=so.id
WHERE sc.text LIKE '%users%'
You will get the list of store procedures and the table relations.
As per MSDN sp_depends will be removed in future releases in case you are using that, you can use the following query instead:
SELECT referencing_schema_name, referencing_entity_name, referencing_id, referencing_class_desc, is_caller_dependent
FROM sys.dm_sql_referencing_entities ('dbo.TableName', 'OBJECT');
There are two possibilities I am aware of.
Firstly SQL Management Studio has an option to show Dependencies. Right-click on the Table and select View Dependencies However, this will not highlight usps where the tablename is embedded in dynamic SQL.
The second option is to right click on the database and select Generate Scripts. Follow the wizard and script all the usps to a new query window, then search that for the name of your table. This is more laborious, but will find all uses.
I guess this script shows all the dependent object of the table, including SPs.
USE MYDatabase
GO
DECLARE #TableName varchar(100)
SET #TableName = 'mytable'
SELECT
SourceSchema = OBJECT_SCHEMA_NAME(sed.referencing_id)
,SourceObject = OBJECT_NAME(sed.referencing_id)
,ReferencedDB = ISNULL(sre.referenced_database_name, DB_NAME())
,ReferencedSchema = ISNULL(sre.referenced_schema_name,
OBJECT_SCHEMA_NAME(sed.referencing_id))
,ReferencedObject = sre.referenced_entity_name
,ReferencedColumnID = sre.referenced_minor_id
,ReferencedColumn = sre.referenced_minor_name
FROM sys.sql_expression_dependencies sed
CROSS APPLY sys.dm_sql_referenced_entities(OBJECT_SCHEMA_NAME(sed.referencing_id)
+ '.' + OBJECT_NAME(sed.referencing_id), 'OBJECT') sre
WHERE sed.referenced_entity_name = #TableName
AND sre.referenced_entity_name = #TableName
for more details you can check out.
http://sqlserverplanet.com/sql-server-2008/find-dependent-objects/
This will return SP's and Views.
SELECT DISTINCT o.name AS Object_Name,o.type_desc
FROM sys.sql_modules m
INNER JOIN sys.objects o
ON m.object_id=o.object_id
WHERE m.definition Like '%TableName%'
SysObjects stores basic information about all objects inside your database. It's useful for you to know because it tells us the name of each object and the type of the object.
SysComments stores the actual text (code) for your stored procedures and functions. It contains an ID field that maps back to the id field in SysObjects.
select so.name, text
from sysobjects so, syscomments sc
where so.id = sc.id
and text like '%RejectionReason%'
I am using the following SQL script to search for column names and text inside all stored procedures of your database. You can use it as well to find tables in stored procedures.
Specify the search term in variable #SearchFor(as you would use it in a LIKE expression, e.g. '%LastName%' to find columns and stored procedures containing LastName).
It will find column names in tables as well as text inside stored procedures. The script can even display the SP source code, if you set #SPNameOnlyto 0.
--
-- Purpose: Search field names in all tables, views stored procedures
--
DECLARE #SearchFor nvarchar(max)='%Search_SP_Or_Table_Or_View%' -- search for this string
DECLARE #SearchSP bit = 1 -- 1=search in SPs as well
DECLARE #DisplaySPSource bit = 1 -- 1=display SP source code
-- tables
if (#SearchSP=1) begin
(
select '['+c.table_Schema+'].['+c.table_Name+'].['+c.column_name+']' [schema_object],
t.table_type
from information_schema.columns c
left join information_schema.Tables t on c.table_name=t.table_name
where column_name like #SearchFor or t.table_name like #SearchFor
UNION
select '['+routine_Schema+'].['+routine_Name+']' [schema_object],
'PROCEDURE' as table_type from information_schema.routines
where routine_definition like #SearchFor or routine_name like #SearchFor
and routine_type='procedure'
)
order by table_type, schema_object
end else begin
select '['+c.table_Schema+'].['+c.table_Name+'].['+c.column_name+']' [schema_object],
t.table_type
from information_schema.columns c
left join information_schema.Tables t on c.table_name=t.table_name
where column_name like #SearchFor or t.table_name like #SearchFor
order by c.table_Name, c.column_name
end
-- stored procedure (source listing)
if (#SearchSP=1) begin
if (#DisplaySPSource=1) begin
select '['+routine_Schema+'].['+routine_Name+']' [schema.sp], routine_definition
from information_schema.routines
where routine_definition like #SearchFor or routine_name like #SearchFor
and routine_type='procedure'
order by routine_name
end
end
Im working on this large DB which has a lot of the business knowledge embedded in the SPs[I know!] and there is a lot of chaining between the SPs. i.e one stored proc calling another.
Im want to find out a list of stored procedures which update a particular column. How would I do that.
Using showplan_All as outlined in
SQL Table and column Parser for stored procedures doesnt work for me, because this is a shared dev db.
using a Sp from master db scanning system text as described is not feasible because I dont have access to the master db.
So how can I find this informaion?
From system view sys.sql_dependencies you can get dependencies at column level.
DECLARE #Schema SYSNAME
DECLARE #Table SYSNAME
DECLARE #Column SYSNAME
SET #Schema = 'dbo'
SET #Table = 'TableName'
SET #Column = 'ColumnName'
SELECT o.name
FROM sys.sql_dependencies AS d
INNER JOIN sys.all_objects AS o ON o.object_id = d.object_id
INNER JOIN sys.all_objects AS ro ON ro.object_id = d.referenced_major_id
INNER JOIN sys.all_columns AS c ON c.object_id = ro.object_id AND c.column_id = d.referenced_minor_id
WHERE (SCHEMA_NAME(ro.schema_id)=#Schema)
and o.type_desc = 'SQL_STORED_PROCEDURE'
and ro.name = #Table
and c.name = #Column
GROUP BY o.name
Have you tried this : EXEC sp_depends #objname = [table name of the column you are interested in].
So for example, if you had a column named Price in a table named Product, you would execute this: EXEC sp_depends #objname = N'Product'.
Simply executing this would give you list of all sps, views, etc which depend on that particular table.
I use this all the time as I work with a db which has over 400 tables :-)
sp_depends page on MSDN
Try something like this:
use YourDatabase;
select [Name]
from sys.procedures
where object_definition([object_id]) like '%YourColumnName%';
Obviously this has the potential to generate a lot of false positives depending on what the column is named but at least you will have a list of procedures to sift through.
Here's one that works in SQL 2000+; Note that as Andrew noted in his, you will get false positives depending on your column name, but it's a starting place:
SELECT DISTINCT o.Name
FROM syscomments c
JOIN sysobjects o ON c.ID = o.ID
WHERE c.Text LIKE '%ColumnName%'
ORDER BY o.Name
use msdb
go
select * from sysjobs j
inner join sysjobsteps s
on j.job_id=s.job_id
where command like '%HBR_INSTRUMENT%'