NVL2 function does not exist? mysql query - mysql

I'm trying to do some queries but I keep getting errors, now I'm thinking that there is something wrong with the mysql installation. Can anybody tell me if there is an error in this query?
SELECT settings.ID,
settings.name,
settings.description,
NVL2(userSettings.value, userSettings.value, settings.default)
FROM settings
LEFT OUTER JOIN userSettings ON (settings.ID = userSettings.settingID)
The error I get says the function databaseX.NVL2 does not exist

I recommend staying away from vendor specific functions when a ANSI standard equivalent alternative is available. NVL and IFNULL for example can (often) be replaced with COALESCE.
You can also use CASE WHEN, which means a lot more typing on the downside, but the upside is that people with background in SQL Server for example won't have to deal with Oracles DECODE() or NVL or NVL2, because the logic is right there in the code.

That's probably because NVL2 is an Oracle function, not a MySQL function. I believe the function you are looking for in MySQL would be COALESCE()

As #Eric Petroelje mentioned NVL2() is Oracle function, not MySQL. However MySQL has its own equivalent that can be used in this case: IFNULL():
SELECT ... IFNULL(userSettings.value, settings.default) ...

After several try&error probes, I found this method to emulate Oracle's NVL2 function. It's not very elegant, but it works
SELECT IF(LENGTH(ISNULL(FieldName, '')) > 0, 'Not NULL Value', 'Null Value') FROM TableName

I think this can help you
IF(expr1,expr2,expr3)
If expr1 is TRUE (expr1 <> 0 and expr1 <> NULL) then IF() returns expr2; otherwise it returns expr3. IF() returns a numeric or string value, depending on the context in which it is used.

Alternatively you can substitute NVL2 to:
IF (userSettings.value IS NULL, userSettings.value, settings.default)

Related

Is MySQL's IF() broken?

MySQL (5.7.35) chokes with an error "Error Code: 3158. JSON documents may not contain NULL member names." on a query that can be simplified to look like
SELECT IF(false, JSON_OBJECTAGG(NULL, 'whatever'), 0) as x;
So I have to screen the NULL value to make it work:
SELECT IF(false, JSON_OBJECTAGG(IFNULL(NULL, 0), 'whatever'), 0) as x;
Which feels wrong as the expr2 in IF(false, expr2, expr3) is not supposed be even looked at by the engine, unless I'm missing something fundamental.
So my question is, why does MySQL's IF() evaluate/analyse expressions that are not meant to be executed?
Thanks
EDIT: to clarify, my actual code was
SELECT IF(cl.id IS NULL, NULL, JSON_OBJECTAGG(cl.id, cl.somethingelse))
Of cource it is supposed to be looked at and analysed for errors. What if someone else comes by later and sets the condition to true?
If nobody ever will, then you don't need a IF condition in the first place.

IFNULL() Equivalent in PostgreSQL

I am working on a project of migrating from MySQL to PostgreSQL, some function can't works well in PostgreSQL like IFNULL function. Some tutorials say that in PostgreSQL we can use NULLIF to handle it.
When I try I get an issue "argument of NOT must be type boolean, not type integer".
This is the simple SQL :
SELECT * FROM `tableA` WHERE not(nullif(columnA, 0));
How to solve it? Maybe some one can make an explain how can it works well. Thanks
NULLIF() is very different from IFNULL(). I think that what you want is COALESCE(), which will return the first non-NULL argument (it can have more than 2 arguments):
SELECT *
FROM table_a
WHERE NOT (COALESCE(column_a::boolean, false));
Reference: 9.17.2. COALESCE
Also, in Postgres you need to use true or false. 0 and 1 do not work for boolean literals. That's the reason that you get the error:
argument of NOT must be type boolean, not type integer
If column_a is an integer, then you have to CAST it to boolean. That's what column_a::boolean in the example above does. It is equivalent to CAST(column_a AS boolean).

case statement in MS Access query give error

