Find objects that depend on a sp - sql

I use Microsoft SQL server. I have a db with hundreds of Stored Procedures. To find the dependencies, I can right click the SP, select view dependencies, and click objects that depend on [name].
I have this query to find all the stored procs
select * from INFORMATION_SCHEMA.ROUTINES where ROUTINE_TYPE = 'procedure'
and if I add this, I exclude every single system SP.
and LEFT(routine_name, 3) not in ('sp_','xp_','ms_')`
I would like to find ALL the SPs that no other proc/function/trigger depends on.
Ex: I have sproc1. In the right click + view dependencies I have at objects that depend on [sproc1] no elements, meaning that nothing depends on this SP.
Using a query to find procs that were unaltered for a year or more is not an option since some operations execute every leap year. Is there a way to write a query to determine the name of the stored proc and schema_id only for the stored procs that NOONE depend on? (having zero objects that depend on [this_sp] )

You can modify list of searched objects below:
SELECT *
FROM sys.objects o
WHERE NOT EXISTS
(
SELECT *
FROM sys.sql_expression_dependencies e
WHERE e.referenced_id = o.object_id
)
AND o.type IN (N'V', N'P', N'TF', N'IF', N'FN')

Related

How do I get a list of columns in a table or view?

On occasion, I'm interested in getting a list of columns in one of the tables or views in my SQL Server 2008 R2 database. It's useful, for example, if you're building database documentation without using an expensive off-the-shelf product.
What's an easy way to get this information?
In SQL Server 2008 R2 (among other versions), there are system views provided automatically with every database. As long as you are connected to the database where your table resides, you can run a query like this:
DECLARE #TableViewName NVARCHAR(128)
SET #TableViewName=N'MyTableName'
SELECT b.name AS ColumnName, c.name AS DataType,
b.max_length AS Length, c.Precision, c.Scale, d.value AS Description
FROM sys.all_objects a
INNER JOIN sys.all_columns b
ON a.object_id=b.object_id
INNER JOIN sys.types c
ON b.user_type_id=c.user_type_id
LEFT JOIN sys.extended_properties d
ON a.object_id=d.major_id AND b.column_id=d.minor_id AND d.name='MS_Description'
WHERE a.Name=#TableViewName
AND a.type IN ('U','V')
Of course, this is just a starting point. There are many other system views and columns available in every database. You can find them through SQL Server Management Studio under Views > "System Views
Another way is querying the INFORMATION_SCHEMA.columns view as detailed here:
Information_Schema - COLUMNS
This will give you information for all the columns in the current database (and what table/view they belong to) including their datatypes, precision, collation and whether they allow nulls etc
Usefully as well, these views are maintained in multiple DBMS programs too, so you could potentially use the same or similar query to get the same information regarding a MySQL database as you can a SQL Server DB, which could be useful if you are developing on multiple platorms.
sp_columns returns detailed information about each of the columns in the table. SO Answer
sp_columns #tablename
sp_help returns detailed information about the entire table including the columns and constraints. SO Answer
sp_help #tablename
To get a list of Columns of a view with some other information about the column you can use the following:
SELECT * FROM sys.columns c, sys.views v
WHERE c.object_id = v.object_id
AND v.name = 'view_Name'
GO
And if you only want the list of Column Name use this.
SELECT c.name
FROM sys.columns c, sys.views v
WHERE c.object_id = v.object_id
AND v.name = 'view_UserAssessphers'
GO
exec sp_helptext <your view name>
Also works for the view only, blachniet's answer is best if you need details on the columns in the table.
In a new query window, type the name of the view/table, highlight it, and press Alt-F1. This will run sp_help, like blachniet suggested.
simple list of column names without any further information.
SELECT COLUMN_NAME FROM TABLENAME.INFORMATION_SCHEMA.COLUMNS;
Replace TABLENAME with your tables name.

SQL Server 2008 Orphaned Stored Procedure?

I am using SQL Server 2008 through SQL Server Management Studio
I have never seen this before:
Often, when refactoring a database as I have been doing most of my day, I use the following to find references to columns, tables and other procedures in my existing procedures:
select *
from sys.sql_modules
where [definition] like '%SomethingImLookingFor%'
This is nothing special, I'm sure lots of database heads have done it before.
However, I noticed the results contained a procedure that looks to have been a total accident when created(If ever actually created). In the database I have a procedure named ChatObject_Remove, this appeared in my query because I was looking for anything referencing the term %Remove%. But I also see a ghost procedure called zzChatObject_Remove
In SSMS when I expand the database's Programmability -> Stored Procedures I see ChatObject_Remove, but not zzChatObject_Remove.
I have tried refreshing this group and the ghost still does not appear.
I tried to use the statement
drop procedure [dbo].[zzChatObject_Remove]
which returned an error saying it either didn't exist or I didn't have permission.
I tried to create a procedure called zzChatObject_Remove and it allowed me to do it (but now I had 2 objects in sql_modules with a definition for create procedure zzChatObject_Remove ...). I then deleted the new one which it allowed, and the ghost, as expected, is still in the modules table and I cannot touch it.
Has anyone seen this before? Where else could this be? Could it do any harm? How can I get rid of this seemingly orphaned procedure in the sys.sql_modules table?
Thanks in advance for any input.
Just my luck, seeing a ghost around Halloween time...
Try this to see where it comes up:
exec sp_MSforeachdb '
select ''?'' [db]
, s.name [schema]
, o.name [object]
, o.type_desc
from [?].sys.objects o
inner join sys.schemas s
on s.schema_id = o.schema_id
where o.name = ''zzChatObject_Remove''
'
Or the following:
select *
from sys.sql_modules sm
inner join sys.objects o
on o.object_id = sm.object_id
inner join sys.schemas s
on s.schema_id = o.schema_id
where sm.description like '%zzChatObject_Remove%'
Also, to check, is this proc defined in sql_modules, or is it showing because it's referenced in the code of another procedure?

Oracle Table Usage Across Stored Procedures

I have a 11G database. I need to examine a number of stored procedures to see if they use a particular table. (Both front end and back end sps) I have full access to the database, and I also have a copy of all the individual sps for the project which are stored on a TFS.
I would like a way to generate a list of all the sps that interact with this particular table. I'm unfamiliar with how to go about searching for these. Can anyone advise the most logical way of obtaining this data?
Thanks.
If I understand this correctly, you're trying to search for occurrence of a table in all stored procs. In that case, you can use this query:
When searching for occurrences of SP in your schema
SELECT * FROM user_source WHERE text LIKE '%tab_name%';
When searching for occurrences of SP in all schemas
SELECT * FROM all_source WHERE text LIKE '%tab_name%';
Two things, in PL/SQL there are some changes which will require the recompilation of pl/sql object, other don't.
To see the first one, you have the ALL_DEPENDENCIES view. Or DBA_ if you prefer.
If you just want to see where the table name appears in all the pl/sql code, whether a change to the table will require recompilation or not, you can use ALL_SOURCE using a upper and %, but it might take some time.
I use PLSQL Developer, in which you can browse to a table (or other object), and view 'Referenced by', to see all objects that refer to the table. That's about as easy as it gets.
I can imagine other tools have similar features.
I don't know if this pre-parsed information is readily available in Oracle, but I can imagine so, since those tools seem to work pretty fast.
This information is available in the viewAll_DEPENDENCIES, which these tools probably use.
The source of stored procedures can be found in the USER_SOURCE (or ALL_SOURCE) view, in which the structure of the entire database is stored. Nevertheless, fetching and parsing the code from there would be quite cumbersome.
Here is snippet I wrote to perform impact analysis (ONLY MERGE, INSERT and UPDATE) for a given #schema (upper case only) and #table (upper case only). It will return all the procedure name, procedure code, from line number and to line number along with other details. It can be easily used to include functions objects as well instead of package. am working on a utility that can run across all schema or selected schema (that will include SELECT rows as well). Though this will be good enough for you to start working.
I know you can use the dependency and references available in Oracle to perform similarly. But for package level impact this is good addition. We can also use regex for more complex searches. But like operator is simple and efficient for my needs.
Note, this doesn't work on any dynamic code that may be working in your environment. This is just a appropriate starting point for quick one on impact with static PL/SQL code in your packages.
WITH TableDep as
-- This table returns references where the table is used within the code for UPDATE OR INSERT
(
SELECT
owner as schemaname,
name as packagename,
type as typename,
TEXT as refcodeline,
CASE WHEN upper(text) LIKE '%INSERT%' THEN 'INSERT'
WHEN upper(text) LIKE '%UPDATE%' THEN 'UPDATE'
WHEN upper(text) LIKE '%MERGE%' THEN 'MERGE'
END AS opr,
:Tablename AS Tablename,
line refline
FROM dba_source WHERE upper(owner) = upper(:OWNER)
AND type = 'PACKAGE BODY'
AND (
upper(text) LIKE ('%INSERT INTO '||:Tablename||'%')
OR
upper(text) LIKE ('%UPDATE%'||:Tablename||' %')
OR
upper(text) LIKE ('%MERGE%'||:Tablename||' %')
)
),
ProcedureDetails as
-- This code build all procedures within the package for references that is found in above query
(
SELECT
owner as schemaname,
name as packagename,
type as typename,
TEXT,
trim(REGEXP_SUBSTR(TEXT, '(PROCEDURE [[:print:]]+)\(',1,1,null,1)) as procedure_name,
line startline,
LEAD(line, 1) OVER (partition by name order by line)-1 as endline
FROM dba_source
WHERE owner = upper(:OWNER)
AND type = 'PACKAGE BODY'
AND upper(text) LIKE '%PROCEDURE%(%'
and exists (SELECt 1 FROM TableDep WHERE TableDep.packagename=name)
)
,ProcCode as
-- This code builds procedures into one cell per program for a given package. Later to find the effected procedures
(
SELECT
ProcTag.packagename ,
ProcTag.schemaname,
ProcTag.typename,
ProcTag.PROCEDURE_NAME,
ProcTag.startline,
ProcTag.endline,
TO_CLOB(rtrim(xmlagg(xmlelement(e,codeline.text).extract('//text()') order by line).GetClobVal(),',')) as Procedure_Code
FROM
ProcedureDetails ProcTag
INNER JOIN dba_source codeline ON ProcTag.packagename=codeline.name
AND ProcTag.schemaname=codeline.owner
and ProcTag.typename=codeline.type
and codeline.line between ProcTag.startline and ProcTag.endline
--WHERE PROCEDURE_NAME='PROCEDURE TRANS_KAT_INSO'
group by
ProcTag.packagename ,
ProcTag.schemaname,
ProcTag.typename,
ProcTag.PROCEDURE_NAME,
ProcTag.startline,
ProcTag.endline
)
-- extract all the reference code for the given table selected with it complete procedure code.
SELECT
ProcHeader.Packagename, ProcHeader.schemaname, ProcHeader.typename, ProcHeader.procedure_name, ProcHeader.Procedure_Code ,ProcHeader.startline,ProcHeader.endline,ProcReference.Tablename, ProcReference.opr
FROM
ProcCode ProcHeader
INNER JOIN
(
SELECT DISTINCT ProcCode.Packagename, ProcCode.schemaname, ProcCode.typename, ProcCode.procedure_name , TableDep.Tablename, TableDep.opr
FROM ProcCode
INNER JOIN TableDep ON ProcCode.packagename=TableDep.packagename
AND ProcCode.schemaname=TableDep.schemaname
and ProcCode.typename=TableDep.typename
and TableDep.refline between ProcCode.startline and ProcCode.endline
) ProcReference
ON ProcHeader.Packagename=ProcReference.Packagename
AND ProcHeader.schemaname=ProcReference.schemaname
AND ProcHeader.typename=ProcReference.typename
AND ProcHeader.procedure_name=ProcReference.procedure_name
;
This question already have an accepted answer but anyhow the query used inside the accepted answer will pick all the user sources which uses the particular table.
Because the question is specific about Procedures you can go for the below query to get the result
SELECT * FROM user_source WHERE text LIKE '%YourTableName%' and TYPE='PROCEDURE';

How to find which views are using a certain table in SQL Server (2008)?

I have to add a few columns to a table and I also need to add these columns to all the views that use this table.
Is it possible to get a list of all the views in a database that use a certain table?
This should do it:
SELECT *
FROM INFORMATION_SCHEMA.VIEWS
WHERE VIEW_DEFINITION like '%YourTableName%'
To find table dependencies you can use the sys.sql_expression_dependencies catalog view:
SELECT
referencing_object_name = o.name,
referencing_object_type_desc = o.type_desc,
referenced_object_name = referenced_entity_name,
referenced_object_type_desc =so1.type_desc
FROM sys.sql_expression_dependencies sed
INNER JOIN sys.views o ON sed.referencing_id = o.object_id
LEFT OUTER JOIN sys.views so1 ON sed.referenced_id =so1.object_id
WHERE referenced_entity_name = 'Person'
You can also try out ApexSQL Search a free SSMS and VS add-in that also has the View Dependencies feature. The View Dependencies feature has the ability to visualize all SQL database objects’ relationships, including those between encrypted and system objects, SQL server 2012 specific objects, and objects stored in databases encrypted with Transparent Data Encryption (TDE)
Disclaimer: I work for ApexSQL as a Support Engineer
If you need to find database objects (e.g. tables, columns, triggers) by name - have a look at the FREE Red-Gate tool called SQL Search which does this - it searches your entire database for any kind of string(s).
It's a great must-have tool for any DBA or database developer - did I already mention it's absolutely FREE to use for any kind of use??
I find this works better:
SELECT type, *
FROM sys.objects
WHERE OBJECT_DEFINITION(object_id) LIKE '%' + #ObjectName + '%'
AND type IN ('V')
ORDER BY name
Filtering VIEW_DEFINTION inside INFORMATION_SCHEMA.VIEWS is giving me quite a few false positives.
SELECT VIEW_NAME
FROM INFORMATION_SCHEMA.VIEW_TABLE_USAGE
WHERE TABLE_NAME = 'Your Table'
select your table -> view dependencies -> Objects that depend on
Simplest way to find used view or stored procedure for the tableName using below query -
exec dbo.dbsearch 'Your_Table_Name'

SQL script to change all table references in all stored procedures

I have created a new database with copies of existing tables but changed the names of these tables, is there a SQL script that I can run (maybe using SysObjects) to change all references to these tables in all stored procedures?
DO NOT RELY ON INFORMATION_SCHEMA.ROUTINES because ROUTINE_DEFINITION is only nvarchar(4000). You need to sys.sql_modules where definition is nvarchar(max)
try any of these to find the procedure that you need to modify:
SELECT DISTINCT
LEFT(s.name+'.'+o.name, 100) AS Object_Name,o.type_desc --, m.definition
FROM sys.sql_modules m
INNER JOIN sys.objects o ON m.object_id=o.object_id
INNER JOIN sys.schemas s ON o.schema_id=s.schema_id
WHERE m.definition Like '%'+#SearchValue+'%'
ORDER BY 1
SELECT
OBJECT_SCHEMA_NAME(m.object_id)+'.'+OBJECT_NAME(m.object_id) --, m.definition
FROM sys.sql_modules m
WHERE m.definition like '%whatever%'
SELECT
OBJECT_SCHEMA_NAME(m.object_id)+'.'+OBJECT_NAME(m.object_id), o.type_desc
--,m.definition
FROM sys.sql_modules m
INNER JOIN sys.objects o ON m.object_id=o.object_id
WHERE m.definition like '%whatever%'
you can uncomment m.definition to list out the content, but I find it better to just ID all the procedures and then review them manually, because you don't want to run UPDATE commands on the system tables. Script out the necessary procedures, make the changes (search/replace or manually), and then run the scripts!!!
No.
I believe SQL Refactor from Redgate has this functionality. Otherwise you could script out all objects and either manually or via code do a search and replace.
SQL Server 2005 also has support for synonyms that might be of some help.
Here is a chunk of SQL that you could use to retrieve the definition of stored procedures that match a certain search criteria. You could simply change it to do a search and replace like Martin had suggested.
Simply change '%TABLE_NAME%' to your search criteria or the table name you would like to change.
SELECT ROUTINE_NAME, ROUTINE_DEFINITION
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_DEFINITION LIKE '%TABLE_NAME%' AND ROUTINE_TYPE='PROCEDURE'
If it's short term (like a testing database), the easier solution may be to make a VIEW for each table that you changed, using the old name. For instance, if you changed the table tests to tests_new you can do:
CREATE VIEW dbo.tests
AS
SELECT * FROM dbo.tests_new
All your procedures will that reference dbo.tests will actually look at the data in dbo.tests_new.
This is a very very bad idea if this will be a permanent/production DB, as it just adds a layer of obfuscation to your structure and will make it a nightmare to maintain.
You can't change the table references in sprocs through the system data dictionary - you will have to get the script that creates the stored procedure and change the table names in the script. If you have the scripts this is a simple search and replace for the most part.
If you don't have the scripts you can get the text of the stored procedure scripts from sys.sql_modules, or retrieve it through SSMS.