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

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

Related

How to assign an output of a stored procedure that is nested in a stored procedure?

I have a stored procedure that has a nested stored procedure that is executed when the parent stored procedure is executed.
Can the output of the nested stored procedure be assigned to a #variable and the output in a select statement?
EXEC #bat_key = [dbo].[client_icc_set_batch] - I can see the output here but would also like to include the output in a SELECT statement.
SELECT 'return_key' = #bat_key
I would just do it like this:
DECLARE #bat_key INT
CREATE TABLE #tmp (bat_key INT)
INSERT #tmp
EXEC [dbo].[client_icc_set_batch];
SET #bat_key = (
SELECT TOP 1 bat_key
FROM #tmp
order by bat_key DESC
);
SELECT 'return_key' + '=' + CONVERT(VARCHAR, #bat_key)
DROP TABLE #tmp

Passing a table variable to a stored procedure

I am seeking to create a procedure that I can pass a one column table, and the procedure will output the median. Right now I have a procedure that will determine the median; however, I am getting errors that my #table table variable has not been declared and that the stored procedure could not be found.
My median procedure:
CREATE OR ALTER PROCEDURE dbo.median
(#table NUMERIC,
#median FLOAT OUTPUT)
AS
DECLARE #size AS NUMERIC
SET #size = (SELECT COUNT(*) FROM #table)
SET #median = (SELECT AVG(1) FROM (SELECT *, ROW_NUMBER() OVER(ORDER BY 1) AS ROW FROM #table) AS subquery
WHERE subquery.ROW = ROUND(#size / 2, 0) OR subquery.ROW = ROUND(#size / 2, 0, 1))
RETURN
GO
Calling the procedure:
DECLARE #Arsenic TABLE(Ar FLOAT)
INSERT INTO #Arsenic SELECT Arsenic from dbo.HubspotWaterTestAverages
EXEC dbo.median (SELECT Arsenic FROM dbo.HubspotWaterTestAverages)
NOTE: Arsenic represents the Arsenic level results from water tests, and the values range from null to 10
The working procedure is expected to just return the median value for the column, and later on I am planning on cross joining that to a master table. Thank you for any help!
This may help. Except table variable have to use Table Type.
CREATE TABLE Employee
(
EmpId int NOT NULL,
EmployeeName nvarchar(MAX),
)
GO
CREATE TYPE EmployeeType AS TABLE
(
EmpId int NOT NULL,
EmployeeName nvarchar(MAX)
)
GO
CREATE PROCEDURE PassTableTypeIntoProcedure(#EmployeeType EmployeeType READONLY)
AS
BEGIN
INSERT INTO Employee
SELECT * FROM #EmployeeType
END
GO
DECLARE #EmployeeTypeVariable AS EmployeeType
INSERT INTO #EmployeeTypeVariable VALUES
(1,'A'),
( 2,'B')
EXEC PassTableTypeIntoProcedure #EmployeeTypeVariable
GO
SELECT * FROM Employee

Stored procedure returning result even thought it's not supposed to

I have a stored procedure which looks like following:
ALTER PROCDURE [dbo].[zsp_selectallupceans_listProduction]
(#UPCList NVARCHAR(4000),
#EANList NVARCHAR(4000),
#Type TINYINT)
AS
SELECT
dd.UPC, dd.EAN, dd.EBAYID AS ItemID
FROM
ThirdPartyData AS dd
WHERE
EXISTS (SELECT 1 FROM dbo.SplitStringProduction(#UPCList,',') S1
WHERE dd.UPC = S1.val)
OR EXISTS (SELECT 1 FROM dbo.SplitStringProduction(#EANList,',') S2
WHERE dd.EAN = S2.val)
AND dd.Type = #Type
The parameters are passed like following:
#UPCList='709127309019',
#EanList='0709127309019',
#Type=4
The "SplitStringProduction" function looks like this:
ALTER FUNCTION [dbo].[SplitStringProduction]
(#string NVARCHAR(MAX),
#delimiter NVARCHAR(5))
RETURNS #t TABLE
(
val NVARCHAR(500)
)
AS
BEGIN
DECLARE #xml XML
SET #xml = N'<root><r>' + replace(#string,#delimiter,'</r><r>') + '</r></root>'
INSERT INTO #t(val)
SELECT
r.value('.','varchar(500)') AS item
FROM
#xml.nodes('//root/r') as records(r)
RETURN
END
Now when I do a simple select from my table like following:
select *
from thirdpartydata dd
where dd.UPC = '709127309019' -- note this is one of the parameters passed to the stored procedure...
I will get only 1 result with a column Type set to "1"....
Now when I try out my stored procedure:
exec zsp_selectallupceans_listProduction '709127309019','0709127309019',4
I still get 1 result, even though I'm not supposed to get any result, because if you can see the "Type" parameter is set to 4, thus no matching records should be found....
What am I doing wrong here, I can't seem to figure it out ??
You need to enclose the OR condition inside parenthesis:
WHERE (
EXISTS (SELECT 1 FROM dbo.SplitStringProduction(#UPCList,',') S1 WHERE dd.UPC=S1.val)
OR EXISTS (SELECT 1 FROM dbo.SplitStringProduction(#EANList,',') S2 WHERE dd.EAN=S2.val)
) AND dd.Type = #Type
Without them your query like this:
WHERE EXISTS (...)
OR (EXISTS (...) AND dd.Type = #Type)
And the result your get is because the first OR condition matches.

How to pass multiple values for a column in sql Stored Procedure?

i have two tables, such as
Queue
QueueID
LogParameters
QueueParameters
QueueParametersID
QueueID
LogParametersKey
LogParametersValue
I have to write SP inorder to make an entry in both the tables,
LogParameterKey and LogParameterValue may contains multiple values but the QueueID for each values should be same and QueueParameterID could be different.
**QueueID** **LogParameters**
1 AA
**QueueParametersID** **QueueID** **LogParametersKey** **LogParametersValue**
1 1 FirstName Mohammad
2 1 LastName Salman
3 1 Age 17
How do i pass multiple values for LogParameterKey and LogParameterValue?.. Someone suggested me to use Array for this... Is there's any other way?
CREATE Procedure AddQueue
#LogParameters NVARCHAR(255)
#AuditParameters AS AuditParameter READONLY,-- UserDefinedTable
AS
SET NOCOUNT ON;
BEGIN
DECLARE #QueueID BIGINT
EXECUTE dbo.procInsertQueue
#LogParameters = #LogParameters,
#QueueID = #QueueID OUTPUT
DECLARE #GetQueueID BIGINT = (SELECT QueuesID FROM Queues WHERE LogParameters= #LogParameters
DECLARE #AuditQueueParametersID BIGINT
DECLARE #TempTable TABLE(
ParameterKey NVARCHAR(255),
ParameterValue NVARCHAR(255),
AuditQueuesID BIGINT)
INSERT INTO #TempTable(ParameterKey,ParameterValue,QueuesID)
SELECT ParameterKey,ParameterValue,#GetQueueID FROM #AuditParameters
DECLARE #LogParameterKey NVARCHAR(255) = (SELECT ParameterKey FROM #TempTable WHERE QueuesID = #GetQueueID)
DECLARE #LogParameterValue NVARCHAR(255) = (SELECT ParameterValue FROM #TempTable WHERE QueuesID = #GetQueueID)
EXECUTE dbo.procAddQueueParameters
#AuditQueueID = #GetQueueID
#LogParametersKey = #LogParametersKey,
#LogParametersValue = #LogParametersValue,
#QueueParametersID = #QueueParametersID OUTPUT
END
END
1. Use User-Defined Table Types
https://technet.microsoft.com/en-us/library/bb522526(v=sql.105).aspx
2. Generate xml string and parse in SP
3.Use temp table
CREATE TABLE #Input
(
QueueParametersID ..
QueueID ..
LogParametersKey ..
LogParametersValue ..
)
--INSERT VALUES
EXEC dbo.YouSP
IN SP use table #Input

SQL server stored procedure return a table

I have a stored procedure that takes in two parameters. I can execute it successfully in Server Management Studio. It shows me the results which are as I expect. However it also returns a Return Value.
It has added this line,
SELECT 'Return Value' = #return_value
I would like the stored procedure to return the table it shows me in the results not the return value as I am calling this stored procedure from MATLAB and all it returns is true or false.
Do I need to specify in my stored procedure what it should return? If so how do I specify a table of 4 columns (varchar(10), float, float, float)?
A procedure can't return a table as such. However you can select from a table in a procedure and direct it into a table (or table variable) like this:
create procedure p_x
as
begin
declare #t table(col1 varchar(10), col2 float, col3 float, col4 float)
insert #t values('a', 1,1,1)
insert #t values('b', 2,2,2)
select * from #t
end
go
declare #t table(col1 varchar(10), col2 float, col3 float, col4 float)
insert #t
exec p_x
select * from #t
I do this frequently using Table Types to ensure more consistency and simplify code. You can't technically return "a table", but you can return a result set and using INSERT INTO .. EXEC ... syntax, you can clearly call a PROC and store the results into a table type. In the following example I'm actually passing a table into a PROC along with another param I need to add logic, then I'm effectively "returning a table" and can then work with that as a table variable.
/****** Check if my table type and/or proc exists and drop them ******/
IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'returnTableTypeData')
DROP PROCEDURE returnTableTypeData
GO
IF EXISTS (SELECT * FROM sys.types WHERE is_table_type = 1 AND name = 'myTableType')
DROP TYPE myTableType
GO
/****** Create the type that I'll pass into the proc and return from it ******/
CREATE TYPE [dbo].[myTableType] AS TABLE(
[someInt] [int] NULL,
[somenVarChar] [nvarchar](100) NULL
)
GO
CREATE PROC returnTableTypeData
#someInputInt INT,
#myInputTable myTableType READONLY --Must be readonly because
AS
BEGIN
--Return the subset of data consistent with the type
SELECT
*
FROM
#myInputTable
WHERE
someInt < #someInputInt
END
GO
DECLARE #myInputTableOrig myTableType
DECLARE #myUpdatedTable myTableType
INSERT INTO #myInputTableOrig ( someInt,somenVarChar )
VALUES ( 0, N'Value 0' ), ( 1, N'Value 1' ), ( 2, N'Value 2' )
INSERT INTO #myUpdatedTable EXEC returnTableTypeData #someInputInt=1, #myInputTable=#myInputTableOrig
SELECT * FROM #myUpdatedTable
DROP PROCEDURE returnTableTypeData
GO
DROP TYPE myTableType
GO
Consider creating a function which can return a table and be used in a query.
https://msdn.microsoft.com/en-us/library/ms186755.aspx
The main difference between a function and a procedure is that a function makes no changes to any table. It only returns a value.
In this example I'm creating a query to give me the counts of all the columns in a given table which aren't null or empty.
There are probably many ways to clean this up. But it illustrates a function well.
USE Northwind
CREATE FUNCTION usp_listFields(#schema VARCHAR(50), #table VARCHAR(50))
RETURNS #query TABLE (
FieldName VARCHAR(255)
)
BEGIN
INSERT #query
SELECT
'SELECT ''' + #table+'~'+RTRIM(COLUMN_NAME)+'~''+CONVERT(VARCHAR, COUNT(*)) '+
'FROM '+#schema+'.'+#table+' '+
' WHERE isnull("'+RTRIM(COLUMN_NAME)+'",'''')<>'''' UNION'
FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = #table and TABLE_SCHEMA = #schema
RETURN
END
Then executing the function with
SELECT * FROM usp_listFields('Employees')
produces a number of rows like:
SELECT 'Employees~EmployeeID~'+CONVERT(VARCHAR, COUNT(*)) FROM dbo.Employees WHERE isnull("EmployeeID",'')<>'' UNION
SELECT 'Employees~LastName~'+CONVERT(VARCHAR, COUNT(*)) FROM dbo.Employees WHERE isnull("LastName",'')<>'' UNION
SELECT 'Employees~FirstName~'+CONVERT(VARCHAR, COUNT(*)) FROM dbo.Employees WHERE isnull("FirstName",'')<>'' UNION
You can use an out parameter instead of the return value if you want both a result set and a return value
CREATE PROCEDURE proc_name
#param int out
AS
BEGIN
SET #param = value
SELECT ... FROM [Table] WHERE Condition
END
GO
I had a similar situation and solved by using a temp table inside the procedure, with the same fields being returned by the original Stored Procedure:
CREATE PROCEDURE mynewstoredprocedure
AS
BEGIN
INSERT INTO temptable (field1, field2)
EXEC mystoredprocedure #param1, #param2
select field1, field2 from temptable
-- (mystoredprocedure returns field1, field2)
END
The Status Value being returned by a Stored Procedure can only be an INT datatype. You cannot return other datatypes in the RETURN statement.
From Lesson 2: Designing Stored Procedures:
Every stored procedure can return an integer value known as the
execution status value or return code.
If you still want a table returned from the SP, you'll either have to work the record set returned from a SELECT within the SP or tie into an OUTPUT variable that passes an XML datatype.
HTH,
John
Though this question is very old but as a new in Software Development I can't stop my self to share what I have learnt :D
Creation of Stored Procedure:
CREATE PROC usp_ValidateUSer
(
#UserName nVARCHAR(50),
#Password nVARCHAR(50)
)
AS
BEGIN
IF EXISTS(SELECT '#' FROM Users WHERE Username=#UserName AND Password=#Password)
BEGIN
SELECT u.UserId, u.Username, r.UserRole
FROM Users u
INNER JOIN UserRoles r
ON u.UserRoleId=r.UserRoleId
END
END
Execution of Stored Procedure:
(If you want to test the execution of Stored Procedure in SQL)
EXEC usp_ValidateUSer #UserName='admin', #Password='admin'
The Output:
create procedure PSaleCForms
as
begin
declare
#b varchar(9),
#c nvarchar(500),
#q nvarchar(max)
declare #T table(FY nvarchar(9),Qtr int,title nvarchar (max),invoicenumber nvarchar(max),invoicedate datetime,sp decimal 18,2),grandtotal decimal(18,2))
declare #data cursor
set #data= Cursor
forward_only static
for
select x.DBTitle,y.CurrentFinancialYear from [Accounts Manager].dbo.DBManager x inner join [Accounts Manager].dbo.Accounts y on y.DBID=x.DBID where x.cfy=1
open #data
fetch next from #data
into #c,#b
while ##FETCH_STATUS=0
begin
set #q=N'Select '''+#b+''' [fy], case cast(month(i.invoicedate)/3.1 as int) when 0 then 4 else cast(month(i.invoicedate)/3.1 as int) end [Qtr], l.title,i.invoicenumber,i.invoicedate,i.sp,i.grandtotal from ['+#c+'].dbo.invoicemain i inner join ['+#c+'].dbo.ledgermain l on l.ledgerid=i.ledgerid where (sp=0 or stocktype=''x'') and invoicetype=''DS'''
insert into #T exec [master].dbo.sp_executesql #q
fetch next from #data
into #c,#b
end
close #data
deallocate #data
select * from #T
return
end
Here's an example of a SP that both returns a table and a return value. I don't know if you need the return the "Return Value" and I have no idea about MATLAB and what it requires.
CREATE PROCEDURE test
AS
BEGIN
SELECT * FROM sys.databases
RETURN 27
END
--Use this to test
DECLARE #returnval int
EXEC #returnval = test
SELECT #returnval