Select with NVL2 Not working Oracle - sql

I am selecting values from the database using Functions. I have three different functions in which if the first does not return anything I check for the second and third functions for values using NVL2. The problem is when I execute independent functions they return values but not in the NVL2 function My query is:
select NVL2(CRBP.FPDATE(LAM.ACID),
CRBP.FPDATE1(LAM.ACID),
CRBP.ODSANCDATE(GAM.ACID)) from
tbaadm.lam, TBAADM.GAM
where gam.acid = lam.acid
and gam.acid = 'VM12990'
This does not return any value.
But when I execute :
select CRBP.FPDATE (LAM.ACID) from tbaadm.lam where lam.acid = 'VM12990';
This Already returns a value. Shouldn't this be the value returned by my first query considering that it is the first in the check. What is the Problem with My first Query??

If CRBP.FPDATE returns a value the query should return the value returned by the function CRBP.FPDATE1 and if CRBP.FPDATE returns NULL then the query should return CRBP.ODSANCDATE's vlaue.
Does CRBP.FPDATE1 return anything?

NVL2(a,b,c) is a "if a is null then a else b" type function. so the value of a is never returned.
it sounds like you want COALESCE which will return the first not null value from the set of parameters

Related

Division by NULL in IBM DB2

In Oracle, any number divided by NULL returns NULL. I was wondering what is the case for DB2 Databases?
The whole point of it is to check whether the following expression behaves in the same way for Oracle and DB2:
SELECT a / NULLIF(b, 0) FROM some_table;
Say b=0, we would get a division by null.
The NULLIF function returns the null value if the two arguments are equal; otherwise, it returns the value of the first argument.
-NULLIF(expression,expression)-------------------------------
The result of using NULLIF(e1,e2) is the same as using the CASE expression:
CASE WHEN e1=e2 THEN NULL ELSE e1 END
Copy
When e1=e2 evaluates to unknown because one or both arguments is null, CASE expressions consider the evaluation not true. In this case, NULLIF returns the value
of the first argument.
IBM DB2 docs
So for DB2 and oracle it works same way
Db2 returns null when one of the operators in a math expression is null. For example
values (3 / cast(null as integer)) will return null.
On the other hand, the definition of NULLID is equal to that in Oracle. If both arguments are equal, it will return null.

msg 175, The isnull function requires 2 arguments(s)

After looking at similar issues I'm no wiser. What I have is a value returning that has two sets of numbers then a name i.e. (xxxx;xxxx;name). I'm trying to just return the name. The original code I've written (below) works if a name value/name is present.
SELECT
SUBSTRING(FIELD_VALUE,75, len (FIELD_VALUE))
FROM
[RWADMIN].[RV_ACTIVITY_FIELDS] P
JOIN
[RWADMIN].[RW_ASSOCIATION] A ON P.activity_ID = A.activityA_id
However it breaks the report if the value is blank as it returns a "NULL",
So I've thought this would work, but I get the above error.
SELECT
ISNULL(SUBSTRING(FIELD_VALUE,75, len (FIELD_VALUE)))
FROM
[RWADMIN].[RV_ACTIVITY_FIELDS] P
JOIN
[RWADMIN].[RW_ASSOCIATION] A ON P.activity_ID = A.activityA_id
Help please.
IsNull takes an expression and a value to replace the null values. It check the expression value, if it is null returns the value that we provided for nulls and if not just returns the expression value, so if you want to return a blank when it is null you should use it this way:
ISNULL(SUBSTRING(FIELD_VALUE,75, len (FIELD_VALUE)), '')

how to return the value of a scalar function in db2

I have a db2 function returning an integer. As per my limited knowledge the only way to see this function working is using to return column in a query like the example below.
Is there a way to display a return value of a function given a parameter withoyt building up a more complex query?
Example
I have a function
myfoo(index integer) returns integer ...
And I am using it in a more complex quewry like
select myIndex, myfoo(myIndex), myValue from MyTable...
If I try to get the following
select from myfoo(3)
it will not work.
Is there any db2 function to print out the return value of that function without error?
SELECT myfoo(3) FROM SYSIBM.SYSDUMMY1
SYSIBM.SYSDUMMY1 is a special "dummy" table that contains a single row, the equivalent of Oracle's DUAL.
If you have the compatibility vector, you can even use Oracle's Dual table. http://pic.dhe.ibm.com/infocenter/db2luw/v10r5/topic/com.ibm.db2.luw.apdv.porting.doc/doc/r0052874.html
Also, you can use the 'values' sentence. For example,
values myfoo(myIndex)

SQL Server : Computed Column DATEDIFF Clause

