How can i execute a stored procedure inside another stored procedure in SQL Server? - sql

I´m working with SQLServer and I have two storedprocedures
The first one:
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON
DECLARE #FECHAFIN AS datetime;
SET #FECHAFIN = #FECHAINICIO + '23:59:59.999'
-- Insert statements for procedure here
SELECT
HC.idCorrida AS Referencia,
T.part AS Parte,
T.idTrabajo AS Trabajo,
HC.cantidadFabricado AS Piezas,
HC.cantidadRechazado AS Rechazo,
CONVERT(varchar(8), HC.tiempoProduccion) AS TiempoDeProduccion,
CONVERT(varchar(8), HC.tiempoMuerto) AS TiempoMuerto,
HC.fechaInicio AS Fecha,
U.nombreUsuario AS Usuario,
MA.nombre AS NombreMaquina,
TR.nombre AS NombreTripulacion,
TXM.idTurno AS Turno,
FROM [Produccion].[HistorialCorridas] AS HC
INNER JOIN [Produccion].[Trabajos] AS T
ON HC.idTrabajo = T.idTrabajo
INNER JOIN [Administracion].[Usuarios] AS U
ON U.idUsuario = HC.idUsuario AND U.idTripulacion = #IDTRIPULACION
INNER JOIN [Administracion].[Tripulaciones] AS TR
ON U.idTripulacion = TR.idTripulacion
WHERE HC.idTurnoXMaquina = #IDTURNOXMAQUINA
AND HC.fechaInicio >= #FECHAINICIO AND HC.fechaInicio <= #FECHAFIN
GROUP BY HC.idCorrida, T.part, T.idTrabajo, HC.cantidadFabricado, HC.cantidadRechazado,
HC.tiempoProduccion, HC.tiempoMuerto, HC.fechaInicio, U.nombreUsuario, MA.nombre, TR.nombre, TXM.idTurno
END
The second one:
BEGIN
SET NOCOUNT ON
SELECT
CONVERT(VARCHAR(8), DATEADD(SECOND,SUM(DATEDIFF(SECOND, '00:00:00', TiempoMuerto)),0),114) AS TotalTiempoMuerto,
P.etiqueta AS TipoParo
FROM [Produccion].[TiemposMuertos]
INNER JOIN [Administracion].[ParosXMaquina] AS PM
ON PM.id = idParoXMaquina
INNER JOIN [Administracion].[Paros] AS P
ON P.idParo = PM.idParo
WHERE idCorrida = #IDCORRIDA
GROUP BY P.etiqueta
END
The second one receives as a parameter a field called Referencia from the first stored procedure. What I want to do, is execute the second stored procedure from the first one, passing that parameter.
How could I achieve this? Is it possible to get the result in just one query?
Thanks in advance!!!

