I have answered a bunch of questions over the last couple of days and some of them had to do with returning values from stored procedures
Everyone knows that you can return a value by using return inside a stored procedure. What everyone doesn't know is that return can only be an int data type
So how do you return something that is not an int (bigint, smallint etc etc) datatype
Let's take a look
We will start with a regular return statement, everything works as expected
--#1 return
CREATE PROCEDURE TestReturn
AS
SET NOCOUNT ON
DECLARE @i int
SELECT @i = DATEPART(hh,GETDATE())
RETURN @i
SET NOCOUNT OFF
GO
DECLARE @SomeValue int
EXEC @SomeValue = TestReturn
SELECT @SomeValue
GO
Now let's try returning a varchar
ALTER PROCEDURE TestReturn
AS
SET NOCOUNT ON
DECLARE @i VARCHAR(50)
SELECT @i = DATENAME(mm,GETDATE())
RETURN @i
SET NOCOUNT OFF
GO
DECLARE @SomeValue VARCHAR(50)
EXEC @SomeValue = TestReturn
SELECT @SomeValue
GO
Oops, it doesn't work the following message is returned (if you run it in September)
Server: Msg 245, Level 16, State 1, Procedure TestReturn, Line 7
Syntax error converting the varchar value 'September' to a column of data type int.
Let's try hard coding a character value
ALTER PROCEDURE TestReturn
AS
SET NOCOUNT ON
RETURN 'ab'
SET NOCOUNT OFF
GO
DECLARE @SomeValue VARCHAR(50)
EXEC @SomeValue = TestReturn
SELECT @SomeValue
GO
It is interesting that the procedure compiles without a problem. But when we try to run it the following message is displayed
Server: Msg 245, Level 16, State 1, Procedure TestReturn, Line 7
Syntax error converting the varchar value 'ab' to a column of data type int.
So what can we do? well we can use an OUTPUT parameter. By the way the following 4 ways to return a varchar values are in the order from best to worst
--#2 OUTPUT
ALTER PROCEDURE TestReturn @SomeParm VARCHAR(50) OUTPUT
AS
SET NOCOUNT ON
SELECT @SomeParm = 'ab'
SET NOCOUNT OFF
GO
DECLARE @SomeValue VARCHAR(50)
EXEC TestReturn @SomeParm = @SomeValue OUTPUT
SELECT @SomeValue
GO
Another way is to create a temp table and call the proc with insert..exec
--#3 Insert Into TEMP Table outside the proc
ALTER PROCEDURE TestReturn
AS
SET NOCOUNT ON
SELECT 'ab'
SET NOCOUNT OFF
GO
DECLARE @SomeValue VARCHAR(50)
CREATE TABLE #Test(SomeValue VARCHAR(50))
INSERT INTO #Test
EXEC TestReturn
SELECT @SomeValue = SomeValue
FROM #Test
SELECT @SomeValue
DROP TABLE #Test
GO
This one is almost the same as the previous example, the only difference is that ther insert happens inside the proc
And of course if you call the proc without creating the table you will get a nice error message
--#4 Insert Into TEMP Table inside the proc
ALTER PROCEDURE TestReturn
AS
SET NOCOUNT ON
INSERT INTO #Test
SELECT 'ab'
SET NOCOUNT OFF
GO
DECLARE @SomeValue VARCHAR(50)
CREATE TABLE #Test(SomeValue VARCHAR(50))
EXEC TestReturn
SELECT @SomeValue = SomeValue
FROM #Test
SELECT @SomeValue
DROP TABLE #Test
And last you create a permanent table with an identity, in the proc you insert into that table and you return the identity value. You can then use that identity value to get the varchar value
--#5 Insert Into A Table And Return The Identity value
CREATE TABLE HoldingTable(ID INT IDENTITY,SomeValue VARCHAR(50))
GO
ALTER PROCEDURE TestReturn
AS
SET NOCOUNT ON
DECLARE @i INT
INSERT INTO HoldingTable
SELECT 'ab'
SELECT @I = SCOPE_IDENTITY()
RETURN @i
SET NOCOUNT OFF
GO
DECLARE @SomeValue VARCHAR(50), @i INT
EXEC @i = TestReturn
SELECT @SomeValue = SomeValue
FROM HoldingTable
WHERE ID = @i
SELECT @SomeValue
DROP PROCEDURE TestReturn
4 comments:
http://www.sommarskog.se/share_data.html
You can return a cursor also.
True
thanks a lot
Post a Comment