How to EXECUTE a set of stored procedures in a table - sql-server

I have a table that stores names of stored procedures in my file structure. The idea is that the calling stored procedure will be given #in_Strings as a parameter; these are the display names of the stored procedures I want to execute.
Then, I want to search my table of stored procedures and execute the ones whose display names match with the inputted set.
For example, the calling stored procedure may be given an input set of strings 'foo', 'bar', and 'baz'. That means I want to be able to execute 'dbo.foo_sproc','dbo.bar_sproc', and 'dbo.baz_sproc'.
I am using SQL Server 2012. Any ideas?
BTW, my stored procedures table looks like this:
CREATE TABLE dbo.SPROCS
(
Display_Name NVARCHAR(256) NOT NULL,
SPROC_Name NVARCHAR(256) NOT NULL,
CreatedDateTime DATETIME2(2) NOT NULL DEFAULT GETUTCDATE()
)

You can use dynamic SQL, like in paqogomez's answer, but, unlike any other kind of names, procedure names can be parametrised in SQL Server, and so dynamic SQL is not necessary in this case.
For instance, if this was about a single procedure, you could read and execute the matching name using this simple method:
DECLARE #SPROC_Name nvarchar(256);
SELECT #SPROC_Name = SPROC_Name
FROM dbo.SPROCS
WHERE Display_Name = #in_string;
EXECUTE #SPROC_Name;
Just like that.
Since you are mentioning a set of strings, however, you will need a cursor to loop through the result set of matching procedure names and pass each name to the EXECUTE statement.
DECLARE #SPROC_Name nvarchar(256);
DECLARE procnames CURSOR
LOCAL FORWARD_ONLY STATIC READ_ONLY
FOR
SELECT #SPROC_Name = SPROC_Name
FROM dbo.SPROCS
WHERE ... /* condition involving Display_Name and #in_string */
;
OPEN procnames;
FETCH NEXT FROM procnames INTO #SPROC_Name;
WHILE ##FETCH_STATUS = 0
BEGIN
EXECUTE #SPROC_Name;
FETCH NEXT FROM procnames INTO #SPROC_Name;
END;
CLOSE procnames;
DEALLOCATE procnames;

