Opensips avp_db_query can't compare null value - database

I am using avp_db_query to retrieve my table row, sometimes one field value is null. But when I use if condition it does not follow and move on.
avp_db_query("select status from orders where id = 1", "$avp(status);")
Now if i write condition
if($avp(status)==1){
do success
} else {
do failure
exit();
}
Above condition does not work on failure status and continue, but when I put two if conditions and check if it is equal to one or equal to 0 then it works.
another issue is if this column has null value than nothing work, and it proceeds with giving the following warning.
WARNING:core:comp_scriptvar: invalid EQUAL operation: left is
VARIABLE_ELEMENT/STRING_VAL, right is NUMBER/NO_VAL

You can test for NULL SQL column values with:
if ($avp(status) == "<null>")
... which is equivalent to:
if ($(avp(status)[0]) == "<null>")
It was the only way we could get this to work, given that the $avp(status) = NULL; statement is meant to delete the top-most value in the AVP's stack.
If you are claiming that the else statement is not executed when it should be, please give a minimally viable example, along with the output of opensips -V, possibly opening up a new issue, separately.

Related

Apply If condition in solr fieldlist

I need a variable value, which will compute the value on the basis of condition I have used.
I need to apply if condition and in case that condition exists I need to return the value as 1 else 0
My logic is:
{!field f=temp_close_timing v='[2022-03-11T11:14:39.667679 TO 2022-03-11T11:14:39.667679]'}
If we get the value from the above statement, we need to return true else return false.
I am not sure how to do this. I have tried exists condition here but I am not sure how to right the same in FL
eg:
fl=if((exists({!field f=temp_close_timing v='[2022-03-11T11:14:39.667679 TO 2022-03-11T11:14:39.667679]'}),1,0),1,0)
but here I am getting error as "Error parsing fieldname: Expected identifier at pos 3 str="
I am not sure how to assign variable and if I assign variable that should be indexed separately.

My program crashes when I try to read a NULL value using sqlite in C

I have tried to use the below statement to check if the value present in the given fieldname for a record is NULL or not, if it is NULL then put 0 else return the value present in the fieldname.
It shows syntax error.
SELECT [structname.fieldname], isnull([structname.fieldname],0) FROM tablename WHERE condition;
Can you please let me know where am I going wrong?
I have also tried the below statement
SELECT [structname.fieldname], CASE WHEN [structname.fieldname] IS NULL THEN 0 ELSE [structname.fieldname] END FROM tablename WHERE condition;
For the above statement, the program crashes when it encounters a NULL value. Can you please tell me how else can I check if a value of a particular record is NULL or not and then read the value if it is not NULL else read it as 0
You are not using correctly the square brackets.
The column names should be written like:
[structname].[fieldname]
assuming that [structname] is the name or the alias of the table where fieldname comes from, and not like:
[structname.fieldname]
which would be ok only if the column's name is actually structname.fieldname.
What you need can be done with the function COALESCE():
SELECT COALESCE([fieldname], 0) FROM tablename

Invalid length parameter passed to the substring function case

I have an issue with substring function while using it inside case statement.
select
case when -1<0 then 'ok' else SUBSTRING('abcd',1,-1) end
gives me an issue:
Invalid length parameter passed to the substring function.
Why is the case "looking" at the else condition since the first condition is met?
On the other hand query:
declare #a int;
set #a=-1
select
#a,
case when #a<0 then 'ok' else SUBSTRING('abcd',1,#a) end
presents the right answer 'ok' without any errors.
The problem is that the literal value of -1 is parsed by the compiler before run-time for the length parameter. The compiler knows that -1 is invalid, as length must have a positive value, so the error is flagged before the SQL is even run.
In the latter statement, the length passed is a variable. At compile time, the variable has an "unknown" value, as it's not SET till run time, thus the syntax is fine.
Simply put, the compiler knows that a length of -1 for SUBSTRINGis invalid, regardless of if that SQL will actually run, and so errors.
Unlike other functions, such as STUFF and REPLICATE, which state "If length is negative, a null string is returned.", SUBSTRING, LEFT, and RIGHT all state: "If integer_expression is negative, an error is returned." For a literal value, it appears that the compiler is checking these values, even if they will never be used, and then flagging the error.
This isn't limited to logic within a CASE either. For example, the using logical flow operators such as IF generates the same behaviour:
IF 1 = 0
SELECT LEFT('abc',-1)
As does the ISNULL function:
SELECT ISNULL('ok',RIGHT('abc',-1));
It only, however, occurs with literal values. If, for example, you were to use the values from a column, the behaviour is not seen:
IF 1 = 0
SELECT SUBSTRING('abc',1,n) FROM (VALUES(1),(-1)) V(n);
This does not return an error, even though everything in VALUES is a literal. That is because the value of n has not been evaluated.
You can try this as it needed positive end values as length can not be in negative but can be 0.
select
case when -1 < 0 then 'ok' else SUBSTRING('abcd',1, 1) end

