Can not write the value to a variable - sql

I have a function, which needs to return true if there is a row in a table with values which user inputs.
I need to write the value to a variable which Ii return, but I got an error:
Incorrect syntax near '#ret'.
USE BDLab5;
GO
Create Function WasComplaint (#date date, #component varchar)
Returns BIT
Begin
Declare #was int, #ret bit
Select #was = ComponentCode from Complaints
Where ComplaintDate = #date AND
ComponentCode = (Select ComponentCode from Components Where ComponentName = #component)
if (#was = 0)
#ret = 0
else
#ret = 1
Return #ret
End;
I tried different variant of if else syntax but it doesn't help.

You need to use SET when assigning a value to a variable.
USE BDLab5;
GO
Create Function WasComplaint (#date date, #component varchar)
Returns BIT
Begin
Declare #was int, #ret bit
Select #was = ComponentCode from Complaints
Where ComplaintDate = #date AND
ComponentCode = (Select ComponentCode from Components Where ComponentName = #component)
if (#was = 0)
set #ret = 0
else
set #ret = 1
Return #ret
End;

Put the word SET before #ret when you give it a value

Related

Generate Next Alphanumeric Code on SQL Server

I need to create a consecutive sequence of varchar(5) (always 5 chars only) code starting from PREVIOUS code.
For example
'00000', '00001', '00002'...'00009', '0000A', '0000B'...'0000Z', '00010','00011'...'ZZZZZ'.
So if I have #PREVIOUS_CODE = '00000', #NEXT_CODE will be '00001'.
If I have #PREVIOUS_CODE = '00009', #NEXT_CODE will be '0000A'
If I have #PREVIOUS_CODE = '0000Z', #NEXT_CODE will be '00010'
So I need something like that
USE [DATABASE]
GO
CREATE PROCEDURE [dbo].[spGetNextCode]
#PREVIOUS_CODE VARCHAR(5)
AS
DECLARE #NEXT_CODE VARCHAR(5)
DO STUFF
...
SELECT #NEXT_CODE AS NEXT_CODE
GO
Any Help?
Just keep an integer counter in the same table and convert it. I'm using the following SQL Server function in one of my applications:
CREATE FUNCTION [dbo].[GetAlphanumericCode]
(
#number BIGINT,
#leadingzeroes INT = 0
)
RETURNS varchar(255)
AS
BEGIN
DECLARE #charPool varchar(36)
SET #charPool = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
DECLARE #result varchar(255)
IF #number < 0
RETURN ''
IF #number = 0
SET #result = '0'
ELSE BEGIN
SET #result = ''
WHILE (#number > 0)
BEGIN
SET #result = substring(#charPool, #number % 36 + 1, 1) + #result
SET #number = #number / 36
END
END
IF #leadingzeroes > 0 AND len(#result) < #leadingzeroes
SET #result = right(replicate('0', #leadingzeroes) + #result, #leadingzeroes)
RETURN #result
END
It should be a trivial task to rewrite it as a stored procedure

Why is SQL output parameter always null

I have the following SP
CREATE PROCEDURE [dbo].[GetBaseSixtyTwoString]
#a_number_to_convert int,
#v_temp_val nvarchar(256) output
AS
DECLARE #v_modulo INTEGER;
DECLARE #v_temp_int decimal(38) = #a_number_to_convert;
DECLARE #v_temp_char VARCHAR(1);
DECLARE #c_base62_digits VARCHAR(62) = '0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ';
IF ( #a_number_to_convert = 0 )
BEGIN
SET #v_temp_val = '5';
END
WHILE ( #v_temp_int <> 0 )
BEGIN
SET #v_modulo = #v_temp_int % 62;
SET #v_temp_char = substring( #c_base62_digits, #v_modulo + 1, 1 );
SET #v_temp_val = #v_temp_char + #v_temp_val;
SET #v_temp_int = floor(#v_temp_int / 62);
END
I am calling it like this:
declare #shorturl nvarchar(256)
exec dbo.GetBaseSixtyTwoString 1, #shorturl output
But the variable #shorturl always returns null
However if I put print statements in the SP I can see that #v_temp_val is indeed getting the correct value.
What am I missing?
You need to initialise #v_temp_val inside the stored procedure to non-NULL value, to ''.
If #v_temp_val is NULL, then this line would still result in NULL:
SET #v_temp_val = #v_temp_char + #v_temp_val;
because "value" + NULL = NULL
check if any value you put into variable #v_temp_val is null. note that any non-null value + NULL will result to NULL:
SET #v_temp_val = ISNULL(#v_temp_char, '') + ISNULL(#v_temp_val, '');

Update error on stored procedure on updating time

I have this stored procedure that update the actual date of an answer but return a conversion error :
ALTER procedure [dbo].[MensajeCompletado]
#id int,
#RESPUESTA nvarchar(50),
#resp int = 1 output
AS
if Exists(select * from OFICIOS where IdOficio = #id)
begin
update OFICIOS
set Respuesta = #RESPUESTA,
FechaRecibido = CONVERT(nvarchar(11), GETDATE(), 105),
Estatus = 2
where IdOficio = #id
set #resp = 0
end
else
begin
set #resp = 1
end
I get this error:
Conversion failed when converting date and/or time from character string.
Sorry for my english :)
If FechaRecibido is a DATE - why on earth are you converting GETDATE() into a NVARCHAR then!?
Just assign the output of GETDATE (or better: SYSDATETIME) to your column by casting to a DATE:
update OFICIOS
set Respuesta = #RESPUESTA,
FechaRecibido = CAST(SYSDATETIME() AS DATE),
Estatus = 2
where IdOficio = #id
but most definitely don't convert to a nvarchar !!
It is failing because you are returning a string format that it cannot implicitly convert. Just CAST it to DATE instead. This should work:
ALTER procedure [dbo].[MensajeCompletado]
#id int,
#RESPUESTA nvarchar(50),
#resp int = 1 output
AS
if Exists(select * from OFICIOS where IdOficio = #id)
begin
update OFICIOS
set Respuesta = #RESPUESTA,
FechaRecibido = Cast (GETDATE() as Date)
Estatus = 2
where IdOficio = #id
set #resp = 0
end
else
begin
set #resp = 1
end

Uniqueidentifier as parameter in SQL Server Function

I have created a Function in SQL Server 2012 that I will use in a Check Constraint on a table.
The function works as expected if I do:
SELECT [dbo].[CheckValidCardnumberForShellTankingen] ('700678036658047691' ,'2925CA00-6DD5-4F9D-AB0E-AA15DBBD388B')
But when I try to set the expression in Check Constraint so:
([dbo].[CheckValidCardnumberForShellTankingen]([Volledig kaartnummer],[RollBackCode])=(1))
I get a Messaage: "Error validating constraint 'CK_MyConstraint'"
I use the Uniqueidentifier in a Where clause and the strange thing is if I replace the parameter with string containing the Uniqueidentifier I dont get this error.
Here is the Function:
-- =============================================
-- Author: Anders Pedersen
-- Create date: 2015-02-13
-- Description: Check of the Cardnumber of a transaction is valid.
-- =============================================
CREATE FUNCTION [dbo].[CheckValidCardnumberForShellTankingen]
(
-- Add the parameters for the function here
#Cardnumber NvarChar(50),
#RollBackCode NvarChar(200)
)
RETURNS BIT
AS
BEGIN
-- Declare the return variable here
DECLARE
#Result BIT
,#ResultLenght BIT
,#ResultPrefix BIT
,#CardLenght INT
,#SupplierID INT
,#UseCardnumber BIT
,#Prefix NvarChar(50)
-- Add the T-SQL statements to compute the return value here
SET #Result = 0
SET #ResultLenght = 0
SET #ResultPrefix = 0
SET #CardLenght = -1
SET #SupplierID = -1
SET #UseCardnumber = 0
SET #Prefix = ''
-- Get the UseCardnumber and the SupplierID
SELECT #UseCardnumber = C.UseCardNumber, #SupplierID = F.SupplierID
FROM Client C INNER JOIN
ClientFileUploads F ON C.ClientID = F.ClientID
WHERE F.RollBackCode = #RollBackCode
--WHERE F.RollBackCode = '2925CA00-6DD5-4F9D-AB0E-AA15DBBD388B'
-- Only carry out the check if the Client use Cards else set the check to True (1)
IF #UseCardnumber = 1
BEGIN
SELECT #CardLenght = [CardNumberLenght], #Prefix = ISNULL([Prefix],'') FROM [dbo].[Supplier] AS S WHERE S.SupplierID = #SupplierID
IF (#CardLenght IS NULL) OR (#CardLenght = 0)
BEGIN
SET #ResultLenght = 1
END
ELSE
BEGIN
IF (LEN(#Cardnumber) - #CardLenght)= 0
BEGIN
SET #ResultLenght = 1
END
ELSE
BEGIN
SET #ResultLenght = 0
END
END
IF SUBSTRING(#Cardnumber, 1, LEN(#Prefix)) = #Prefix
BEGIN
SET #ResultPrefix = 1
END
ELSE
BEGIN
SET #ResultPrefix = 0
END
IF ((#ResultLenght = 1) AND (#ResultPrefix = 1))
BEGIN
SET #Result = 1
END
ELSE
BEGIN
SET #Result = 0
END
END
ELSE
BEGIN
SET #Result = 1
END
-- Return the result of the function
RETURN #Result
END
GO
If #RollBackCode is a uniqueidentifier, I recommend making the parameter a uniqueidentifier and not a varchar.
As Rhys Jones points out, you shouldn't use a UDF in a check constraint.
See
https://dba.stackexchange.com/questions/22297/udf-in-check-constraint-downside
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/078b720f-faac-425c-b51a-33bcecb263d2/check-constraint-with-udf-problem-with-lots-of-data?forum=transactsql
http://sqlblog.com/blogs/tibor_karaszi/archive/2009/12/17/be-careful-with-constraints-calling-udfs.aspx
If you need to check in a trigger and roll back -- SQL Server - After Insert/ For Insert - Rollback

Convert a number to letters

Given a number, how do you convert that to letters?
You can just translate your existing logic into a t-sql scalar function, like so:
CREATE FUNCTION dbo.fnColumnNameFromIndex(#i int)
RETURNS varchar(3)
AS
BEGIN
DECLARE #dividend int, #letters varchar(3), #modulo int
SET #dividend = #i
SET #letters = ''
WHILE #dividend > 0
BEGIN
SET #modulo = (#dividend - 1) % 26
SET #letters = CHAR(65 + #modulo) + #letters
SET #dividend = CONVERT(int, (#dividend - #modulo) / 26 )
END
RETURN #letters;
END
GO
Call it like this:
SELECT dbo.fnColumnNameFromIndex(2000)
...admittedly not set logic, but I don't see this as a set logic problem.