My question here would be... Why is it converting to int from varchar? I'm not sure what it is trying to do
CREATE PROCEDURE #myTestProcedure
(
#TransId VARCHAR(15)
)
AS
BEGIN
DECLARE #Result VARCHAR(15);
WITH TestCTE (TransId, AdjRefTransId) AS
(
SELECT TRANSID, ADJREFTRANSID
FROM dbo.MyTable
WHERE TRANSID = #TransId
UNION ALL
SELECT pet.TRANSID, pet.ADJREFTRANSID
FROM dbo.MyTable AS pet
JOIN TestCTE
ON TestCTE.ADJREFTRANSID = pet.TRANSID
)
SELECT #Result =
(
SELECT MAX(MyResult)
FROM dbo.MyOtherTable
WHERE TRANSID = TestCTE.TRANSID
)
FROM TestCTE
WHERE TestCTE.ADJREFTRANSID = ''
RETURN #Result
END
EXEC dbo.#myTestProcedure #TransId = 'MyTransId'
Error:
Msg 245, Level 16, State 1, Procedure #myTestProcedure 0004C61A, Line 32
Conversion failed when converting the varchar value 'MyResult' to data type int.
I can't see where it is trying to make this conversion. Line 32 is a blank line. No code there.
It is your RETURN. Stored procedures return an integer to indicate the status of the execution, not return values. You would either need to Select #Result OR have #Result be an output parameter.
Related
I get 'A TOP or FETCH clause contains an invalid value' this error
"
Msg 1014, Niveau 15, État 1, Procédure dbo.sp_contacts_getcontacts, Ligne 24 [Ligne de départ du lot 0]
A TOP or FETCH clause contains an invalid value. "
I want to get contacts using stored procedure , this is the code of the SP
( #Id uniqueidentifier = NULL,
#role nvarchar(max) = NULL,
#IdCompany uniqueidentifier = NULL,
#Active bit = 0,
#Page int = NULL,
#PerPage int = NULL,
)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON
-- Insert statements for procedure here
SELECT *
FROM [dbo].[Contacts]
LEFT JOIN [dbo].[Companies]
ON Contacts.[IdCompany] = Companies.[IdCompany]
WHERE
(#Id is null or #Id = [IdContact])
AND (#role is null or #role=contacts.[Role])
AND (#IdCompany is null or #IdCompany = [IdCompany])
AND (#Active = 0 or #Active = [Active])
ORDER BY [IdContact] OFFSET ((#Page - 1) * #PerPage) ROWS FETCH NEXT #PerPage ROWS ONLY
END
I could be misunderstanding your question.
If you want to grab the results from that select, you'll need a table variable that matches the output of the sproc to Insert Into.
DECLARE #someTable TABLE(
/* Whatever the output is of the sproc */
)
INSERT INTO #someTable
EXEC #return_value = dbo.nameOfYourSproc
You could also try creating a temp table from the results
INSERT INTO #someTable
EXEC #return_value = dbo.nameOfYourSproc
Although, my recommendation is to turn that SPROC into a table-valued function.
The code was correct , i just did not insert values for page and perpage this way it show the error 'FETCH...'
CREATE PROCEDURE sp_product_listing
(
#product varchar(30),
#month datetime,
#year datetime
)
AS
SELECT
'product_name' = products.name,
products.unit_price,
products.quantity_in_stock,
'supplier_name' = suppliers.name
FROM
suppliers
INNER JOIN
products ON suppliers.supplier_id = products.supplier_id
INNER JOIN
order_details ON products.product_id = order_details.product_id
INNER JOIN
orders ON order_details.order_id = orders.order_id
WHERE
products.name = #product
AND MONTH ('orders.order_date') = #month
AND YEAR ('orders.order_date') = #year;
GO
When some try to execute the procedure with wrong input, instead of getting this error message catch in exception block
Msg 8114, Level 16, State 5, Procedure sp_product_listing, Line 0
Error converting data type varchar to datetime.
From my comments : It is impossible to validate the input pram of an SP inside the same sp !
You need to undergo a validation of input prams.
So hear is an simple example to do this with error handling method.
GO
CREATE PROCEDURE ERROR_TEST
(
#month DATETIME,
#year DATETIME
)
AS
BEGIN
SELECT
MONTH (#month) [month],
YEAR (#year) [year]
END
GO
Now create a similar sp with same input prams.
GO
CREATE PROCEDURE ERROR_TEST_1
(
#month_1 VARCHAR(50),
#year_1 VARCHAR(50)
)
AS
BEGIN TRY
EXEC ERROR_TEST #month_1,#year_1
END TRY
BEGIN CATCH
IF ERROR_NUMBER() = 8114 --> update asper your error OR set > 0
BEGIN
PRINT 'INVALID MONTH OR YEAR'
END
END CATCH;
GO
Sample Execution :
EXEC ERROR_TEST_1 '1','2' ---> Error result
EXEC ERROR_TEST_1 '2015-11-15','2015-11-15'---> correct result
I have the following procedure;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
--re runnable.
IF EXISTS (SELECT 1 FROM sys.objects WHERE name = 'spGetMessageArray' AND type = 'P' )
BEGIN
DROP PROCEDURE dbo.spGetMessageArray
END
GO
CREATE PROCEDURE dbo.spGetMessageArray
#message VARCHAR(50),
#messageArray VARCHAR(50) OUTPUT
AS
BEGIN
SET NOCOUNT ON
SELECT #messageArray = (SELECT CAST(MessageId AS VARCHAR(5))+','
FROM Messages
WHERE Message = #message
FOR XML Path(''))
-- Remove trailing comma if necessary
SELECT #messageArray = LEFT(#messageArray, LEN(#messageArray) - 1)
RETURN #messageArray
END
When I run this as just a query (not as an sp), I get the results I want (33, 44, 53) as a comma separated string.
When I call this using;
DECLARE #message VARCHAR(50) = 'Safety'
DECLARE #messageArray VARCHAR(50) =''
EXEC dbo.spGetMessageArray #message, #messageArray = #messageArray OUTPUT
PRINT #messageArray
I get an error:
Conversion failed when converting the varchar value '33,44,53' to data type int.
Can anyone explain what I'm misunderstanding. I'm guessing the INT is some form of count of rows affected or something. I'm just so confused by that damn int. As far as I can tell, I'm just using VARCHAR
In testing output values from procs, why does the final select #TestValOut return 0 instead of null or an empty string?
I understand the correct way to do this is by using OUTPUT parameters, so the question really becomes: Why is the datatype of the set value of #TestValOut, at execution, an integer?
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'Custom.test') AND type in (N'P', N'PC'))
DROP PROCEDURE Custom.test
GO
CREATE PROCEDURE Custom.test (
#CurrentUserID INT = 1
)
As
Declare #TestValIn varchar(max)
select #TestValIn='asdf'
GO
BEGIN TRAN
Declare #TestValOut varchar(max)
set #TestValOut='ffff'
Exec #TestValOut=Custom.test #CurrentUserID=1
select #TestValOut
ROLLBACK
A return value in a stored procedure is always an integer, as a matter of fact you can only use an integer with a return value. The fact that you see 0 means the proc executed correctly, this is the return value that SQL Server returns telling you what the result of the proc execution is
For fun do a select 1/0 in the proc and you will see it won't be 0 anymore
See here
Is a return value of 0 always a success in stored procedures?
here are the examples from that answer
CREATE PROC pr_test AS
SELECT 1/0
RETURN 0
GO
Now run it
DECLARE #i INT
exec #i = pr_test
SELECT #i -- will be 0
DROP PROC pr_test
Now let's do it again without the return statement
CREATE PROC pr_test2 AS
SELECT 1/0
GO
DECLARE #i INT
exec #i = pr_test2
SELECT #i -- will be - 6
Better to use an output parameter to pass back statuses and or messages
I think what you're trying to do is use an output parameter, which should be done like this.
CREATE PROCEDURE Custom.test (
#CurrentUserID INT = 1,
#TestValOut varchar(max) OUTPUT
)
As
select #TestValOut='asdf'
GO
BEGIN TRAN
Declare #TestValOut varchar(max)
Exec Custom.test #CurrentUserID=1, #TestValOut OUTPUT
select #TestValOut
ROLLBACK
#TestValOut is assigned the value that would be returned by an "RETURN" like this:
CREATE PROCEDURE Custom.test (
#CurrentUserID INT = 1
)
As
Declare #TestValIn varchar(max)
select #TestValIn='asdf'
RETURN --defaults to zero, this is the value
GO
or
CREATE PROCEDURE Custom.test (
#CurrentUserID INT = 1
)
As
Declare #TestValIn varchar(max)
select #TestValIn='asdf'
RETURN 0 --this is the value
GO
Your stored procedure doesn't actually do anything at all: there is no resultset. To see the difference...
CREATE PROCEDURE Custom.test (
#CurrentUserID INT = 1
)
As
select * from sys.objects
RETURN 42 --random value
GO
DECLARE #rtn int
EXEC #rtn = Custom.test
--you have the output of sys.objects now
--and the scalar RETURN value
SELECT #rtn
You need to explicity say what value to return. Default is 0
CREATE PROCEDURE Custom.test (
#CurrentUserID INT = 1
)
As
Declare #TestValIn varchar(max)
select #TestValIn='asdf'
RETURN 0
GO
I would like to know if in SQL is it possible to return a varchar value from a stored procedure, most of the examples I have seen the return value is an int.
Example within a procedure:
declare #ErrorMessage varchar(255)
if #TestFlag = 0
set #ErrorMessage = 'Test'
return #ErrorMessage
You can use out parameter or the resulset to return any data type.
Return values should always be integer
CREATE PROCEDURE GetImmediateManager
#employeeID INT,
#managerName VARCHAR OUTPUT
AS
BEGIN
SELECT #managerName = ManagerName
FROM HumanResources.Employee
WHERE EmployeeID = #employeeID
END
Taken from here
You will need to create a stored function for that:
create function dbo.GetLookupValue(#value INT)
returns varchar(100)
as begin
declare #result varchar(100)
select
#result = somefield
from
yourtable
where
ID = #value;
return #result
end
You can then use this stored function like this:
select dbo.GetLookupValue(4)
Marc
A stored procedure's return code is always integer, but you can have OUTPUT parameters that are any desired type -- see http://msdn.microsoft.com/en-us/library/aa174792.aspx .