How to change data type of output of stored procedure? I want to output money data type but procedure always returns int - sql

This is my procedure:
ALTER PROCEDURE spMaxOfInvoiceTotal
AS
BEGIN
DECLARE #max MONEY
SET #max = (SELECT MAX(InvoiceTotal) FROM Invoices)
PRINT #MAX
RETURN #MAX
END
GO
But when I execute, it returns int not money type.
DECLARE #return_value int
EXEC #return_value = [dbo].[spMaxOfInvoiceTotal]
SELECT 'Return Value' = #return_value
GO
As a result, a value is incorrect. It has to be 37966.19. But procedure returns 37966.
Even if I change #return_value money, I still get int. How to change procedure so return value would be money?

Stored procedure return value is used to return exit code, it is integer.
You should define output parameter
CREATE PROCEDURE mysp
#Maxval MONEY OUTPUT
http://msdn.microsoft.com/en-us/library/ms188655.aspx

What RDBMS is this for? SQL Server?
The value returned from a stored procedure in SQL Server is always INT and you can't change that - it's typically used to convey back a success/failure flag, or a "number of rows affected" information.
If you to "return" a MONEY (or better yet: DECIMAL) value - you can either use an OUTPUT parameter (which works fine for a single value), or you need to return a result set with that value.
So in your case, you could try something like:
CREATE PROCEDURE GetMaxOfInvoiceTotal
#MaxValue DECIMAL(20,4) OUTPUT
AS
BEGIN
SET #MaxValue = (SELECT MAX(InvoiceTotal) FROM Invoices)
END
GO
and then call this stored procedure like this:
DECLARE #RC INT
DECLARE #MaxValue DECIMAL(20,4)
EXECUTE #RC = [dbo].[GetMaxOfInvoiceTotal] #MaxValue OUTPUT
GO

Related

Why would a stored procedure return a 0 and the selected id?

