My IF..ELSE block fails at BEGIN. I can understand how my expression is not boolean in nature, but what is causing this failure?
IF (SUBSTRING(#PARIDIN,1,1) = 'P'
BEGIN
SET #PARIDTEMP = SUBSTRING(LTRIM(RTRIM(#PARIDIN)),2,6))
END
BEGIN
ELSE SET #PARIDTEMP = #PARIDIN
END
You have an extra set of parentheses in a weird place.:
IF SUBSTRING(#PARIDIN,1,1) = 'P' -- one at the beginning of this line.
BEGIN
SET #PARIDTEMP = SUBSTRING(LTRIM(RTRIM(#PARIDIN)),2,6) -- one at the end of this line.
END
ELSE
BEGIN
SET #PARIDTEMP = #PARIDIN
END
You are not closing the expression being evaluated.
Change
IF (SUBSTRING(#PARIDIN,1,1) = 'P'
To
IF (SUBSTRING(#PARIDIN,1,1) = 'P')
Taking everybody else's suggestion of fixing the condition I am surprised nobody mentioned the very strange BEGIN END blocks. They don't make sense and not sure they would even work. Since you have only a single statement for each it makes more sense to remove them.
IF (SUBSTRING(#PARIDIN,1,1) = 'P')
SET #PARIDTEMP = SUBSTRING(LTRIM(RTRIM(#PARIDIN)),2,6))
ELSE
SET #PARIDTEMP = #PARIDIN
Related
I'm using SQL Server 2016 database project and my script is like below
DECLARE Marker NVARCHAR(50) = (SELECT Value FROM Table1 WHERE name = 'Marker')
IF( IS NOT NULL)
BEGIN
IF #Marker = 'Marker1' GOTO Marker2;
IF #Marker = 'Marker2' GOTO Marker3;
IF #Marker = 'Marker3' GOTO Marker4;
IF #Marker = 'Marker4' GOTO Marker5;
IF #Marker = 'Marker5' GOTO Marker6;
IF #Marker = 'Marker6' GOTO Marker7;
ELSE GOTO EmptyBlock;
END
MARKER1:
Code for marker 1
MARKER2:
Code for marker 2
MARKER3:
Code for marker 3
.
.
.
EmptyBlock:
PRINT 'No changes'
This script file will be executed after every deployment and based on deployment it will be skipping the previous lines and now it will be reached to marker 15.
It's taking too much time to execute even though there are few lines of code, I've finally found the issue due to GOTO statements. I don't know if using GOTO is best practice or not, if its not good practice using it in production site then please give me the suggestions for an alternate of GOTO.
You can replace the GOTO statements with a script like this using IF:
-- get the number of the marker (instead of the full name of the marker).
DECLARE #Marker INT = (SELECT REPLACE(Value, 'Marker', '') FROM Table1 WHERE name = 'Marker')
IF #Marker IS NULL
BEGIN
PRINT 'no marker'
END
IF #Marker < 1
BEGIN
-- Code for Marker No. 1
END
IF #Marker < 2
BEGIN
-- Code for Marker No. 2
END
IF #Marker < 3
BEGIN
-- Code for Marker No. 3
END
IF #Marker < 4
BEGIN
-- Code for Marker No. 4
END
ELSE IF #Marker IS NOT NULL
BEGIN
PRINT 'no changes'
END
demo on dbfiddle.uk
I have an Oracle function that needs to be converted to SQL-Server function
This is the Oracle Function:
FUNCTION check_education(in_crs_code IN VARCHAR2)
RETURN BOOLEAN IS
v_bool BOOLEAN := FALSE;
v_dummy VARCHAR2(1);
CURSOR find_education IS
SELECT 'x'
FROM KU_LIBRARY_EDUCATION_EXTLOAN
WHERE UPPER(course_code) = UPPER(in_crs_code) AND in_use = 'Y';
BEGIN
OPEN find_education;
FETCH find_education INTO v_dummy;
IF find_education%FOUND THEN
v_bool := TRUE;
ELSE
v_bool := FALSE;
END IF;
CLOSE find_education;
RETURN (v_bool);
END check_education;
This is what I have written in SQL-Server to replicate Oracle function:
CREATE FUNCTION [dbo].[check_education](#in_crs_code VARCHAR(4000))
RETURNS BIT AS
BEGIN
DECLARE #v_bool BIT = 0;
DECLARE #v_dummy VARCHAR(1);
DECLARE find_education CURSOR LOCAL FOR
SELECT 'x'
FROM [dbo].[KU_LIBRARY_EDUCATION_EXTLOAN]
WHERE UPPER(course_code) = UPPER(#in_crs_code)
AND in_use = 'Y';
OPEN find_education;
FETCH find_education INTO #v_dummy;
IF ##CURSOR_ROWS >1 BEGIN
SET #v_bool = 1;
END
ELSE BEGIN
SET #v_bool = 0;
END
CLOSE find_education;
DEALLOCATE find_education;
RETURN (#v_bool);
END;
I would expect the SQL server function to return 1 if the cursor returns 'x' but i'm getting 0. Anu help will be appreciated.
I would suggest using an inline table valued function instead of a scalar function. To make sure this is an inline table valued function it MUST be a single select statement. This means there can't be loops and other stuff. Fortunately this query does not actually need any loops. A simple count will return the number of rows. And any value other than 0 when converted to a bit will always be 1.
CREATE FUNCTION [dbo].[check_education]
(
#in_crs_code VARCHAR(4000)
) RETURNS table as return
SELECT CourseExists = convert(bit, count(*))
FROM [dbo].[KU_LIBRARY_EDUCATION_EXTLOAN]
WHERE UPPER(course_code) = UPPER(#in_crs_code)
AND in_use = 'Y';
This is a mere EXISTS thing, so we could try
CREATE FUNCTION [dbo].[check_education](#in_crs_code VARCHAR(4000)) RETURNS BIT AS
BEGIN
RETURN EXISTS ( <query> )
END;
But as far as I know, SQL Server doesn't accept this (though I cannot say why not - maybe it's because of their lack of a real boolean; Oracle doesn't accept it, because EXISTS is no keyword in their PL/SQL programming language).
So we'd use IF/ THEN/ ELSE:
CREATE FUNCTION [dbo].[check_education](#in_crs_code VARCHAR(4000)) RETURNS BIT AS
BEGIN
IF EXISTS
(
SELECT 'x'
FROM ku_library_education_extloan
WHERE UPPER(course_code) = UPPER(in_crs_code) AND in_use = 'Y'
)
RETURN 1
ELSE
RETURN 0
END
END;
There may be errors, because I've never coded a stored procedure in T-SQL, but anyway, you get the idea.
Hello there I have a Function and is introduction a variable which will bring a letter or a number, if the variable is a letter it need to cause an error and return a 0, or if is a number then return 1.
SO in T-SQL I have a Procedure that eventually will call this function to check is is a number:
IF dbo.VALIDNUMBER(#sTxpX) != 0 AND #sTxpX IS NOT NULL
The variable #sTxpX is holding a value which is 'T' so I know it needs to return 0 from the function because is invalid to be a numeric, but Im not getting the proper function to build it, I will appreciate some help here.
CREATE FUNCTION DBO.VALIDNUMBER (#sTextStr VARCHAR(4000)) RETURNS BIT AS
BEGIN
DECLARE #bValidNumberStr BIT = 1; DECLARE #nTest BIGINT;
SET #nTest = CAST(#sTextStr AS numeric(38, 10)) + 1;
RETURN #bValidNumberStr;
EXCEPTION
WHEN OTHERS THEN
SET #bValidNumberStr = 0;
RETURN #bValidNumberStr;
END;
Try this function:
CREATE function [dbo].[VALIDNUMBER]
(#strText VARCHAR(4000))
RETURNS BIT
AS
BEGIN
DECLARE #Return as bit
IF TRY_CAST(#strText AS NUMERIC(38,10)) IS NOT NULL BEGIN
SET #Return = 1
END ELSE BEGIN
SET #Return = 0
END
RETURN #Return
END
Why can't you use the built-in SQL function? It's faster, and no need for you to drive yourself crazy to come up with a solution.
In your procedure do the following:
DECLARE #isNumber bit;
IF (ISNUMERIC(#sTextStr) = 1)
BEGIN
SET #isNumber = 1
END
ELSE
BEGIN
SET #isNumber = 0
RAISERROR(15600, 16, 20, 'That was not a number')
END
You can pass the #isNumber variable back to the user at a later point in time.
I'm trying to setup parameter values according to other parameter value like following in stored procedure
DECLARE #secndvalues NCHAR(1);
IF (#firstvalue = 'Con')
BEGIN
SET #secndvalues = 'R';
END
ELSE IF (#firstvalue = 'Tin')
BEGIN
SET #secndvalues = 'N';
END
but it seems like it's not working with the second condition which is ELSE IF (#firstvalue = 'Tin'). How can I do this properly?
Your code should work, but a case seems simpler:
DECLARE #secndvalues NCHAR(1);
SET #secondvalues = (CASE WHEN #firstvalue = 'Con' THEN 'R'
WHEN #firstvalue = 'Tin' THEN 'N'
ELSE #secondvalues
END);
Actually problem was #firstvalue length too short keep its values, since that #firstvalue value getting null, therefor #secndvalues values can't setup , now problem sorted
In C#, you can have multiple conditionals of which only one will execute:
if (Condition1)
{
// Condition1 is true.
}
else if (Condition2)
{
// Condition1 is false and Condition2 is true.
}
else if (Condition3)
{
// Condition1 is false and Condition2 is false and Condition3 is true.
}
else
{
// Condition1, Condition2, and Condition3 are false.
}
But does the same logic work in T-SQL or must you nest the statements? Will this execute exactly like the above code?
IF #variable1 = 1
BEGIN
--#variable1 = 1
END
ELSE IF #variable1 = 2
BEGIN
--#variable1 = 2
END
ELSE IF #variable3 = 3
BEGIN
--#variable1 = 3
END
ELSE
BEGIN
--#variable1 > 3
END
I might be wrong here, but isn't there a way the SQL code would not evaluate the same way as the C# code from a logic standpoint if SQL doesn't allow multiple conditionals like C#? For example, is execution of each new ELSE IF guaranteed to be exclusive of the previous statements?
Yes, they are the same. Only one condition will be executed and the order of conditions is crucial.
LiveDemo
DECLARE #variable1 INT = 2
,#variable3 INT = 3;
IF #variable1 = 1
BEGIN
SELECT 'First IF'
END
ELSE IF #variable1 = 2
BEGIN
SELECT 'Second IF'
END
ELSE IF #variable3 = 3
BEGIN
SELECT 'Third IF'
END
ELSE
BEGIN
SELECT 'Else Clause'
END
In both the C# case as well as the SQL Server case, the ELSE keyword indicates that ONLY one block beneath an IF statement with a valid condition is going to be executed. Without ELSE, that's when the behavior changes. Your example is fine.