How to select database name in sys.dm_* - sql

I'm calling stored proc through a service. I wanted my stored proc to be running on a database.
I've two questions
Is sys.dm_* tables specific to a database or it is general one?
select * FROM sys.dm_exec_requests
Does above query return requests of all the databases or the current database where the query is being executed?
If sys.dm_* specific to a database is there any way to specify the database through stored procedure. I'm aware that we cannot use use. and select * FROM [dbname].sys.dm_exec_requests isn't working it seems. It returns the result for the current DB it seems. I may be wrong here.

It looks like the dm_* tables are global to the system. The statement select * from [dbname].sys.dm_exec_requests returns data for all databases on the server. If the table contains database specific data, then it will include a database_id field.
If you want to limit the data your stored procedure returns to just one database, then you have to qualify by database_id. Both of the following statements work in stored procedures:
/* specify the database name manually */
declare #db_name sysname = 'master'
select *
from sys.dm_exec_requests er
inner join sys.databases d on er.database_id = d.database_id
where d.name = #db_name
/* gets the database name for the current database */
select *
from sys.dm_exec_requests er
inner join sys.databases d on er.database_id = d.database_id
where d.name = db_name()

Related

How to avoid showing result-window if there are no results to show?

I have a script which searches through all the available databases (those I have access to) for a specific text in a procedure.
In my server, there are many databases (in my case about 150 databases), meaning that I get shown the results for all databases eventhough there are no results for most of them (about 90%).
Is there any way to avoid getting these empty result-queries?
You can use below code to check whether stored procedure contains a text in each database. If there are stored procedures in a database only, you will have resultset.
CREATE TABLE ##DatabasesContainingSP(dbname sysname, SPName SYSNAME);
EXECUTE master.sys.sp_MSforeachdb 'USE [?];
INSERT INTO ##DatabasesContainingSP
SELECT DISTINCT
db_name() as dbname, o.name AS Object_Name
FROM sys.sql_modules m
INNER JOIN
sys.objects o
ON m.object_id = o.object_id
WHERE m.definition Like ''%ABC%'';
'
IF EXISTS(SELECT * FROM ##DatabasesContainingSP )
begin
SELECT * FROM ##DatabasesContainingSP
end
GO
IF OBJECT_ID('tempdb..##DatabasesContainingSP' , 'U') IS NOT NULL
drop TABLE ##DatabasesContainingSP;
Thank you for the quick responses.
I managed to solve it by creating a table and adding insert into this table in the beginning of my generated and concatenated code, which solved the problem since when reading the table in the end, it only shows the inserted results.
With kind regards,
Alexander

List out stored procedures with in the stored procedure in sql server

SQL stored procedures used some inner stored procedures.so I want to get all inner used stored procedures list in specific stored procedure in SQL server.i am using SQL server 2008.please help to find this solution.
use this to find the dependency
EXEC sp_depends #objName = N'Stored_Procedure_Name'
You can use the information_schema.routines combined with sys.sql_expression_dependencies - but you need it in a recursive fashion.
with recursedProcs(code_database, ancestorName, object, Recursion, procpath)
as
(
select isr.specific_catalog as code_database, isr.[specific_name] as ancestorName, cast(isr.specific_name as varchar(200)) as object, 1 as Recursion, cast(isr.specific_name as varchar(200)) as procpath
from information_schema.routines isr with (nolock)
union all
select p.code_database, p.ancestorName, cast(d.referenced_entity_name as varchar(200)), p.recursion + 1, cast(p.procpath + '/' + cast(d.referenced_entity_name as varchar(200)) as varchar(200))
from recursedProcs p
inner join sys.sql_expression_dependencies d on d.referencing_id = OBJECT_ID(p.object)
where p.recursion < 20
and d.referenced_id <> object_id(p.object)
)
select * from recursedProcs
This recurses down every procedure in the database, through sub-procedures and finally to the tables that a procedure depends on. From this starting point you can refine it to suit your needs. (If you have more than 20 levels deep of sub-procedures, you will also need to add a maxrecursion option and remove the <20 predicate)
sp_depends is deprecated going forward and does currently have the ability to give incorrect answers.

Store a database name in variable & then using it dynamically

I have a Table in my Database Which have name of all the Database of my Server
Table Look like
create Table #db_name_list(Did INT IDENTITY(1,1), DNAME NVARCHAR(100))
INSERT INTO #db_name_list
SELECT 'db_One ' UNION ALL
SELECT 'db_Two' UNION ALL
SELECT 'db_Three' UNION ALL
SELECT 'db_four' UNION ALL
SELECT 'db_five'
select * from #db_name_list
I have so many SP in my Database..Which uses multiple table and Join Them..
At Present I am using the SQL code like
Select Column from db_One..Table1
Left outer join db_two..Table2
on ....some Condition ....
REQUIREMENT
But I do not want to HARDCODE the DATABASE Name ..
I want store DataBase name in Variable and use that .
Reason :: I want to restore same Database with Different name and want to Run those SP..At Present we Cant Do ,Because I have used db_One..Table1
or db_two..Table2
I want some thing like ...
/SAMPLE SP/
CREATE PROCEDURE LOAD_DATA
AS
BEGIN
DECLARE #dbname nvarchar(500)
set #dbname=( SELECT DNAME FROM #db_name_list WHERE Did=1)
set #dbname2=( SELECT DNAME FROM #db_name_list WHERE Did=2)
PRINT #DBNAME
SELECT * FROM #dbname..table1
/* or */
SELECT * FROM #dbname2.dbo.table1
END
i.e using Variable Instead of Database name ..
But it thow error
"Incorrect syntax near '.'."
P.S This was posted by some else on msdn but the answer there was not clear & I had the same kind of doubt. So please help
You can't use a variable like this in a static sql query. You have to use the variable in dynamic sql instead, in order to build the query you want to execute, like:
DECLARE #sql nvarchar(500) = 'SELECT * FROM ' + #dbname + '.dbo.mytable'
EXEC(#sql);
There seem to be a couple of options for you depending on your circumstances.
1. Simple - Generalise your procedures
Simply take out the database references in your stored procedure, as there is no need to have an explicit reference to the database if it is running against the database it is stored in. Your select queries will look like:
SELECT * from schema.table WHERE x = y
Rather than
SELECT * from database.schema.table WHERE x = y
Then just create the stored procedure in the new database and away you go. Simply connect to the new database and run the SP. This method would also allow you to promote the procedure to being a system stored procedure, which would mean they were automatically available in every database without having to run CREATE beforehand. For more details, see this article.
2. Moderate - Dynamic SQL
Change your stored procedure to take a database name as a parameter, such as this example:
CREATE PROCEDURE example (#DatabaseName VARCHAR(200))
AS
BEGIN
DECLARE #SQL VARCHAR(MAX) = 'SELECT * FROM ['+#DatabaseName+'].schema.table WHERE x = y'
EXEC (#SQL)
END

How to find all stored procedures and table from a single stored procedure?

I am working on a database which has does a lot of stored procedures and tables.
One brute force way to know all the stored procedures and tables called by a single stored procedure is by scanning and reading through the code. However, it takes a lot of time.
what is the query to find out all the stored procedures and tables that are called by a main stored procedure?
You can query sys.objects and sys.sql_expression_dependencies tables like this:
SELECT sys.objects.name, sys.objects.type_desc
FROM sys.sql_expression_dependencies
INNER JOIN sys.objects ON(referenced_id = object_id)
WHERE referencing_id = OBJECT_ID('<Your stored procedure name here>')
Don't forget to replace <Your stored procedure name here> with the actual name of the stored procedure.
Update:
A stored procedure called from another stored procedure will still have a row in sys.sql_expression_dependencies, but will have a null value in the referenced_id column. you can use something like this:
DECLARE #StoredProcedureName sysname = '<Your stored procedure name here>'
SELECT sys.objects.name, sys.objects.type_desc
FROM sys.sql_expression_dependencies
INNER JOIN sys.objects ON(referenced_id = object_id)
WHERE referencing_id = OBJECT_ID(#StoredProcedureName)
UNION ALL
SELECT procedures.name , 'Stored Procedure' As type_desc
FROM sys.sql_expression_dependencies
INNER JOIN sys.procedures ON(referenced_entity_name = sys.procedures.name)
WHERE referencing_id = OBJECT_ID(#StoredProcedureName)
AND referenced_id IS NULL

Stored procedures and the tables used by them

Is there a way to know what are the tables used by one stored procedure by doing an SQL query?
Best regards, and thanks for the help.
P.S.: I'm using SQL Server 2005.
This article on TechRepublic
Finding dependencies in SQL Server 2005
describes a way to do that:
This tutorial will show how you can
write a procedure that will look up
all of the objects that are dependent
upon other objects.
Here is the code to create the system stored procedure for finding object dependencies:
USE master
GO
CREATE PROCEDURE sp_FindDependencies
(
#ObjectName SYSNAME,
#ObjectType VARCHAR(5) = NULL
)
AS
BEGIN
DECLARE #ObjectID AS BIGINT
SELECT TOP(1) #ObjectID = object_id
FROM sys.objects
WHERE name = #ObjectName
AND type = ISNULL(#ObjectType, type)
SET NOCOUNT ON ;
WITH DependentObjectCTE (DependentObjectID, DependentObjectName, ReferencedObjectName, ReferencedObjectID)
AS
(
SELECT DISTINCT
sd.object_id,
OBJECT_NAME(sd.object_id),
ReferencedObject = OBJECT_NAME(sd.referenced_major_id),
ReferencedObjectID = sd.referenced_major_id
FROM
sys.sql_dependencies sd
JOIN sys.objects so ON sd.referenced_major_id = so.object_id
WHERE
sd.referenced_major_id = #ObjectID
UNION ALL
SELECT
sd.object_id,
OBJECT_NAME(sd.object_id),
OBJECT_NAME(referenced_major_id),
object_id
FROM
sys.sql_dependencies sd
JOIN DependentObjectCTE do ON sd.referenced_major_id = do.DependentObjectID
WHERE
sd.referenced_major_id <> sd.object_id
)
SELECT DISTINCT
DependentObjectName
FROM
DependentObjectCTE c
END
This procedure uses a Common Table
Expression (CTE) with recursion to
walk down the dependency chain to get
to all of the objects that are
dependent on the object passed into
the procedure. The main source of data
comes from the system view
sys.sql_dependencies, which contains
dependency information for all of your
objects in the database.
Try sp_depends, although you should probably recompile the stored procedure to update the statistics in the database.
Look up sp_depends system stored proc.
I think that as long as the stored procedure and the tables are all in the same database then you can right click on the procedure in SSMS and click "View Dependencies". I don't know the query behind the dialog though...
As others indicated you can use the Dependancies stored procedures; however, in my experience and this was back on SQL Server 2000, the depandancies were not always reliable. In some cases they weren't being updated. You can always go to the sysComments table assuming your schema is not encrypted.
declare #crlfSearch varchar(max),#objectSearch varchar(max),#escapeSearch varchar(max)
set #crlfSearch=('%bid' + char(13)+'%')
set #objectSearch='%bid %'
set #escapeSearch ='%[[]Bid]%'
select distinct so.name
from syscomments sc
inner join sysobjects so
on sc.id=so.id
where text like #objectSearch or text like #crlfSearch
or text like #escapesearch
This query looks for three common cases you might have to add some but basically we find where the table name has a space after it, (This helps to limit cases where the table name is part of another table name), Has a return at the end of it, or is escaped within brackets.