MySQ: IF() function in JOOQ - mysql

I see JOOQ doesn't support MySQL's IF Function, But I find iif() in DSL.java, it's SQL Sever style, I used it in MySQL, it works well, so can I use iff() in My MySQL query?
It's my test code
dslContext.select(EMPLOYEE.EMPLOYEE_ID,
DSL.iif(EMPLOYEE.ALGO.eq(1), EMPLOYEE.FULLNAME, EMPLOYEE.ACCOUNT).as("fullname"))
.from(EMPLOYEE)
.where(EMPLOYEE.EMPLOYEE_ID.eq(100)).fetchOneInto(Employee.class);

jOOQ 3.14 will add native support for MySQL's IF() via #10160. This isn't really a necessary feature, it's mere convenience compared to writing the equivalent CASE expression:
-- MySQL
IF (C, A, B)
-- Standard SQL
CASE WHEN C THEN A ELSE B END
If you prefer IF(), you can always write your own plain SQL template even before jOOQ 3.14

Related

How do I express the MySql function `GROUP_CONCAT(DISTINCT column)` in Arel?

I can use
Arel::Nodes::NamedFunction.new('GROUP_CONCAT', [an_arel_table[:a_column]])
to generate
GROUP_CONCAT(a_column)
in my SELECT statement. But how do I add the DISTINCT option?
Arel::Nodes::NamedFunction.new('GROUP_CONCAT', ['DISTINCT', an_arel_table[:a_column]])
yields
GROUP_CONCAT(DISTINCT, a_column)
which is a syntax error.
It's a bit of a hack, but the following works.
Arel::Nodes::InfixOperation provides a mechanism for generating a sequence X DISTINCT Y. By setting X to blank (Arel::Nodes::SqlLiteral.new('')), we end up with DISTINCT Y.
Arel::Nodes::NamedFunction.new('GROUP_CONCAT', [
Arel::Nodes::InfixOperation.new('DISTINCT',
Arel::Nodes::SqlLiteral.new(''),
an_arel_table[:a_column]])])
Later versions of Arel (beyond Rails 4.2) support UnaryOperation which may allow expressing the DISTINCT modifier as Arel::Nodes::UnaryOperation.new('DISTINCT', an_arel_table[:a_column]). (UNTESTED)

how to use find_in_set of mySQL in SYBASE?

Before, I use find_in_set(idField,:ids) in mySQL to delete or update multi field with ids separated by comma, example:
UPDATE USER SET name = 'a' WHERE find_in_set(id,'1,2,3,4') > 0
How do I can customize the query and use it in SyBase ?
NOTE: You haven't mentioned which Sybase database product you're using (ASE? SQLAnywhere? IQ? Advantage?), nor the version. While ASE does not have anything like find_in_set(), I can't speak for the other database products.
From an ASE perspective you have a few options:
create your own user-defined function; you have T-SQL (since ASE 15.0.2) and Java options
build a dynamic query and submit via execute()
rewrite your query to use available ASE functions (eg, patindex(), charindex())
rewrite your query to use the like operator (see alternate to find_in_set() for non-MySQL databases for an example)
As Sybase does not have function like find_in_set, you have couple of options: google a function which parses the comma separated list to a temp table or use dynamic SQL with execute-command.

How to use Postgres JSON operators in a WHERE condition with jOOQ?

I have a JSONB column which holds arrays of strings, eg: ["foo", "bar"]
I want to write the jOOQ equivalent of:
SELECT * FROM sometable WHERE somecolumn ?| <mylist>
...where should be bound to a java List of string tag names.
There doesn't appear to be any direct support for ?| in jOOQ 3.8. I have looked at binding to raw sql in a condition but I'm not quite sure the syntax; it gets even worse if trying to use the ? postgres operator which conflicts with the binding expression.
UPDATE: the stacktrace with 3.8.3
I stripped this down to a minimal test. When adding a condition like this using jOOQ 3.8.3:
query.addConditions(DSL.condition("sometable.tags ?| array['sometag']"));
Produces a stacktrace like this:
Caused by: org.postgresql.util.PSQLException: No value specified for parameter 1.
at org.postgresql.core.v3.SimpleParameterList.checkAllParametersSet(SimpleParameterList.java:228)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:163)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:622)
at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:472)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:465)
at org.jooq.tools.jdbc.DefaultPreparedStatement.execute(DefaultPreparedStatement.java:194)
at org.jooq.impl.AbstractResultQuery.execute(AbstractResultQuery.java:269)
at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:348)
... 36 more
An issue related to jOOQ parsing ?| and similar operators as bind variables has been addressed in jOOQ 3.8.3: https://github.com/jOOQ/jOOQ/issues/5307
JDBC limitation
Note, in addition to the above, there is also a JDBC limitation that I have documented in a separate question. In jOOQ, you can work around this JDBC limitation by specifying:
Settings settings = new Settings().withStatementType(StatementType.STATIC_STATEMENT);
See also: http://www.jooq.org/doc/latest/manual/sql-execution/statement-type
Or, alternatively, by falling back to using the jsonb_exists_any() function instead of the ?| operator.

Equivalent of oracle function DBMS_LOB.SUBSTRING in MYSQL

Is there any equivalent for the Oracle DBMS function DBMS_LOB.SUBSTRING on Mysql?
if not how can I get the text of BLOB in MYSQL server? (I only need to use SQL no other programming languages)
Please try dbms_lob.substr which is equivalent to DBMS_LOB.SUBSTRING
Get the Oracle value passed to dbms_lob.substr and prefix the value with 0x without quotes for the MySQL insert statement.
I did tried for my case and succeeded.

NVL2 function does not exist? mysql query

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)