To call a PROCEDURE from another PROCEDURE that returns a value as output, you must use the out keyword for the output, which may be a table or other data type.
The following two procedures are defined.
In test1 procedure, the return parameter is specified with out.
In the second procedure, the first procedure is called as follows:
DECLARE #result int
EXEC test1 #result OUTPUT
CREATE PROCEDURE test1
(#outID int output)
AS
BEGIN
SET #outID = (select top 1 ID from table1)
END
CREATE PROCEDURE test2
AS
BEGIN
BEGIN
DECLARE #result int
EXEC test1 #result OUTPUT
SELECT ID from table2 where ID = #result
END;
END
GO
EXEC test2

Related

How to create procedure with multiple string select query in sql?

I want to create procedure with multiple string select query.I want to insert data to table variable and join that temp table with other table.
I don't want to create temp table as real tables. I want to insert data to memory temp table.
Here is my procedure,
CREATE PROCEDURE sp_TempBatch
AS
DECLARE #TempBatchSerial TABLE
(
ID int,
Name nvarchar(200),
StockType nvarchar(50),
ItemNo nvarchar(50)
)
DECLARE #TempQuery as nvarchar(MAX)='',
#VendorQuery as nvarchar(MAX)=''
BEGIN
SET #TempQuery='SELECT ID,Name,'
IF StockType = '1'
BEGIN
SET #TempQuery += ' ''Batch'' as StockType,'
END
ELSE
BEGIN
SET #TempQuery += ' ''Serial'' as StockType,'
END
SET #TempQuery += 'ItemNo INTO #TempBatchSerial
FROM Stock'
EXEC (#TempQuery)
SET #VendorQuery+=' SELECT #TempBatchSerial.* FROM #TempBatchSerial
INNER JOIN Vendor
ON #TempBatchSerial.ID = Vendor.ID
INNER JOIN Partner
ON Vendor.parentid = Partner.syskey'
EXEC (#VendorQuery)
END
When execute procedure show error message of Must declare the table variable "#TempBatchSerial"
You have to refer to #tempBatchSerial via an Alias
That's the only way #tempTables can be referred or linked to.
SELECT T.* FROM #TempBatchSerial T
INNER JOIN Vendor
ON T.ID = Vendor.ID
INNER JOIN Partner
ON Vendor.parentid = Partner.syskey
If that doesn't work you can try to put the #tempTable in the #vendorQuery text.

without using function how to call result set to another stored procedure in sql server

i am working on sql server 2008
i have a stored procedure for getting total amount. while executing this i am getting result
my first stored procedure like this:
alter procedure [dbo].[jaseem_test4]
#carid varchar(50)
as
begin
Declare
#locid integer,
#vtid integer,
#day varchar(20),
#Date date,
#startdate datetime,
#Pdatetime datetime,#Ptime time,
#prkdtime datetime,#pdate date,
#Starttime time,#startloctime varchar(10),
#currenttime varchar(10),#endtime time,
#endloctime varchar(10)
--finding loc_id and vtid
set #locid = (select t.locid
from Transaction_tbl t where Tbarcode=#carid)
set #vtid=(select t.vtid from Transaction_tbl t where TBarcode=#carid)
----------
--finding parked time
set #Pdatetime=(select t.dtime from Transaction_tbl t where Tbarcode=#carid)
--finding location end time
select #endtime=l.EndTime from Location_tbl l where l.Locid=#locid
select #endloctime=convert(Varchar(8), #endtime,108)
select #currenttime=CONVERT(VARCHAR(8),GETDATE(),108)
select #Date=convert(date,getdate())
select #pdate=convert(date,#Pdatetime,108)
select #Ptime=CONVERT(VARCHAR(8),#Pdatetime,108)
declare #prevousdate datetime
select #prevousdate=convert(date,getdate()-1)
declare #LT integer
if #endloctime<#Ptime
begin
select #startdate= cast(#Date as Datetime) + cast(#endloctime as Datetime)
select #prkdtime=cast(#prevousdate as Datetime) + cast(#Ptime as Datetime)
select #LT =datediff(mi,#prkdtime,#startdate)
--select #LT as LT1
end
else
begin
select #LT=datediff(mi,#ptime,#endloctime)
--select #LT as LT
end
declare #PT integer=datediff(mi,#Pdatetime,getdate())
--select #PT as PT
DEclare #daycount integer
if (#LT >= #PT)
begin
set #daycount=1
--select #daycount
end
If (#PT > #LT)
begin
Declare #q Integer ,#q1 float,#modvAL float,#PT1 integer
set #q=1
set #modvAL=1440
set #PT1=#PT-#LT
-- select #PT1 as PT1
if #PT1>#modvAL
begin
set #q1= round((#PT1) / (#modvAL),0)
--select #q1 as q2
end
else
begin
set #q1=1
end
set #q=(#q+#q1)
set #daycount=#daycount*#q
--select #daycount as daycount
end
------------------------------------------------------
declare #days integer,#s varchar(10),#Total integer,
#n integer
,#day1 integer,
#checkWeekend integer,
#Hamount integer,
#Htotel integer, #Namount integer,#startloctime1 varchar(10),#currenttime1 varchar(10),
#Ntotal integer
set #days=0
set #n=0
set #day1=#daycount
set #Htotel=0
set #Ntotal=0
Select #startloctime1= convert(Varchar(8),( select l.StartTime from Location_tbl l where l.Locid=5),108)
select #currenttime1=CONVERT(VARCHAR(8),GETDATE(),108)
while (#days < #day1)
begin
if #day1=1
begin
if #startloctime1>#currenttime1
begin
set #s= datename(dw,getdate()-1)
end
else
begin
set #s= datename(dw,getdate())
end
end
else
begin
select #s=datename(dw,getdate()-#n)
--select #s
end
select #checkWeekend= Weekend from weekends_tbl where weekdays=#s
if #checkWeekend=1
begin
select #hamount= Hamount from locvtypeassign_tbl where
vtid=#vtid and locid=#locid and active=0
set #Htotel=#Htotel+#Hamount
end
else
begin
select #Namount= NAmount from locvtypeassign_tbl where
vtid=#vtid and locid=#locid and active=0
set #Ntotal=#Ntotal+ #Namount
end
set #days=#days+1
set #n= #n+1
set #Total= #Htotel+#Ntotal
end
select #Total as [Total]
end --End main
Go
if i pass carid i am getting out put like this:
Total
100
only for getting this i wrote a stored procedure around 100 lines .in this stored procedure i am just passing one value(Tbarcode)
i have a another stored procedure somthing line this:
Select t.dtime,t.vtid,t.locid
from transaction_tbl t where Tbarcode='4502'
my out put is something like this:
dtime vtid locid
----------------------- ----------- -----------
2014-10-02 23:43:39.453 7 5
i want to add this two stored procedure and i am expecting out put
dtime vtid locid Totalamount
----------------------- ----------- ----------- ------------
2014-10-02 23:43:39.453 7 5 100
i know this i can do by making first stored procedure as function,and return the total amount to second stored procedure.but i fear about execution speed.
if i call function in my stored procedure then my stored procedure execution will get slow right?
without using function is therey any way to get my stored procedure result into second stored proceure??
any help is very appriciable
how i can call my first stored procedure result to seconde stored procedure??
I would use a similar approach as Rahul, but slightly different. To make sure you don't break your existing code which might already be using these 2 procedures, I would do the following:
Step 1. - Extend the first procedure with an optional output parameter as follows (see comments at the end of the lines I've added):
alter procedure [dbo].[jaseem_test4]
#carid varchar(50),
#totalAmount int = null OUTPUT /* the new output parameter which returns the total value */
as
begin
....
set #totalAmount = #Total /* setting the output parameter to the return total value */
select #Total as [Total]
end --End main
Go
Step 2 - call the first procedure with the output parameter from the 2nd procedure - I've borrowed Rahul's code for this
Please note that you just have to add to your 2nd procedure only the lines with a comment:
create procedure sp_another_proc
as
begin
...
declare #totalAmount int /* the total amount variable */
exec jaseem_test4 'InputCaridValue', #totalAmount OUT /* call procedure to get total amount */
....
Select t.dtime,
t.vtid,
t.locid,
#totalAmount as TotalAmount /* add to your final select the #totalAmount variable */
from transaction_tbl t where Tbarcode='4502'
end
GO
All should work just fine.
One approach, assuming that the second procedure also only returns a single row, is to create a 3rd procedure that will call both of the existing ones, capture the output of each, and then select the combination for the real output. The benefit here is that you don't have to modify, in any way, the two existing procedures. This is quite helpful if either, or both, of those existing stored procedures are called by another code and hence a change in behavior might have adverse effects, or at the very least it would create additional complication and code paths to test for.
For example:
DECLARE #JaseemTest4Result TABLE (TotalAmount INT);
DECLARE #Proc2Result TABLE (dtime DATETIME, vtid INT, locid INT);
INSERT INTO #JaseemTest4Result (TotalAmount)
EXEC jaseem_test4 #carid = 25;
INSERT INTO #Proc2Result (dtime, vtid, locid)
EXEC proc2 #Tbarcode = '4502';
SELECT p2r.dtime, p2r.vtid, p2r.locid, jt4.TotalAmount
FROM #JaseemTest4Result jt4
CROSS JOIN #Proc2Result p2r;
Or, if the second stored proc is only for this purpose, you can update it to do only the part from the example above that captures the TotalAmount and then JOIN the real table and the table variable together:
DECLARE #JaseemTest4Result TABLE (TotalAmount INT);
INSERT INTO #JaseemTest4Result (TotalAmount)
EXEC jaseem_test4 #carid = 25;
Select t.dtime, t.vtid, t.locid, jt4.TotalAmount
from transaction_tbl t
CROSS JOIN #JaseemTest4Result jt4
where t.Tbarcode='4502'
Simplest thing you can do is; call your main stored procedure passing the Totalamount value and then display the result like
Main procedure body
exec sp_another_proc 100
In sp_another_proc
create procedure sp_another_proc (#total int)
as
begin
Select t.dtime,
t.vtid,
t.locid,
#total as TotalAmount
from transaction_tbl t where Tbarcode='4502'
end
EDIT:
In your first procedure [dbo].[jaseem_test4] instead of the last line
select #Total as [Total]
Call the second procedure like
exec my_second_procedure #Total
Modify your second procedure to accept a Integer parameter as shown above and then just display it.

How can I call and get back the results of an SP from another Stored Procedure

I have this stored procedure:
CREATE PROCEDURE [dbo].[sp_get_correct_responses]
#QuestionUId UNIQUEIDENTIFIER
AS
BEGIN
...
-- This is the last part of the SP. I need to use the output
-- value of #AnswerGridCorrect in the calling SP
SELECT #AnswerGridCorrect = Correct
FROM Concatenated
WHERE RowNumber = ColumnCount
END
How can I call the stored procedure from another stored procedure, pass it the #QuestionUId parameter and put the returned variable #AnswerGridCorrect into a variable declared in the calling procedure?
Update: Here's the proposed answer:
CREATE PROCEDURE [dbo].[sp_get_correct_responses]
#QuestionUId UNIQUEIDENTIFIER,
#output VARCHAR(20) output
AS
BEGIN
select #QuestionUId
DECLARE #AnswerGridCorrect VARCHAR(20)
DECLARE #QuestionId int;
SELECT #QuestionId = QuestionId
FROM dbo.Question
Where QuestionUId = #QuestionUId;
Select #questionId;
WITH Partitioned AS (
SELECT ROW_NUMBER() OVER (PARTITION BY QuestionId ORDER BY AnswerId ASC) AS RowNumber,
COUNT(1) OVER (PARTITION BY QuestionId) AS ColumnCount,
CONVERT(VARCHAR(MAX), Correct) AS Correct
FROM dbo.Answer
WHERE [QuestionId] = #QuestionId
),
Concatenated AS (
SELECT RowNumber, ColumnCount, Correct FROM Partitioned WHERE RowNumber = 1
UNION ALL
SELECT P.RowNumber,
P.ColumnCount,
C.Correct + P.Correct AS Correct
FROM Partitioned P
INNER JOIN Concatenated C
ON P.RowNumber = C.RowNumber + 1
)
SET #output = (SELECT Correct
FROM Concatenated
WHERE RowNumber = ColumnCount)
RETURN
END
You could have a temp table in the other stored procedure and populate it with the results of this one:
INSERT INTO #table
Exec sp_get_correct_responses #QuestionUId
The other way would be to modify sp_get_correct_responses to produce an output as you are expecting only one value.
CREATE PROCEDURE [dbo].[sp_get_correct_responses]
#QuestionUId UNIQUEIDENTIFIER,
#output VARCHAR(20) output
AS
BEGIN
...
-- This is the last part of the SP. I need to use the output
-- value of #AnswerGridCorrect in the calling SP
SELECT #output = Correct
FROM Concatenated
WHERE RowNumber = ColumnCount
RETURN
END
And in your other SP:
DECLARE #output VARCHAR(20)
EXEC sp_get_correct_responses
#QuestionUId,
#output output
SELECT #output
You can make one table variable in parent SP and insert result of child SP in that like below :
DECLARE #TempTable TABLE(AnswerGridCorrect INT)
INSERT INTO #TempTable
EXEC [dbo].[sp_get_correct_responses] #QuestionUId

How do I define a stored procedure that returns table?

For example I have this stored procedure:
create procedure MyStoredProcedure
as
begin
select *
from X,Y
where x.Id = Y.ID
end
return #table table(X.tTitle, Y.Description)
I want return table and when use table in another query
Stored procedures cannot1 be composed into other queries as a source of rows - is there a reason why it has to be a stored procedure? A user defined function has almost the same amount of expressability as a stored procedure and can easily be a source of rows in the FROM clause of another query.
Something like:
create function MyFunction()
returns table
as
return (select X.tTitle,Y.Description
from X
inner join Y
on x.Id = Y.ID)
1 Ignoring INSERT...EXEC since it does nothing for composition, and OPENROWSET isn't always a viable approach.
Try this:
create procedure MyStoredProcedure
as
begin
select X.*,Y.*
From X INNER JOIN Y ON X.Id=Y.ID
end
This will select all data from tables X and Y.
Try This Way:
CREATE PROCEDURE [dbo].[MyStoredProcedure]
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
Declare #ID int
set #ID =(select ID From X INNER JOIN Y ON X.Id=Y.ID)
IF #ID > 0
BEGIN
return #table table(X.tTitle,Y.Description)
END
END
you can simply Create a Procedure and then, Try this:
CREATE PROCEDURE MyStoredProcedure
AS
BEGIN
SELECT tTitle ,
Description
FROM X
JOIN Y ON Y.ID = X.ID
END
You can use temp tables or table variables.
Like this:
CREATE TABLE #TABLE
(
COLUMN DEFINITION
)
INSERT INTO #TABLE
EXEC <YOUR STORED PROCEDURE>
SELECT *
FROM #TABLE
DROP TABLE #TABLE
You can insert your stored procedure inside the temp table so you can use it as well as a table.
Note that temp table names should start with #.
Somethings like this you most write
CREATE PROCEDURE <SP_Name>
AS
BEGIN
Select ......
End

How to execute a Stored Procedure on the results of a SQL Server CTE

I have a CTE which returns DISTINCT ID's. I want to execute a scalar function on each of the Id's returned.
WITH cte (reqID) as
(SELECT DISTINCT pol.ReqID FROM
LOG_PackingListItems pli
JOIN
v_PO_LN pol on pol.PO_ID = pli.PoId
WHERE
pli.PackingListHeaderID = 1)
EXEC dbo.spUpdateLOG_ReqCompleteCheck reqID -- Error "Incorrect Syntax near EXEC"
The EXEC line is what I want to make work but I get a syntax error. Not sure if what I want to do is possible or if I do in fact have a syntax error. Any ideas?
EDIT:
I'm adding the code for the Stored Procedure since I am now using a Table-Valued Parameter as suggested by realnumber3012
EDIT:
I have changed my CTE code so it populates a Table-Type as realnumber has suggested. I now get an error when executing spUpdateLOG_ReqCompleteCheck "Subquery returns more than one value."
DECLARE #ReqIdTVP as ReqIdType;
DELETE FROM #ReqIDTVP;
with cte (reqID) as
(select distinct pol.ReqID from
LOG_PackingListItems pli
join
v_PO_LN pol on pol.PO_ID = pli.PoId
where
pli.PackingListHeaderID = #PackingListHeaderID)
INSERT INTO #ReqIdTVP
SELECT * FROM cte
EXEC dbo.spUpdateLOG_ReqCompleteCheck #ReqIdTVP
Sproc code :
Alter PROCEDURE spUpdateLOG_ReqCompleteCheck
(#ReqIdTVP ReqIdType READONLY )
AS
BEGIN
DECLARE #TotalOrd int
DECLARE #TotalRx int
DECLARE #ReqID char(8)
SET #ReqID = (SELECT ReqID FROM #ReqIdTVP)
SET #TotalOrd = (SELECT ISNULL(SUM(ORD_QTY),0)
FROM dbo.v_PoLnNonFreight l
WHERE l.ReqID = #reqID)
SET #TotalRx = (SELECT ISNULL(SUM(TotalRxSite),0)
FROM dbo.v_PoLnNonFreight l
WHERE l.ReqID = #reqID)
IF #TotalRx >= #TotalOrd
BEGIN
DECLARE #curDate datetime
SET #CurDate = ISNULL(#CurDate,GetDate())
SET NOCOUNT ON;
UPDATE LOG_ReqHeader
SET
ReqCompleteDate = #curDate,
ReqStatus = 'Complete'
WHERE ReqID = #ReqID
END
END
Seems that the only thing your stored proc does is to update a logging table: (it only changes state via this statement and doesn't return anything????
UPDATE LOG_ReqHeader
SET
ReqCompleteDate = #curDate,
ReqStatus = 'Complete'
WHERE ReqID = #ReqID
How about splitting the logic out and write a function (inline if possible that will evaluate the condition you are looking for (didn't really understand what you are doind there) -- run the function on the results of the CTE (wrapping it in another CTE if you want) with the CROSS APPLY OPERATOR.
You'd end up with a result set that looks like [ReqId], [UpdateLog] (where updateLog is a BIT)
Then simply do a set based upadete JOINING to the results:
UPDATE l SET
ReqCompleteDate = #curDate,
ReqStatus = 'Complete'
FROM
LOG_ReqHeader AS l
JOIN <CTE> AS c ON c.[ReqID] = l.[ReqID]
WHERE
c.[UpdateLog] = 0x1
Does this make any sense?