CREATE PROCEDURE dbo.test2
AS
BEGIN
DECLARE #status as int
DECLARE #error as int
SET #status = 1
SET #Error = ##ERROR
UPDATE dbo.BView
SET bview='dar'
WHERE pt='foo'
IF #Error > 0
print 'ERROR'
else
SELECT #status as 'status'
END;
Why does this query always return the default value of the local variable #status regardless of what was assigned to it?
status
------
0
Server version: MS SQL Server 2014 Express
In sql server 2005 : Run this in your sql server.
You cannot assign a default value at declaration.
and post the result in command.
DECLARE #status int
SET #status = 1
SELECT #status as 'status'
Suggestions. Although can't find some thing amiss, why not do it the normal way.
Always Declare a variable first before your update,insert or any action.
CREATE PROCEDURE dbo.sp_test2
AS
BEGIN
DECLARE #status as int
SET #status = 1
UPDATE dbo.BView
SET bview='dar'
WHERE pt='foo'
SELECT #status as 'status'
END
Second Always use the keyword AS then variable type , the followed by the size. If you dont follow by the variable size, it mostly return 0, note nvarchar types/varchar types mostly. Example
DECLARE #status as nvarchar
Often return 0 when use against a string of length 20 . Where as ,
Declare #status as nvacrhar(20)
Works fine.
There might exist an error in your update/Insert etc processes and i can see u put the declaration and the select process in the same node(i.e begin and end). You can check for an error like.
CREATE PROCEDURE dbo.sp_test2
AS
BEGIN
DECLARE #status as int
DECLARE #error as int
SET #status = 1
SET #Error = ##ERROR
--Some statement, update or insert, let's say:
UPDATE dbo.BView
SET bview='dar'
WHERE pt='foo'
IF #Error > 0
print 'ERROR'
else
SELECT #status as 'status'
END
These are suggestions though, I often do this way and it never fails me. FOr better understanding of variable in SQL Here and . Raising Errors in MSSql here and many more. Hope it helps.
Related
I am sure the solution is something super simple that I am missing but I keep getting a
SqlException: Procedure or function expects parameter which was not supplied
error. I am not a SQL wizard but to me the parameter looks okay. I did change the parameter and was not receiving this error but then when I consistently started receiving it I restored the stored procedure to the original version that I knew for a fact was fine but still receive it.
I tried executing the stored procedure like this
EXECUTE [dbo].[BHS_CloseCnt_Print_PackList] #palletid = '562992'
with a variable filled in. This stored procedure calls a function that determines the status of an order, if the variable I plug in and check with this method meets the criteria for the function I get an expected return.
If the container does not yet meet the function criteria, I get a null which I believe is okay.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[BHS_CloseCnt_Print_PackList]
(#PalletId numeric)
AS
BEGIN
Declare #PO as nvarchar(50)
Declare #Internal_Shipment_Num as numeric
Declare #Internal_Shipment_Line_Num as numeric
select top 1
#Internal_Shipment_Num = sc.INTERNAL_SHIPMENT_NUM,
#Internal_Shipment_Line_Num = sc.INTERNAL_SHIPMENT_LINE_NUM
from
SHIPPING_CONTAINER sc
where
INTERNAL_CONTAINER_NUM = #PalletId
or PARENT = #PalletId
and INTERNAL_SHIPMENT_LINE_NUM is not null
select #PO = dbo.fn_BHS_AllPOPLTS_CLOSED(#PalletId, #Internal_Shipment_Num, #Internal_Shipment_Line_Num)
print #PO
if #PO is not null
Begin
select #PalletId 'INTERNAL_CONTAINER_NUM', '60' 'DOCUMENT_TYPE'
End
End
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[fn_BHS_AllPOPLTS_CLOSED]
(#palletId numeric,
#Internal_Shipment_Num numeric,
#Internal_Shipment_Line_Num numeric)
RETURNS nvarchar(50)
AS
BEGIN
Declare #PO nvarchar(50)
Declare #OPENPO nvarchar(50)
Declare #IntShip as numeric
select #PO = isnull(sd.CUSTOMER_PO, 'FEIT')
from SHIPMENT_DETAIL sd
where sd.INTERNAL_SHIPMENT_LINE_NUM = #Internal_Shipment_Line_Num
and sd.internal_shipment_num = #Internal_Shipment_Num
select #OPENPO = isnull(sd.CUSTOMER_PO, '')
from shipping_container sc
join SHIPMENT_DETAIL sd on sd.INTERNAL_SHIPMENT_LINE_NUM = sc.INTERNAL_SHIPMENT_LINE_NUM
where sd.CUSTOMER_PO = #PO and sc.INTERNAL_SHIPMENT_NUM = #Internal_Shipment_Num
and sc.status < 600
if(isnull(#OPENPO, '') != '')
Begin
set #PO = null
End
return #PO
End
The stored procedure looks to have stored the cache from the previous edit I did although a known working version was restored.
Resolution for this was to run DBCC FREEPROCCACHE to clear the stored procedure cache and I was able to execute as expected.
Thanks Nemanja Perovic!
I wonder if there is a way update a column (which is not null) as 'NULL' with optional parameter in this stored procedure.
For example;
testid test test2
1 4 3
Update just test column as null
testid test test2
1 NULL 3
Edit--
This is a common structure for partial update of a table. But its not possible to set a column(which has a different value than default value of optional parameter) as (default value of optional parameter). If you have other suggestions rather than this for partial updating of a table please share.
Thanks
ALTER PROCEDURE [Pay].[UpdTest] (
#testid int,
#test int =null,
#test2 int =null
)
AS
BEGIN
UPDATE
[Pay].[Test]
SET
test =COALESCE(#test,test)
test2 =COALESCE(#test2,test2)
WHERE
testid =#testid
END
There is a way to tell if the default value of the optional parameter was explicitly specified. A quick and dirty way is to have the command passed on to SQL as literal, and use a wrapper procedure to test the parameters. Remember that you'd have to hard-code the default value in the wrapper procedure so if it gets changed, you'd have to change the wrapper of course.
Below is an example of how to process an input SQL command in a very simple manner. From this wrapper, you can return a flag to notify the main procedure what to do.
CREATE PROCEDURE TestWapper
(#RESULT INT OUTPUT)
AS
SET NOCOUNT ON;
DECLARE
#SQL AS NVARCHAR(200),
#NumberCommas AS INT,
#LOC1 AS INT,
#LOC2 AS INT,
#Param1Literal AS VARCHAR(50),
#Param2Literal AS VARCHAR(50)
--Set the SQL Command
SET #SQL = N'EXEC SetColumnNull 5, NULL';
--How many commas can tell us how many parameters MIGHT have been used
SET #NumberCommas = LEN(#SQL)-LEN(REPLACE(#SQL,',',''));
--Iterate through and see what the parameters are
IF #NumberCommas = 0
BEGIN
PRINT 'no optional parameter was specified'
SET #RESULT = 0
RETURN
END
IF #NumberCommas = 1 --the 1st optional parameter might have been specified
BEGIN
--let's get the location of the comma first
SET #LOC1 = CHARINDEX(',',#SQL);
SET #Param1Literal = LTRIM(SUBSTRING(#SQL,#LOC1+1,LEN(#SQL)))
IF #Param1Literal = 'NULL'
BEGIN
PRINT 'parameter1 : ' + #Param1Literal + ' was used'
SET #RESULT = 1;
END
ELSE
SET #RESULT = 0;
RETURN
END;
--IF #NumberCommas = 2 -- do similar things
END
If you don't have access to the command text, then I don't see any way to compare NULL as the default parameter value to NULL as the specified parameter value.
I am trying to write a stored procedure which inserts the username and password into the database. And there is an Identity column which auto-increments itself. But I am not able to get the syntax correct !
Here is the code snippet:
CREATE PROCEDURE dbo.SPRegisterUser
#Username_V nvarchar(100),
#Email_V nvarchar(100),
#Password_V nvarchar(100)
AS
BEGIN
Declare #count int;
Declare #ReturnCode int;
Select #count = COUNT(Username)
from Register
where Username = #Username_V
If #count > 0
Begin
Set ReturnCode = -1
End
Else
Begin
Set ReturnCode = 1
Insert into Register
values(#Username_V, #Email_V, #Password_V)
END
RETURN
The error generated is
Incorrect Syntax near'='
Incorrect syntax near RETURN
First of all, the following line
RETURN
needs to be replaced by this
RETURN #ReturnCode
Also you're missing the final END
Also, variables need to start with a #, so change the two lines
SET ReturnCode ...
to
SET #ReturnCode ...
It must be:
Set #ReturnCode=1
It is a variable declared further up.
I have seen this question all over stackoverflow, but it seems that there are a wide number of solutions tailored to the situation. It seems I have a unique situation as far as I can tell. I am running this sql statement
use IST_CA_2_Batch_Conversion
GO
--T-SQL script to populate the Match type column
declare #MatchType varchar(16),
#PK varchar(500),
#CAReturnCode VARCHAR(255),
#CAErrorCodes VARCHAR(255)
declare cursor1 cursor fast_forward for
select
["Ref#"],
["Return Code"],
["Error Codes"]
from CACodes2MatchType
open cursor1
fetch next from cursor1 into #PK,#CAReturnCode,#CAErrorCodes
while ##fetch_status = 0
begin
set #MatchType = dbo.GetMatchType(#CAReturnCode,#CAErrorCodes)
update CACodes2MatchType
set [Match Type] = #MatchType
where ["Ref#"] = #PK
fetch next from cursor1 into #PK,#CAReturnCode,#CAErrorCodes
end
close cursor1
deallocate cursor1
It will fail at
set #MatchType = dbo.GetMatchType(#CAReturnCode,#CAErrorCodes)
Here is the beginning code for the GetMatchType function:
-- Batch submitted through debugger:
SQLQuery14.sql|6|0|C:\Users\b01642a\AppData\Local\Temp\~vs1C8E.sql
CREATE FUNCTION [dbo].[GetMatchType](#CAReturnCode VARCHAR(255), #CAErrorCodes
VARCHAR(255))
RETURNS VARCHAR(16)
BEGIN
DECLARE #MatchType VARCHAR(16);
DECLARE #errorCodes TABLE(Pos INT, Code CHAR(2));
DECLARE #country INT; -- 1 is US, 2 is Canada
DECLARE #numMinorChanges INT;
DECLARE #numMajorChanges INT;
DECLARE #numSingleCodes INT;
DECLARE #returnCode INT;
DECLARE #verified VARCHAR(16);
DECLARE #goodFull VARCHAR(16);
DECLARE #tentativeFull VARCHAR(16);
DECLARE #poorFull VARCHAR(16);
DECLARE #multipleMatch VARCHAR(16);
DECLARE #unmatched VARCHAR(16);
SET #verified = 'Verified';
SET #goodFull = 'Good Full';
SET #tentativeFull = 'Tentative Full';
SET #poorFull = 'Poor Full';
SET #multipleMatch = 'Multiple Match';
SET #unmatched = 'Unmatched';
SET #returnCode = CAST(#CAReturnCode AS INT);
I will get the error: Msg 245, Level 16, State 1, Line 21
Conversion failed when converting the varchar value '"1"' to data type int.
This error occurs at the last line of the code segment I have shown:
SET #returnCode = CAST(#CAReturnCode AS INT);
This is code that was written by a colleague and supposedly had worked for him. I have had to troubleshoot some errors but I cannot debug this one. I understand alot of people will create a dbo.split function? I don't know if this option will help me in this scenario. I have tried setting #returnCode to a varchar and getting rid of the CAST on #CAReturnCode. As a result, the debugger will make it past that line but raises issues with the rest of the code. I am assuming there is an issue with how I am casting #CAReturnCode? Any help would be much appreciated.
The problem is that #CAReturnCode contains non-numeric characters.
-- Msg 245, Level 16, State 1, Line 21 Conversion failed when converting the varchar value '"1"' to data type int.
See, the outer single quotes are the error message's formatting, but the inner double quotes are in the #CAReturnCode value. So the solution here is to ensure that the variable contains only numeric characters prior to converting. If double quotes are the only possibility, you can do a quick and dirty fix like this:
set #returnCode = cast(replace(#CAReturnCode, '"', '') as int)
If there are more possibilities, you could do multiple REPLACE calls, or you could build a better character-trimming function that will remove all the characters you specify at once yourself.
Can we return null value from stored procedure. i dont want to use collase or isnull. I want to capture NULL at the frontend. Is it possible ?
Edit:
I am using Sql Server 2005
eg. where i want to use
CREATE PROCEDURE [Authentication].[spOnlineTest_CheckLogin]
#UserName NVARCHAR(50)
AS
BEGIN TRY
BEGIN TRAN
COMMIT TRAN
RETURN NULL
END TRY
Error
The 'spOnlineTest_CheckLogin' procedure attempted to return a status of NULL, which is not allowed. A status of 0 will be returned instead.
Msg 0, Level 11, State 0, Line 0
A severe error occurred on the current command. The results, if any, should be discarded.
No, the return type of a stored procedure is INT and it cannot be null.
use an output parameter, example
CREATE PROCEDURE Test
#UserName NVARCHAR(50), #Status int output
AS
BEGIN TRY
BEGIN TRAN
COMMIT TRAN
set #Status = null
END TRY
begin catch
end catch
go
then call it like this
declare #s int
set #s =5
exec Test'bla',#s output
select #s --will be null
You can think of a proc like follows. Let me first set the context. We might have a table Table1(id int, name varchar(2), Address varchar(2)) and want to get the id and if not found, it will be null. So we might write a proc like the following:
CREATE PROCEDURE GetId
#Name VARCHAR(50), #Status int output
AS
BEGIN TRY
set #Status = null
select #Status = id from Table1 where name=#name
This will work for you.