What I'm trying to do is the following: I have 3 columns (Control_OpenDate, Control_Record Age, Control_Stage2). Once the row is inserted it will populate Control_OpenDate (01/27/2013) and Control_RecordAge (computed column, see formula).
(datediff(day, [Control_OpenDate], getdate()))
which gives the days up to date.
Everything is working perfect but I want to add like an IF condition to the computed column whenever the column Control_Stage2 is populated if not, do not calculate or add a text...
How can I add the WHERE-statement in the above formula??
Note: I'm entering such formula directly into the column properties, I know there are queries that can do this but is there a way to do it trough a formula.
This can be done using a CASE-statement, as shown here.
Your logic will then look like:
(CASE
WHEN [Control_Stage2] IS NULL THEN NULL -- or -1 or what you like
ELSE datediff(day,[Control_OpenDate],getdate())
END)
This can also be written as a ternary statement (IIF)
IIF ( boolean_expression, true_value, false_value )
IIF is a shorthand way for writing a CASE expression. It evaluates the Boolean expression passed as the first argument, and then returns either of the other two arguments based on the result of the evaluation. That is, the true_value is returned if the Boolean expression is true, and the false_value is returned if the Boolean expression is false or unknown
E.G.
iif([Control_Stage2] is null, null, datediff(day,[Control_OpenDate],getdate()))

Problems with Postgresql CASE syntax

Here is my SQL query:
SELECT (CASE (elapsed_time_from_first_login IS NULL)
WHEN true THEN 0
ELSE elapsed_time_from_first_login END)
FROM (
SELECT (now()::ABSTIME::INT4 - min(AcctStartTime)::ABSTIME::INT4)
FROM radacct
WHERE UserName = 'test156') AS elapsed_time_from_first_login;
When I execute the above query, I get this error:
ERROR: CASE types record and integer cannot be matched
From the error message I understand that PostgreSQL take the second select, respectively elapsed_time_from_first_login as a row, even if it will always be a single value (because of the min() function).
Question: do you have some suggestions on how to deal with this query?
I suppose, what you are actually trying to do should look like this:
SELECT COALESCE((SELECT now() - min(acct_start_time)
FROM radacct
WHERE user_name = 'test156')
, interval '0s')
While there is an aggregate function in the top SELECT list of the subselect, it cannot return "no row". The aggregate function min() converts "no row" to NULL, and the simple form below also does the trick.
db<>fiddle here
Oldsqlfiddle
Other problems with your query have already been pointed out. But this is the much simpler solution. It returns an interval rather than an integer.
Convert to integer
Simplified with input from artaxerxe.
Simple form does the job without check for "no row":
SELECT COALESCE(EXTRACT(epoch FROM now() - min(acct_start_time))::int, 0)
FROM radacct
WHERE user_name = 'test156';
Details about EXTRACT(epoch FROM INTERVAL) in the manual.
Aggregate functions and NULL
If you had used the aggregate function count() instead of sum() as you had initially, the outcome would be different. count() is a special case among standard aggregate functions in that it never returns NULL. If no value (or row) is found, it returns 0 instead.
The manual on aggregate functions:
It should be noted that except for count, these functions return a
null value when no rows are selected. In particular, sum of no rows
returns null, not zero as one might expect, and array_agg returns
null rather than an empty array when there are no input rows. The
coalesce function can be used to substitute zero or an empty array for
null when necessary.
Postgres is complaining that 0 and elapsed_time_from_first_login are not the same type.
Try this (also simplifying your select):
select
coalesce(elapsed_time_from_first_login::INT4, 0)
from ...
Here is how I formatted the SQL and now is working:
SELECT coalesce(result, 0)
FROM (SELECT (now()::ABSTIME::INT4 - min(AcctStartTime)::ABSTIME::INT4) as result
FROM radacct WHERE UserName = 'test156') as elapsed_time_from_first_login;
The second SELECT is returning a table, named elapsed_time_from_first_login with one column and one row. You have to alias that column and use it in the CASE clause. You can't put a whole table (even if it is one column, one row only) where a value is expected.
SELECT (CASE (elapsed_time IS NULL)
WHEN true THEN 0
ELSE elapsed_time end)
FROM (SELECT (now()::ABSTIME::INT4 - min(AcctStartTime)::ABSTIME::INT4)
AS elapsed_time -- column alias
FROM radacct
WHERE UserName = 'test156'
) as elapsed_time_from_first_login; -- table alias
and you can shorten the CASE by using the COALESCE() function (and optionally add an alias for that column to be shown in the results):
SELECT COALESCE(elapsed_time, 0)
AS elapsed_time
FROM (SELECT (now()::ABSTIME::INT4 - min(AcctStartTime)::ABSTIME::INT4)
AS elapsed_time
FROM radacct
WHERE UserName = 'test156'
) as elapsed_time_from_first_login; -- table alias