What does two return statements inside an SQL function mean?

What code path is actually being returned from this a Scalar function that returns a decimal:
DECLARE #SafetyStockUnitsCalcNew decimal(14,2)
RETURN( SELECT STDEV(
.
.
-- Calculating code here.
)
-- Return the result of the function
RETURN #SafetyStockUnitsCalcNew
END
So what gets returned?
Is it the first return scaler statement or the second scaler one?
Also, once #SafetyStockUnitsCalcNew is declared it is never used until it is returned. Where is it set?
The code inside STDEV does not reference #SafetyStockUnitsCalcNew at all.
A function can have as many RETURN statements as you want.
E.g. Below there are three.
When the flow of control encounters a return statement then execution of the function stops and the value is returned.
CREATE FUNCTION dbo.Foo(#x int)
RETURNS INT
AS
BEGIN
IF #x = 1
RETURN 10;
ELSE
RETURN 18;
RETURN 1/0;
END
SQL Server does not do anything like the same level of analysis as happens in C# to detect that all code paths return a value and warn you of unreachable code. It just insists that the last statement must be a return.
In the above example the third RETURN statement can never be reached but nonetheless without it you would see an error "The last statement included within a function must be a return statement.".
In your example the second RETURN statement can never be reached and it is not required for the "last statement" rule either so it is useless. Perhaps originally the SELECT assigned the result to the variable and then the person coding it realised that they could just return the SELECT result directly.
I'd go on to a test server, create the function and comment out that second RETURN and see what happens. I'm 99% sure that it is never executing.

Is SQL Server's double checking needed here?

IF #insertedValue IS NOT NULL AND #insertedValue > 0
This logic is in a trigger.
The value comes from a deleted or inserted row (doesn't matter).
2 questions :
Do I need to check both conditions? (I want all value > 0, value in db can be nullable)
Does SQL Server check the expression in the order I wrote it ?
1) Actually, no, since if the #insertedValue is NULL, the expression #insertedValue > 0 will evaulate to false. (Actually, as Martin Smith points out in his comment, it will evaluate to a special value "unknown", which when forced to a Boolean result on its own collapses to false - examples: unknown AND true = unknown which is forced to false, unknown OR true = true.) But you're relying on comparison behaviour with NULL values. A single step equivalent method, BTW, would be:
IF ISNULL(#insertedValue, 0) > 0
IMHO, you're better sticking with the explicit NULL check for clarity if nothing else.
2) Since the query will be optimised before execution, there is absolutely no guarantee of order of execution or short circuiting of the AND operator.
Combining the two - if the double check is truly unnecessary, then it will probably be optimised out before execution anyway, but your SQL code will be more maintainable in my view if you make this explicit.
You can use COALESCE => Returns the first nonnull expression among its arguments.
Now you can make the query more flexible, by increasing the column limits and again you need to check the Greater Then Zero condition. Important point to note down here is you have the option to check values in multiple columns.
declare #val int
set #val = COALESCE( null, 1, 10 )
if(#val>0)
select 'fine'
else
select 'not fine'

Resources