I have a stored procedure like this:
CREATE PROCEDURE [dbo].[create_myNewId]
(#parentId BIGINT)
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [Mapping] (ParentId)
VALUES (#parentId)
SELECT SCOPE_IDENTITY();
END
This, when run on its own, returns the new id that has been assigned to the new row that's inserted with the parent id. However, when I do something like this:
DECLARE #NewId int
EXEC #NewId = create_myNewId #parentId = 33333
SELECT #NewId
When running this, the output window shows the result of the stored procedure, which returns an Id but #NewId always is 0. I fixed this by changing the stored procedure to use RETURN SCOPE_IDENTITY() but I was wondering why SELECT didn't work in this case?
I have my suspicions that it's something around the 0 being the success status being returned first from the stored procedure rather than the result, but was curious why this doesn't then happen when called directly from the client.
No! Write the procedure the right way:
CREATE PROCEDURE [dbo].[create_myNewId] (
#parentId bigint,
#outId bigint OUTPUT
) AS
BEGIN
SET NOCOUNT ON;
DECLARE #ids TABLE (id bigint);
INSERT INTO [Mapping](ParentId)
OUTPUT id INTO #ids
VALUES (#parentId);
SELECT #outId = id
FROM #ids;
END;
Then call this as:
DECLARE #NewId int;
EXEC create_myNewId #parentId = 33333, #NewId OUTPUT;
SELECT #NewId;
The OUTPUT clause is the recommend way to get results from a data-modification clause. The older methods using the *_IDENTITY() functions should be obsoleted.
Stored procedures do return values. These are integers that are designed to return status information. Other information should be returned via OUTPUT parameters.
Microsoft's design intent for stored procedures is that they always return an int to describe how successful the process undertaken by the procedure was. It's not intended to return a result data, and you're free to define the bits you want to return to describe succes, partial success etc. You could abuse it to return an integer result data (count query for example) if you wanted, but it's not the design intention
Executing a select query within a stored procedure creates a result set you can read on your client if the sproc is the kind that is intended to return data
My suggestion is to use an OUTPUT parameter. Not only will it be 'easier' to use when calling the stored procedure, it will also be clearer to the person calling the stored procedure.
CREATE PROCEDURE [dbo].[create_myNewId]
(#parentId BIGINT,
#myNewId BIGINT OUTPUT)
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [Mapping] ([ParentId])
VALUES (#parentId);
SET #myNewId = SCOPE_IDENTITY();
END;
GO
You would then call your stored procedure like this:
DECLARE #myNewId BIGINT;
EXECUTE [dbo].[create_myNewId] #parentId = 0, -- bigint
#myNewId = #myNewId OUTPUT; -- bigint
SELECT [This was just inserted] = #myNewId;
For anyone who has 0 as return value from a stored procedure, check if the stored procedure executes from the right database and only one procedure exists within the given context. Output parameters wouldn't be of any use if you ever plan to access the DB with ORM and the procedure returns an object's property.

A stored procedure returns multiple values but only need one

I'm trying to build a stored procedure that seems to return a grid. But I only need the first column of that grid. Below is the code I'm using to call the procedure
USE [OperationsView]
DECLARE #ProductionDate As DateTime
DECLARE #tag_in As VARCHAR(80)
DECLARE #FCChemGALPERMIN float
DECLARE #pi_server As VARCHAR(32)
DECLARE #endDate As DateTime
DECLARE #Debug As Bit
DECLARE #result As Float
SELECT #ProductionDate = '2016-12-01 07:00:00'
SELECT #tag_in = 'I-FC-835'
SELECT #pi_server = 'valpi'
SELECT #endDate = DATEADD(DAY, 1, #productionDate)
SELECT #Debug = 1
EXEC #FCChemGALPERMIN = Interface.proc_GetPIValueAverageTime
#result, #tag_in, #ProductionDate, #endDate, #pi_server, #Debug
PRINT #FCChemGALPERMIN
PRINT 'done'
Under the results tab I need that float value, I don't care about the percentage next to it. Below this picture is what I get from the messages tab. Basically I want to grab that float value and assign it to a variable so I can display it in the messages tab also.
Results tab looks like this:
Messages tab looks like this:
The ChemGALPERMIN displays 0 when I simply print that variable. What do I do to get desired float number?
If Interface.Proc_getpivalueaveragetime is a stored procedure and NOT a user defined function, then you CANNOT return a value from stored procedure like that.
UPDATE: if you are sure that your stored procedure will ALWAYS return only 1 float value and the stored procedure doesn't update physical tables data, then you can convert it to a user defined function (CREATE FUNCTION examples) then you will be able to use it the way you have it in your original post, i.e. #result = Interface.Proc_GetPIvalueAverageTime(...) .
But if you still want to keep it as a stored procedure call then you need to pass an additional parameter to Interface.Proc_GetPIValueAverageTime and mark it as OUTPUT. Then in the body of your stored procedure, probably in the end of it when you already have the needed float value, you need to set that additional OUTPUT param to the calculated float value.
So, in code it will look something like this (you need to update your stored procedure definition):
CREATE PROCEDURE Interface.proc_GetPIValueAverageTime
#result float,
#tag_in varchar(80),
#ProductionDate DATETIME,
#endDate DATETIME,
#pi_server VARCHAR(32),
#Debug bit,
-- new param below
#sproc_result float OUTPUT
AS
BEGIN
... do your calc ..
set #sproc_result = #calculation_result_as_float
END
Then in the calling context you need to define that extra result var (or use the one you already have called #result ) and pass that extra param to the stored procedure call:
declare #sproc_result float;
EXEC #FCChemGALPERMIN = Interface.proc_GetPIValueAverageTime
#result, #tag_in, #ProductionDate, #endDate, #pi_server, #Debug,
#sproc_result OUTPUT
-- here #sproc_result will have the float value you've assigned to it in the stored procedure body.
print cast(#sproc_result as varchar(15))
Note, IIRC you need to specify OUTPUT after the returning param both in the stored procedure definition and in the calling statement.
Note, you're already passing the #result var as the first param into your stored procedure. then just add OUTPUT modifier to it both in the stored procedure definition and calling statement and assign the value to it in the stored procedure body. This way you won't need the new stored procedure param which I've named #sproc_result.
HTH
Considering there is a need for second column some where else.
Insert the result into temp table and take the float value from there
Insert into #temp(float_col,percent_col)
EXEC Interface.Proc_getpivalueaveragetime
#result,
#tag_in,
#ProductionDate,
#endDate,
#pi_server,
#Debug
select #FCChemGALPERMIN= float_col
From #temp
If your second column is not useful at any case then alter your procedure from resulting percentage column

The formal parameter “#mode” was not declared as an OUTPUT parameter, but the actual parameter passed in requested output

I have this stored procedure:
ALTER PROCEDURE spCertificationType
#result nvarchar(15) output,
#mode int
AS
BEGIN
if #mode = 1
begin
exec spGeneratedID 2, #result output
print #result
end
END
but when I tried to execute it,it has this error
The formal parameter “#mode” was not declared as an OUTPUT parameter, but the actual parameter passed in requested output.
I tried to set #mode as output like this:
ALTER PROCEDURE spCertificationType
#result nvarchar(15) output,
#mode int output
AS
BEGIN
if #mode = 1
begin
exec spGeneratedID 2, #result output
print #result
end
END
but the it returns a null value.
Any fix for this? Thanks in advance.
the sequence of parameter in store procedure is that first use input parameter then use output parameter:-
you can see this link for more knowledge of store procedure:-
http://www.codeproject.com/Articles/126898/Sql-Server-How-To-Write-a-Stored-Procedure-in-SQL
ALTER PROCEDURE spCertificationType
#mode int,
#result nvarchar(15) output
AS
BEGIN
if #mode = 1
begin
exec spGeneratedID 2, #result output
print #result
end
END
I fixed this error a different way.
I had removed the OUTPUT statement after a parameter in my SP.
I then got the error.
I then went back to the SQLDataSource Configure Data Source wizard and went through the steps again. I discovered that changing the SP made the wizard delete the settings associated with the parameter that used to have OUTPUT after it.
In my case, I had declared the OUTPUT parameter last but was also getting a similar exception.
I moved the default parameters (like #var FLOAT = null) to the end after the output parameter then it started working.

Get scalar value from SELECT statement in stored proc, from within a stored proc

I know the preferred method for returning scalar values from stored procs is either using RETURN or an OUTPUT parameter. But lets say that I have a stored proc that returns the value using a select statement:
CREATE PROC spReturnNumber AS
SELECT 1
Is it possible to get this value from within another stored proc?
CREATE PROC spCheckNumber AS
EXEC spReturnNumber -- <-- get the return value here?
Clarification: I need a solution that doesn't require using an OUTPUT parameter, or using RETURN to return the value.
Thanks in advance.
You could use insert-exec to store the result of a stored procedure in a table:
declare #t table (col1 int)
insert #t exec spReturnNumber
return (select col1 from #t)
The definition of the table has to match the result set of the stored procedure.
Use an OUTPUT parameter instead of (or in addition to, if this procedure is used by other applications) the SELECT.
ALTER PROCEDURE dbo.spReturnNumber
#Number INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SET #Number = 1;
SELECT #Number;
END
GO
CREATE PROCEDURE dbo.spCheckNumber
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Number INT;
EXEC dbo.spReturnNumber #Number = #Number;
SELECT #Number;
END
GO
If you can't change the original procedure, but you know its output will remain static, you could use a #temp table.
CREATE PROCEDURE dbo.spCheckNumber
AS
BEGIN
SET NOCOUNT ON;
CREATE TABLE #n(i INT);
INSERT #n(i) EXEC dbo.spReturnNumber;
DECLARE #Number INT;
SELECT #Number = i FROM #n;
END
GO
You can't get the SELECT value from "parent" procedure but you can get the return value like this:
CREATE PROC A AS
BEGIN
DECLARE #ret int
EXEC #ret = spReturnNumber
RETURN #ret
END
If you are unable to change the proc being called .. place the result set in a temp table [or table variable]:
CREATE TABLE #results (val INT)
DECLARE #someval int
INSERT #results
EXEC dbo.spCheckNumber
SELECT #someval =val from #results

can we have a stored procedure with output parameters and return statement?

Can a stored procedure have output parameters and return statement? If so can anybody give me a simple example.thank you all.
Stored procedure can return integer type only in a return statement and can have any number of out parameters. See this for references supporting this.
Simplest eg of stored procedure
Return integer value from SP
CREATE procedure [sys].[sp_name]
(
#var1 bit = 0,
#publisher smallint
)
AS
BEGIN
IF #var1<> 0
RETURN (#publisher )
END
Using Out Parameter
CREATE PROCEDURE GetImmediateManager
#employeeID INT,
#managerID INT OUTPUT
AS
BEGIN
SELECT #managerID = ManagerID
FROM HumanResources.Employee
WHERE EmployeeID = #employeeID
END
You can use Transactions, Exception handling(try Catch), DDL and DML Queries, calling another stored procedure within one stored procedures and many more operations.
Please comments for more functionalities supported in stored procedure
If you mean the standard RETURN statement that gives an integer then yes
If you mean a UDF RETURN , then no. But a stored proc can have a normal SELECT
You are free to use both OUTPUT params and a single RETURN value:
CREATE PROCEDURE RaiseToPower (
#IN INT,
#OUT INT OUTPUT
)
AS
DECLARE #POWER INT
SET #POWER = 3
SET #OUT = POWER(#IN, #POWER)
RETURN #POWER
GO
/**/
DECLARE #POW INT, #RESULT INT
EXEC #POW = dbo.RaiseToPower 2, #RESULT OUTPUT
SELECT 2, 'raised to', #POW, 'is', #RESULT
>> 2 raised to 3 is 8
No. It is either a stored procedure or a scalar function.
A scalar function returns a value and takes 0 to n in parameters.
A stored procedure can take from 0 to n input parameters and can have 0 to n output parameters.