I am using below query in Ms Access. And this gives me error Syntax error in your query expression CASE WHEN not ... . Can you please tell me what I am doing wrong? In Sql Server 2008 R2, the case statement runs correctly.
SELECT TableApron.RadButtonNo, TableApron.ShortName, QueryForNot1.InspectionDate, QueryForNot1.Findings, QueryForNot1.Status, QueryForNot1.Initials, TableApron.DeptName, TableApron.Lost, TableApron.InServelDate, TableApron.RemovedDate, TableApron.PrivateUserName, TableApron.PrivateUserEmail, TableApron.ApronType, TableApron.Manufacturer
FROM TableApron LEFT JOIN QueryForNot1 ON TableApron.RadButtonNo=QueryForNot1.RadButtonNoI
WHERE (((TableApron.Lost)="N" Or (TableApron.Lost)=[#Lost]) And ((TableApron.InServelDate) Is Null Or (TableApron.InServelDate) Between CDATE([#From]) And CDATE([#To]) Or (TableApron.InServelDate)<CDATE([#To])) And ((TableApron.RemovedDate) Is Null Or (TableApron.RemovedDate) Between CDATE([#From]) And CDATE([#To]) Or (TableApron.RemovedDate)>CDATE([#To])))
ORDER BY
CASE
WHEN not TableApron.RadButtonNo like '%[^0-9]%' THEN CONVERT(int,TableApron.RadButtonNo)
WHEN TableApron.RadButtonNo like '[0-9]%' THEN CONVERT(int,SUBSTRING(TableApron.RadButtonNo,1,PATINDEX('%[A-Z]%',TableApron.RadButtonNo)-1))
END,
CASE
WHEN not TableApron.RadButtonNo like '%[^0-9]%' THEN NULL
WHEN TableApron.RadButtonNo like '[0-9]%' THEN SUBSTRING(TableApron.RadButtonNo,PATINDEX('%[A-Z]%',TableApron.RadButtonNo),9000)
ELSE TableApron.RadButtonNo
END;
The CASE statement triggers the first reported error because it is not supported in Access SQL. Use IIf() instead as #Gustav suggested.
However then you will encounter additional errors because CONVERT, SUBSTRING, and PATINDEX are also not supported in Access SQL.
Instead of CONVERT, use CInt() to cast a value to Access Integer or CLng() for Long Integer. Or you could use Val() and let Access decide which numeric datatype to give you.
Instead of SUBSTRING, use Mid().
Instead of PATINDEX, use InStr().
Assuming those suggestions eliminate the syntax errors, you may still have an issue with the Like wildcard.
If you will be running the query from the query designer or elsewhere under DAO, Access expects * instead of % as the wildcard. % is the correct wild card only when the query is run from ADO/OleDb.

Is it better to use "<>" or "!=" for not equals in MySQL?

I remember someone told me to use <> rather than != but I forgot the reason why. I cannot find the answer on Google. Just want to know if they're just the same comparison operator or not because we're on refactoring stage of our MySQL codes now.
<> is an ANSI SQL compatible operator, whereas != is not.
So presumably you must use the former, since the latter is just a mysql's sql extension.
References:
http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt
<not equals operator> ::= <>

Dynamic Values in 'IN' operator

I have a select statement in which the WHERE clause's IN operator. The query works properly as long as some values are passed to question mark (passed from java program). But when there are no values passed, I get a syntax error.
select
this_.categoryAddressMapId as category1_1_0_,
this_.categoryId as categoryId1_0_,
this_.addressId as addressId1_0_
from
icapcheckmyphotos.category_address_map this_ <br>
where
this_.addressId in (
?
)
When there are no parameters passed, I need null set. Please suggest how to modify the where clause. Thanks in advance
Modify your java program. Your choices are to not run the query if there are no addressIds, or ensure that it passes at least one value. If addressId is an integer field, pass -1 or something like that. Personally, I like the first option but it depends on your requirements.
how about doing sometiong like
where (? is null) OR this_.addressId in ( ? )
you may need to add some special treatment to the first part of the OR if your columns does accept NULLS
//pseudo code
...
WHERE 1
if(!null) {
AND this_.addressId in ('stuff')
}