A sql server example:
A cursor can loop through your result set and execute your stored procedures.
This (simple, but untested) script loops every sproc in the #in_strings variable.
CREATE PROCEDURE getSprocs #in_Strings varchar(max)
AS
BEGIN
DECLARE #sql varchar(max)
DECLARE db_cursor CURSOR FOR
SELECT SPROC_Name
FROM dbo.SPROCS
where sproc_name in (#in_Strings)
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #name
WHILE ##FETCH_STATUS = 0
BEGIN
set #sql = 'exec ' + #name
exec #sql
FETCH NEXT FROM db_cursor INTO #name
END
CLOSE db_cursor
DEALLOCATE db_cursor
END

Related

How to systematically get stored procedure (SP) parameter names and their values INSIDE the SP execution

As described in title, I am trying to systematically get stored procedure pararameter names and their corresponding values inside the execution of the proper stored procedure.
First point, which is taking stored procedure parameter names, is easy using table [sys].[all_parameters] and the stored procedure name. However, getting the actual values of these parameters is the difficult part, specially when you are not allowed to use table [sys].[dm_exec_input_buffer] (as a developer, I am not allowed to read this table, since it is a system administrator table).
Here is the code I have so far, which I am sure can serve you as a template:
CREATE PROCEDURE [dbo].[get_proc_params_demo]
(
#number1 int,
#string1 varchar(50),
#calendar datetime,
#number2 int,
#string2 nvarchar(max)
)
AS
BEGIN
DECLARE #sql NVARCHAR(MAX);
DECLARE #ParameterNames NVARCHAR(MAX) = ( SELECT STRING_AGG([Name], ',') FROM [sys].[all_parameters] WHERE OBJECT_ID = OBJECT_ID('[dbo].[get_proc_params_demo]') )
SET #sql = N'SELECT ' + #ParameterNames;
DECLARE GetParameterValues CURSOR FOR
SELECT DISTINCT [Name] FROM [sys].[all_parameters] WHERE OBJECT_ID = OBJECT_ID('[dbo].[get_proc_params_demo]');
OPEN GetParameterValues;
DECLARE #param_values NVARCHAR(MAX) = NULL
DECLARE #StoredProcedureParameter NVARCHAR(MAX)
FETCH NEXT FROM GetParameterValues INTO #StoredProcedureParameter;
WHILE ##FETCH_STATUS = 0
BEGIN
SET #param_values = 'ISNULL('+#param_values+','')'+#StoredProcedureParameter+','
EXEC(#param_values)
FETCH NEXT FROM GetParameterValues INTO #StoredProcedureParameter;
END;
CLOSE GetParameterValues;
DEALLOCATE GetParameterValues;
SET #param_values = LEFT(#param_values, LEN(#param_values) - 1)
EXEC sp_executesql #sql,#ParameterNames,#param_values;
END
EXEC [dbo].[get_proc_params_demo]
#number1=42,
#string1='is the answer',
#calendar='2019-06-19',
#number2=123456789,
#string2='another string'
This is my approach trying to dynamically get parameter actual values inside a cursor, but it does not work, and I am clueless so far. I know it is quite rudimentary, and I am happy to hear other approaches. To be fair, I don't know if this problem is even possible to solve without system tables, but it would be great.
EDIT: This is an attempt to get a generic code that works on any stored procedure. You do not want to hardcode any parameter name. The only input you have is the stored procedure name via OBJECT_NAME(##PROCID)

Screen dump of all SQL Server database stored procedures

I was working with T-SQL recently and I wanted a certain functionality in one of the stored procedure, problem, I can't remember what is the stored procedure name, I handcrafted this:
DECLARE #storedProcsDumpTBL TABLE([SP_DUMP_TEXT] nVARCHAR(500))
DECLARE #firstValue AS VARCHAR(20)
DECLARE #prefix AS VARCHAR(20)
DECLARE #storedProcFullName AS VARCHAR(100)
DECLARE #storedProcNameTBL AS VARCHAR(100)
DECLARE hammerCursor CURSOR FOR
SELECT name
FROM sys.procedures
ORDER BY 1
OPEN hammerCursor
FETCH NEXT FROM hammerCursor INTO #storedProcNameTBL
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC xp_sprintf #storedProcFullName OUTPUT, N'dbo.%s',#storedProcNameTBL
INSERT INTO #storedProcsDumpTBL([SP_DUMP_TEXT])
EXEC sp_helptext #storedProcFullName
FETCH NEXT FROM hammerCursor INTO #storedProcNameTBL
END
CLOSE hammerCursor
DEALLOCATE hammerCursor
SELECT * FROM #storedProcsDumpTBL
it kind of served my purpose, but is there anything better?
How about
select object_definition(object_id) ddl
from sys.procedures
?

How to declare a variable that lists all the existing databases on my server with the Microsoft SQL Server Management Studio

I need to create a variable that lists all the existing databases in my system, because I need it and I don't know how to do it. I have tried to create variables like this one:
DECLARE #nombreBD INT;
SET #nombreBD = (SELECT [database_id] FROM sys.databases Where name = 'model' )
SELECT #nombreBD AS Database_ID
PRINT #nombreBD
GO
This variable gets me only the name I put in the "WHERE" parameter but I need to get them all.
The table sys.databases shows you all the existing databases in the system and I need to get a boolean value from it, I thought to get it from the column "database_id" that's why I declared this variable.
This creates a table name #DBList with a column nombreBD
and inserts the database_id to the column,
then it shows all your sql-server database database_id
BEGIN
DECLARE #DBList TABLE (nombreBD INT)
INSERT INTO #DBList(nombreBD) SELECT database_id FROM sys.databases
SELECT * FROM #DBList
END
Is that what you need ?
To achieve what you want, you will need to use some dynamic SQL. Something like this ought to work for your case:
DECLARE #DBList TABLE (nombre varchar(50));
INSERT INTO #DBList(nombre) SELECT name FROM sys.databases
WHERE name NOT IN ('master','tempdb','msdb');
declare #name nvarchar(50);
declare #sql nvarchar(2000);
DECLARE db_Cursor CURSOR FOR
SELECT nombre FROM #DBList;
OPEN db_Cursor;
FETCH NEXT FROM db_Cursor INTO #name;
WHILE ##FETCH_STATUS = 0
BEGIN
SET #sql = N'USE ' + #name + N';'
exec sp_executesql #sql;
SET #sql = N'SELECT DB_NAME() AS DatabaseName, ''guest'' AS Database_User, [permission_name], [state_desc]
FROM sys.database_permissions WHERE [grantee_principal_id] = DATABASE_PRINCIPAL_ID(''guest'') AND [state_desc] LIKE ''GRANT%'' AND [permission_name] = ''CONNECT'';';
exec sp_executesql #sql;
FETCH NEXT FROM db_Cursor INTO #name;
END;
CLOSE db_Cursor;
DEALLOCATE db_Cursor;
Notice that I have changed the table variable to hold the database names, not their ids. This is because the USE statement takes the name not the id.
The cursor loops through the values, builds the various sql statements and executes them.

MS SQL loop through all DBs. Script works to alter table but not stored procedure

I use a piece of code to loop through all the databases on an MS SQL server. It works fine for altering a column on a table and also for updating the data. But I continue to get errors when trying to alter a stored procedure. Here is the code:
use master
declare #dbname varchar(100)
,#sql varchar(max)
declare db_cur cursor for
SELECT name
FROM sys.databases where ([name] like 'ce%')
and [state] = 0
open db_cur
fetch next from db_cur into #dbname
while ##FETCH_STATUS = 0
begin
set #sql=
'ALTER TABLE ['+#dbname+'].[dbo].MyStuff
ADD myNewColumn bit NULL DEFAULT(0)
'
exec(#sql)
fetch next from db_cur into #dbname
end
close db_cur
deallocate db_cur
So the code above works perfectly fine. But when I alter that code to instead do an alter stored procedure I receive the message below:
'CREATE/ALTER PROCEDURE' does not allow specifying the database name as a prefix to the object name.
I realized that the message stated I can't use the database name in the front of the procedure like I was doing here: ALTER procedure ['+#dbname+'].[dbo].[spSelectSomething]. But I haven't been able to figure out a way around the issue. Thanks for your help.
You need to nest dynamic SQL for this task because a proc CREATE or ALTER must be the first statement in the batch:
SET #sql= N'EXEC(N''USE ' + QUOTENAME(#dbname) + N';EXEC(N''''CREATE PROC...;'''')'')';

SQL Agent job to select a value from table and pass the values as input parameter to execute stored procedure

I have a stored procedure which expects integer as input parameter.
i need this sp to run every 10 mins. for this im thinking to use sql server agent job.
i want to select a set of values from table.column and pass this as an input parameter to the stored procedure every 10 minutes.
Appreciate your assistance in advance.
Thanks & Regards,
Sanjai
If I have understand your requirement.
Use Cursor (if the set of values are not huge) to pass the values from set of values of table.
DECLARE #value VARCHAR(50) -- table.column value
DECLARE myCursor CURSOR FOR
SELECT ColVal FROM Table -- Get the values from table
OPEN myCursor
FETCH NEXT FROM myCursor INTO #value
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC dbo.getValue #value -- Execute the SP
FETCH NEXT FROM myCursor INTO #value
END
CLOSE myCursor
DEALLOCATE myCursor
Use this T-SQL in agent job step.

Resources