Use table columns in Exec stored procedure command SQL Server - sql

I have a command:
exec [Database].[dbo].DepartmentChangeLevel , Department, Date, Level;
I currently specify the values manually and explicitly like this:
exec [Database].[dbo].DepartmentChangeLevel , 'Catering', '20180101 08:01:00', 3;
However, I want to run the same command and use values from a table - like this:
exec [Database].[dbo].DepartmentChangeLevel
select
[Department], [Date], [Level]
from
[Database].[dbo].[DepartmentChange]
The error message I get is
Expects parameter #department which is not supplied
Please help

You can use a Cursor instead:
Create a Cursor on your table and pass all three columns into three variables
and execute proc in the cursor.
Example :
declare db_cursor cursor
for select
[Department], [Date], [Level]
from
[Database].[dbo].[DepartmentChange];
declare #department int --your column data type
,#date datetime --your column data type
,#level varchar(10) --your column data type
OPEN db_cursor;
FETCH NEXT FROM db_cursor INTO #department, #date, #level;
WHILE ##FETCH_STATUS = 0
BEGIN
exec [Database].[dbo].DepartmentChangeLevel #department, #date, #level;
DELETE FROM [Database].[dbo].DepartmentChangeLevel ---or you can store values from DepartmentChangeLevel table into temporary table then delete those values from temporary table
WHERE [Department]=#department
and [Date]=#date
and [Level]=#level
FETCH NEXT FROM db_cursor INTO #department,#date, #level
END
CLOSE db_cursor;
DEALLOCATE db_cursor;

Related

How to insert records in a existing table using Cursor

