include the outptut of storedprocedure in select - sql-server

I have a stored procedure like this:
create proc calcaulateavaerage
#studentid int
as
begin
-- some complicated business and query
return #result -- single decimal value
end
and then I want to
create proc the whole result
select * , ................................ from X where X.value > (calculateaverage X.Id)
It always gives an error that reads like "multi-part identifier calculateaverage couldn't be bound." Any idea how to solve that?

You don't want a stored procedure. You want a function.

Use Output variables to output the data out of stored procedure:
create proc calcaulateavaerage
#studentid int, #result int
as
begin
-- some complecated business and query
select #result = id from sometable;
end
-- Declaring output variable named result;
declare #result int;
-- Passing output variable to stored procedure.
exec calculateaverage 1, #result;
-- Now you can display the result or do whatever you like.
print #result

Related

When exactly do we use stored procedures with output parameters?

When exactly do we use stored procedures with output parameters and when do we use stored procedures without parameters?
I base my question on an example:
Stored procedure with output parameter
CREATE PROCEDURE uspGetContactsCountByCity
#City nvarchar(60),
#ContactsCount int OUT
AS
BEGIN
SELECT #ContactsCount = COUNT(ContactID)
FROM Contacts
WHERE City = #City
END
Stored procedure executing
DECLARE #ContactsTotal INT
EXEC uspGetContactsCountByCity #ContactsCount = #ContactsTotal OUT, #city = 'Berlin'
SELECT #ContactsTotal
Results: 2
Stored procedure without output parameter
CREATE PROCEDURE uspGetContactsCountByCity2
#City nvarchar(60)
AS
BEGIN
SELECT COUNT(ContactID)
FROM Contacts
WHERE City = #City
END
Stored procedure executing:
EXEC uspGetContactsCountByCity2 #city = 'Berlin'
Results: 2
Both procedures return the same result, in same form, so what's the difference?
Basically, the result you're seeing is actually the result of your SELECT at the end of the procedure, which is doing the same thing.
Please take a look at this documentation:
If you specify the OUTPUT keyword for a parameter in the procedure definition, the stored procedure can return the current value of the parameter to the calling program when the stored procedure exits. To save the value of the parameter in a variable that can be used in the calling program, the calling program must use the OUTPUT keyword when executing the stored procedure.
So basically if you would like your stored procedure to just return just a value instead of a data set, you could use the output parameter. For example, let's take the procedures you have given as an example. They both do the same thing, this is why you got the same result. But what about changing a little bit in the first procedure that has the output parameter.
Here's an example:
create table OutputParameter (
ParaName varchar(100)
)
insert into OutputParameter values ('one'), ('two'),('three'),('one')
CREATE PROCEDURE AllDataAndCountWhereOne
#name nvarchar(60),
#count int OUT
as
Begin
SELECT #count = COUNT(*) from OutputParameter
Where ParaName = #name
select Distinct(ParaName) from OutputParameter
End
Declare #TotalCount int
Exec AllDataAndCountWhereOne #count = #TotalCount OUT, #name = 'One'
Select #TotalCount
With this example, you are getting all the distinct stored data in the table, plus getting the count of a given name.
ParaName
--------------------
one
three
two
(3 row(s) affected)
-----------
2
(1 row(s) affected)
This is one way of using the output parameter. You got both the distinct data and the count you wanted without doing extra query after getting the initial data set.
At the end, to answer your question:
Both procedures gives us the same result, in same form, so what's the difference?
You didn't make a difference in your own results, this is why you didn't really notice the difference.
Other Examples:
You could use the OUT parameter in other kinds of procedures. Let's assume that your stored procedure doesn't return anything, it's more like a command to the DB, but you still want a kind of message back, or more specifically a value. Take these two examples:
CREATE PROCEDURE InsertDbAndGetLastInsertedId
--This procedure will insert your name in the database, and return as output parameter the last inserted ID.
#name nvarchar(60),
#LastId int OUT
as
Begin
insert into OutputParameterWithId values (#name);
SELECT #LastId = SCOPE_IDENTITY()
End
or:
CREATE PROCEDURE InsertIntoDbUnlessSomeLogicFails
--This procedure will only insert into the db if name does exist, but there's no more than 5 of it
#name nvarchar(60),
#ErrorMessage varchar(100) OUT
as
Begin
set #ErrorMessage = ''
if ((select count(*) from OutputParameterWithId) = 0)
begin
set #ErrorMessage = 'Name Does Not Exist'
return
end
if ((select count(*) from OutputParameterWithId) = 5)
begin
set #ErrorMessage = 'Already have five'
return
end
insert into OutputParameterWithId values (#name);
End
These are just dummy examples, but just to make the idea more clear.
An example, based on yours would be if you introduced paging to the query.
So the result set is constrained to 10 items, and you use a total count out parameter to drive paging on a grid on screen.
Answer from ozz regarding paging does not make sense because there is no input param that implements a contraint on the number of records returned.
However, to answer the question... the results returned by these stored procedures are not the same. The first returns the record count of contacts in given city in the out param ContactsCount. While the count may also be recieved in the second implement through examining the reader.Rows.Count, the actual records are also made a available. In the first, no records are returned - only the count.

how to use declare variable in select query in stored procedure using sql server

Hello I want to concate two things one is string and other is int variable. Now, these thing I want to store in one variable and use that variable in select query as a into type to create a temptable in stored procedure using sql server.
Here is my query
USE [FlightExamSoftware]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- For Storing Question in Temp table
-- EXEC [GetQuestionListPerSubjectRatioWise] 1,11
ALTER PROCEDURE [dbo].[GetQuestionListPerSubjectRatioWise]
#SubjectID INT,
#NumberOfQue INT,
#UserID int
AS
BEGIN
DECLARE #strQuery VARCHAR(MAX);
DECLARE #PerChapQue INT;
DECLARE #tempTable VARCHAR(MAX) = 'tempTestUser' + #UserID;
SELECT #PerChapQue = COUNT(appQueID)/#NumberOfQue FROM tblQuestion WHERE appQueSubID=#SubjectID
SELECT COUNT(appQueID)/#PerChapQue ChapwiseQue
,CASE WHEN COUNT(appQueID)>=#PerChapQue THEN COUNT(appQueID)/#PerChapQue ELSE 1 END ChapWiseQuePlusOne
,appQueChapID into #tempTable
FROM tblQuestion
WHERE appQueSubID=#SubjectID
GROUP BY appQueChapID
END
Now, I am talking about these line
DECLARE #tempTable VARCHAR(MAX) = 'tempTestUser' + #UserID;
In these line two things are concate one is string and other is int. And store in varchar variable.
And use in following select query i.e.
SELECT COUNT(appQueID)/#PerChapQue ChapwiseQue
,CASE WHEN COUNT(appQueID)>=#PerChapQue THEN COUNT(appQueID)/#PerChapQue ELSE 1 END ChapWiseQuePlusOne
,appQueChapID into #tempTable
FROM tblQuestion
WHERE appQueSubID=#SubjectID
GROUP BY appQueChapID
END
Now, in these query I want to create a temptable named #tempTable.
But, in these line it showing error i.e. Incorrect syntax near '#tempTable'.
Confuse that where is the syntax is wrong.
Thank You.
There are a number of things wrong with your code.
When concatenating an int to a string, you must first cast the int to varchar. Otherwise, SQL Server will try to implicitly convert the string to int, that will result with an error.
So this: DECLARE #tempTable VARCHAR(MAX) = 'tempTestUser' + #UserID; should become this:
DECLARE #tempTable VARCHAR(MAX) = 'tempTestUser' + CAST(#UserID AS VARCHAR(11)); (you need 11 chars to be able to fit the minimum value of int: -2,147,483,648)
You can't use select...into with a table variable.
You can only use it for actual tables (temporary or regular).
your #tempTable isn't even a table variable (not that it will help with a select...into).
Even if you would use select...into the correct way, unless you are going to use a global temporary table (and that doesn't come without it's risks), Unless your stored procedure uses this temporary table later on, it will be useless, since temporary tables are bound to scope.
Taking all of that into consideration I'm not sure what output you are actually looking for. If you could edit your question to include the desired output of your stored procedure as well as some sample data as DDL+DML, it would be easier to help you write better code.
Hope this Dynamic Query helps you:
Try like this:
USE [FlightExamSoftware]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- For Storing Question in Temp table
-- EXEC [GetQuestionListPerSubjectRatioWise] 1,11
ALTER PROCEDURE [dbo].[GetQuestionListPerSubjectRatioWise]
#SubjectID INT,
#NumberOfQue INT,
#UserID int
AS
BEGIN
DECLARE #strQuery VARCHAR(MAX);
DECLARE #PerChapQue INT;
DECLARE #tempTable VARCHAR(MAX) = 'tempTestUser' + CAST(#UserID AS VARCHAR);
SELECT #PerChapQue = COUNT(appQueID)/#NumberOfQue FROM tblQuestion WHERE appQueSubID=#SubjectID
SET #strQuery='
SELECT COUNT(appQueID)/'+CAST(#PerChapQue AS VARCHAR)+' ChapwiseQue
,CASE WHEN COUNT(appQueID)>='+CAST(#PerChapQue AS VARCHAR)+' THEN COUNT(appQueID)/'+CAST(#PerChapQue AS VARCHAR)+' ELSE 1 END ChapWiseQuePlusOne
,appQueChapID
INTO '+#tempTable+'
FROM tblQuestion
WHERE appQueSubID='+CAST(#SubjectID AS VARCHAR)+'
GROUP BY appQueChapID
/*.................................
And you have to use the temp table inside the String only
.................................*/
'
EXEC (#strQuery)
END

sp_executesql output parameter incorrect value

I'm getting different result for outputParam from fallowing two queries. The first one is generated by entity framework and it gives 0 for outputParam. For the second result is 5.
declare #p2 int
set #p2=0
exec sp_executesql N'usp_GetOrders #order_date, #output_param',N'#order_date datetime,#output_param int output',#order_date='2015-05-07 12:37:14.579',#output_param=#p2 output
select #p2 AS outputParam
declare #p2 int
set #p2=0
exec [dbo].[usp_GetOrders] #order_date='2015-05-07 12:37:14.579',#output_param=#p2 output
select #p2 AS outputParam
Procedure looks like this
CREATE PROCEDURE [dbo].[usp_GetOrders]
#order_date AS datetime,
#output_param AS int OUTPUT
AS
BEGIN
SELECT #output_param=5
SELECT o.Id
FROM dbo.[Order] o
WHERE OrderDate > #order_date
END
The reason is because you are missing output when calling the procedure using sp_executesql.
exec sp_executesql N'usp_GetOrders #order_date, #output_param output',N'#order_date datetime,#output_param int output',#order_date='2015-05-07 12:37:14.579',#output_param=#p2 output
Your direct procedure call is correct, what is why it is returning the correct value. If you call your procedure without output, it will return 0 as well.
exec [dbo].[usp_GetOrders] #order_date='2015-05-07 12:37:14.579',#output_param=#p2

Stored procedure doesn't return rows

I want to use SQL Server 2014 stored procedure in Report Builder.
ALTER PROCEDURE [dbo].[getCharacterDetails]
#id int
,#name VARCHAR(200) = '' OUTPUT
,#level int = 0 OUTPUT
AS
BEGIN
SELECT
#name = name, #level = level
FROM
dbo.Characters
WHERE
id = #id;
RETURN
END
I want to use #id as an input parameter and name and level as output only parameters.
When I call the procedure using Report Builder I get no data.
When I execute a query:
exec [dbo].[getCharacterDetails] #id= 1;
I also get no result values, only (1 row(s) affected) or Commands completed successfully.
The table Characters contains 1 row with id=1, so the select is correct.
Am I doing it right? Should I be using stored procedures or maybe UDF?
I'm new to SQL Server.
No, this stored procedure definitely doesn't return rows - because you're capturing the values into output parameters.
If you want to return rows - do not assign those columns to variables! Just write the select"as is".
So just this this SELECT statement instead:
SELECT
name, level
FROM
dbo.Characters
WHERE
id = #id;
and your stored procedure will now return a result set of data.
Try this:
ALTER PROCEDURE [dbo].[getCharacterDetails]
#id int
,#name VARCHAR(200) = '' OUTPUT
,#level int = 0 OUTPUT
AS
BEGIN
SELECT
name, level
FROM
dbo.Characters
WHERE
id = #id;
RETURN
END
Try running the stored procedure as:
declare #name VARCHAR(200);
declare #level int;
exec dbo.getCharacterDetails 1, #name output, #level output;
select #name, #level;
You have to provide the arguments and then look at them afterwards. That is how output parameters work.
If you want the stored procedure to return rows, then don't assign the values, or you can do both. The body could be:
SELECT #name = name, #level = level
FROM dbo.Characters
WHERE id = #id;
SELECT #name, #level;
And, for such a simple process, you might want just a view or user defined function.
Your data is cached, delete the data file (rdl.data) it's in the same folder your rdl is in
The name and level parameters serve no purpose. Remove them.
ALTER PROCEDURE [dbo].[getCharacterDetails]
#id int
AS
BEGIN
SELECT
name, level
FROM
dbo.Characters
WHERE
id = #id;
RETURN
END
call it like this:
EXEC [dbo].[getCharacterDetails] #ID
and make sure you map a SSRS parameter to the input parameter #ID in the parameters tab.
If you still don't get anything use SQL Profiler to work out what parameter it's passing in.

SQL Server - Trouble passing variable to a stored procedure

I know this is a basic question - but I can't figure the correct way to get this done.
I need to pass a variable to a SQL Server 2008 stored procedure and return the query.
Here's the stored procedure:
CREATE PROCEDURE pOrders
AS
DECLARE #enteredClientID varchar(20);
DECLARE #Results table (ClientID varchar(20), Num_orders int);
BEGIN
SET NOCOUNT ON;
-- Get all the order from the client
INSERT INTO #Results
SELECT ClientID, sum(Num_orders)
FROM Orders O
WHERE O.ClientID = #enteredClientID
GROUP BY O.ClientID);
-- Insert the orders into the results table --
SELECT *
FROM #Results;
END
GO;
Now, I would execute the stored procedure and get the result back:
exec pOrders
set #enteredClientID = 'ABC123456789'
I get this error message back:
Must declare the scalar variable "#enteredClientID".
But, I'm declaring the variable.... what am I missing?
You didn't declare a parameter, but a local variable. To declare it as you wanted to:
CREATE PROCEDURE pOrders (#enteredClientID varchar(20))
AS
DECLARE #Results table (ClientID varchar(20), Num_orders int);
SET NOCOUNT ON;
-- Get all the order from the client
INSERT INTO #Results
SELECT ClientID, sum(Num_orders)
FROM Orders O
WHERE O.ClientID = #enteredClientID
GROUP BY O.ClientID);
-- Insert the orders into the results table --
SELECT *
FROM #Results;
GO;
An to call it:
exec pOrders #enteredClientID = 'ABC123456789'
or simply
exec pOrders 'ABC123456789'
--In stored proc
DECLARE #enteredClientID varchar(20) OUTPUT
--Then insert and set identity
SELECT SCOPE_IDENTITY() AS #enteredClientID
--When calling procedure:
-- DECLARE variables to hold the return value
DECLARE #enteredClientID VARCHAR(20);
-- Execute the procedure, which returns value.
EXEC #enteredClientID = pOrders
Try EXEC pOrders 'ABC123456789'.
The call you provided attempts to execute the procedure (with no parameters passed), then attempts to set a variable named #enteredClientID. Since you have not declared #enteredClientID in the scope of the executing code, it cannot set it.
For more information about how to use parameters with procedures, this article may be helpful:
http://msdn.microsoft.com/en-us/library/ms189915.aspx

Resources