Declare Userrole_Cursor Cursor For
Select (User_Role_id,
Pos_entity_Id,
User_role_code,
User_Role_description,
Print_Sequence,
Update_date,
Tx_id,
Add_date,
Add_Username,
Update_Username,
Active_Flag) from User_Role_Tb where pos_entity_id = (pos_entity_id)
Open Cursor
FETCH NEXT FROM UserRole_Cursor into
the above is the Cursor creation i have written, now need to insert in all the mentioned columns in a User_role_tb. please help. this is the first time i am using cursor.
This simple example can help you
-- assume this is your table
create table #tmp (MyDbName varchar(100), MyDbId int, MyStatus int)
-- you need to have a variable for each field.
DECLARE #MyDbName varchar(100)
DECLARE #MyDbId int
DECLARE #MyDbStatus int
DECLARE db_cursor CURSOR FOR
SELECT name, [dbid], [status]
FROM master.dbo.sysdatabases
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #MyDbName, #MyDbId, #MyDbStatus
WHILE ##FETCH_STATUS = 0
BEGIN
-- insert data into your table using variables
insert into #tmp (MyDbName, MyDbId, MyStatus)
values (#MyDbName, #MyDbId, #MyDbStatus)
-- fetch next row from cursor
FETCH NEXT FROM db_cursor INTO #MyDbName, #MyDbId, #MyDbStatus
END
CLOSE db_cursor
DEALLOCATE db_cursor
-- select from your table to make sure data is there
select * from #tmp

Declare a Cursor From a Table as Variable (In the Select-Statement)

I want to create a SP that have 2 String parameters for 2 table names. In the SP I use dynamic SQL to modify one of the tables, but the other is inside a cursor, and I cant use dynamic SQL after the "FOR"
ALTER PROCEDURE NameProcedure #SourceTable VARCHAR(100),#DestinationTable VARCHAR(100)
AS
BEGIN
DECLARE #AddressSource VARCHAR(100), #AddressDestination VARCHAR(100)
SELECT #AddressSource = '[Test_Toa].[dbo].[' + #SourceTable + ']'
SELECT #AddressDestination = '[Test_Toa].[dbo].[' + #DestinationTable + ']'
--Source Table columns
DECLARE #id int, #idmercado int, #idcadena int, #barcode nvarchar(255),#Complete_P nvarchar(MAX)
DECLARE #Cursor CURSOR
SET #Cursor = CURSOR FOR
--HEREE ITS MY PROBLEM :(!!!!!
SELECT id, idmercado, idcadena, barcode, precios + ',' FROM #AddressSource
OPEN #Cursor
FETCH NEXT
FROM #Cursor INTO #id,#idmercado,#idcadena,#barcode,#Complete_P
WHILE ##FETCH_STATUS = 0
BEGIN
--bla bla code
FETCH NEXT
FROM #Cursor INTO #id,#idmercado,#idcadena,#barcode,#Complete_P
END
CLOSE #Cursor
DEALLOCATE #Cursor
END
I just want to declare a cursor for the table that the user gives
Well, you need to write a dynamic sql statement. Just as an hint. You can copy the values from your given source table into a temp table, generate a cursor on the temp table, iterate through it and deallocate the cursor afterwards and drop the temp table. :-)
Here a short demo code:
DECLARE #sql nvarchar(max), #sourceTable nvarchar(255)
CREATE TABLE dbo.t1(id int, name nvarchar(200))
CREATE TABLE dbo.t2(id int, name nvarchar(200))
SET #sourceTable = N'dbo.t1'
CREATE TABLE #temp(id int, name nvarchar(200))
SET #sql = N'
INSERT INTO #temp(id,name)
SELECT id, name
FROM '+#sourceTable
EXEC(#sql)
DECLARE cur CURSOR FOR
SELECT id, name
FROM #temp
OPEN cur
DECLARE #id int, #name nvarchar(200)
FETCH NEXT FROM cur INTO #id, #name
WHILE ##fetch_status = 0 BEGIN
SELECT #id, #name -- demo output
FETCH NEXT FROM cur INTO #id, #name
END
-- cleanup
CLOSE cur
DEALLOCATE cur
DROP TABLE dbo.t1
DROP TABLE dbo.t2
DROP TABLE #temp
Beware, I just have written this in notepad without any database. But I'm quite sure it does it's job.
This just works if all available variants of #sourceTable have the same column specification. If not, you need to extract the needed columns from information schema and build a more dynamic code.

Append result of stored procedure to earlier executed stored procedure

I have a stored procedure which takes a single parameter containing single value.
I want to pass a collection of values to the procedure one by one and get the combined result into one table . Is this possible ?
Currently I am using cursor to execute procedure in loop but only result from passing first value in the collection is obtained.
declare #clientid varchar(10)
create table #tmpp(secid varchar(10))
insert into #tmpp values(2319)
insert into #tmpp values(2855)
insert into #tmpp values(1303)
declare cur CURSOR LOCAL for
select secid from #tmpp
open cur
fetch next from cur into #seclientid
while ##FETCH_STATUS = 0 BEGIN
exec getReportforclient #clientid
fetch next from cur into #clientid
END
close cur
deallocate cur
drop table #tmpp
If this is too obfuscated / unclear/ silly, can somebody please provide me an alternative ?
Any help is most appreciated . Thanks.
There probably is a way to this without using cursors, but without taking a look at your stored procedure we can't help too much on that. You can create a table (temporary or not) that has the same structure that the results of your sp and insert the results into it. Something like this:
DECLARE #clientid VARCHAR(10)
CREATE TABLE #tmpp(secid VARCHAR(10))
INSERT INTO #tmpp VALUES(2319)
INSERT INTO #tmpp VALUES(2855)
INSERT INTO #tmpp VALUES(1303)
CREATE TABLE #Results(col1 INT, col2.... -- create the table that will hold your
-- results
DECLARE cur CURSOR LOCAL for
SELECT secid
FROM #tmpp
OPEN cur
FETCH NEXT FROM cur INTO #seclientid
WHILE ##FETCH_STATUS = 0
BEGIN
INSERT INTO #Results
exec getReportforclient #clientid
FETCH NEXT FROM cur INTO #clientid
END
CLOSE cur
DEALLOCATE cur
DROP TABLE #tmpp
SELECT *
FROM #Results
Loop without CURSOR
IF OBJECT_ID('tempdb.dbo.#tmpp') IS NOT NULL DROP TABLE #tmpp
CREATE TABLE #tmpp(Clientid varchar(10))
INSERT #tmpp values(2319), (2855), (1303)
IF OBJECT_ID('tempdb.dbo.#Results') IS NOT NULL DROP TABLE #Results
CREATE TABLE #Results(--output columns of procedure)
DECLARE #Clientid int = (SELECT MIN(Clientid) FROM #tmpp)
WHILE (#Clientid IS NOT NULL)
BEGIN
INSERT INTO #Results
EXEC getReportforclient #Clientid
SELECT #Clientid = MIN(Clientid) FROM #tmpp WHERE Clientid > #Clientid
END
Simple example on SQLFiddle

Can I get the results of a stored procedure into a cursor within another stored procedure in SQL

I'm trying to put the results of a stored procedure into a cursor to use within the current procedure. I've added my code below but I'm not sure if this is possible or if my syntax is correct?
DECLARE cursorIDList CURSOR FOR
EXEC spGetUserIDs
OPEN cursorIDList
FETCH NEXT FROM cursorIDList INTO #ID
I receive the following error: Incorrect syntax near 'EXEC'. Expecting SELECT, '(' or WITH.
Thanks in advance.
You can do it like this:
DECLARE #t TABLE (ID INT)
INSERT INTO #t
EXEC spGetUserIDs
DECLARE cursorIDList CURSOR FOR
SELECT * FROM #t
OPEN cursorIDList
FETCH NEXT FROM cursorIDList INTO #ID
in my opinion very interesting approach would be to use cursor as parameter (although if you not going to update table i don't think its better choice):
create Table dbo.MyTable
(
i int
);
Insert Into dbo.MyTable (i) values (1)
Insert Into dbo.MyTable (i) values (2)
Insert Into dbo.MyTable (i) values (3)
Insert Into dbo.MyTable (i) values (4)
Go
Set NoCount ON;
Go
Create Proc dbo.myProc
(
#someValue int,
#cur Cursor Varying Output
)
As
Begin
declare #x int;
Set #cur = Cursor for
Select i From dbo.MyTable
Where i < #someValue;
open #cur
End
Go
-- Use of proc
declare #cur cursor;
declare #x int;
Exec dbo.myProc 3, #cur output
fetch next from #cur into #x
while ##fetch_status = 0
begin
print 'value: ' + cast(#x as varchar)
fetch next from #cur into #x
end
close #cur;
Deallocate #cur;
Go
--Cleanup
Drop Proc dbo.myProc
Drop Table dbo.MyTable
The syntax of cursor in SQL-Server is:
DECLARE cursor_name [ INSENSITIVE ] [ SCROLL ] CURSOR FOR select_statement
After FOR you must write a SELECT.
For more info see:
https://msdn.microsoft.com/it-it/library/ms180169.aspx

Using EXEC inside SELECT statement in SQL Server

I need to use exec inside of select clause. The query for the exec is created according to the columns of the table to on which select clause if used. What i want to do is something like following:
SELECT distinct
MTMain.[TableName],
MTMain.[TableFKey],
(select IsActive (exec GetStringForIsActive MTMain.[TableName],MTMain.[TableFKey]))
FROM
[MasterTableForLanguage] MTMain
Here, GetStringForIsActive is the stored procedure I want to execute for every row selected from MasterTableForLanguage.
The stored procedure will use EXEC to execute the following string
select IsActive from [TableName] where PKID= cast([TableFKey] as int)
TableName and TableFKey will be inputs of the stored procedure.
If you can modify your Stored Procedure GetStringForIsActive to return TableName, TableFKey and IsActive, you can use a cursor to get execute it for each row and add the results to a temp table.
ie:
exec GetStringForIsActive 'TableName', 'TableFKey'
returns
select [TableName], [TableFKey], IsActive from [TableName] where PKID= cast([TableFKey] as int)
The code would be like this:
declare #TableName nvarchar(50)
declare #TableFKey nvarchar(50)
declare #Results table (TableName nvarchar(50), TableFKey nvarchar(50), IsActive bit)
declare TableCursor cursor fast_forward for
select TableName, TableFKey from MasterTableForLanguage
open TableCursor
fetch next from TableCursor into #TableName, #TableFKey
if ##FETCH_STATUS <> -1
print 'MasterTableForLanguage check'
while (##FETCH_STATUS <> -1)
begin
insert into #Results
exec GetStringForIsActive #TableName, #TableFKey
fetch next from TableCursor into #TableName, #TableFKey
end
close TaleCursor
deallocate TableCursor
select * from #Results
use Functions instead of Stored procedures in SELECT clause.
Edited:
create that function
CREATE FUNCTION function1 (#TableName nvarchar(10),#TableFKey nvarchar(10))
RETURNS nvarchar(100) AS
BEGIN
-- do whatever here
END
then
SELECT distinct
MTMain.[TableName],
MTMain.[TableFKey],
function1(MTMain.[TableName],MTMain.[TableFKey])
FROM
[MasterTableForLanguage] MTMain
Does this make sense?
Well, I think to answer the full question, I don't believe a stored procedure would EXEC a SELECT statement, it would simply perform the SELECT.
You EXEC your current proc and pass it vars, and it returns a value BASED ON the select statement it runs. It's not EXEC'ing that statement, simply performing a select. I have several stored procs I use daily in some SQL agent processes, they all perform selects to query various tables, and none of them call an EXEC to perform those actions. This is my own example:
CREATE PROCEDURE [myproc]
#job_ident INT
AS
BEGIN
SET NOCOUNT ON;
...
SELECT TOP(1) #filter_type = filter_type FROM [place] WHERE [ident] = #job_ident
...
END
As mentioned previously, the most effective way to perform your query would be to perform that select inside a function, something similar to this I think will do:
CREATE FUNCTION ThisFunction (
#TableName nvarchar(10),
#TableFKey nvarchar(10)
)
RETURNS nvarchar(100)
AS
BEGIN
RETURN
(
select IsActive from [TableName] where PKID= cast([TableFKey] as int)
)
END
You could then do exactly as you want...
SELECT distinct
MTMain.[TableName],
MTMain.[TableFKey],
ThisFunction(MTMain.[TableName],MTMain.[TableFKey])
FROM
[MasterTableForLanguage] MTMain