How to do a JSON_MERGE_PATCH with Knex.js (MySQL)? - mysql

Newer MySQL versions (as well as SQLite and other databases supported by Knex.js) offer a great way to partially update JSON columns: JSON_MERGE_PATCH (aka JSON_PATCH in SQLite). As far as I can tell, Knex.js doesn't offer this functionality. One could use it with the raw() function in Knex.js, but I don't see how we could use it without having to write the whole SQL query from scratch.
How would you use Knex.js to perform a JSON_MERGE_PATCH in a same .update() statement that updates other non-JSON columns as well?

Found this workaround:
knex(table)
.where('id',id)
.update({
textColumn: textColumnUpdatedString,
// ... other columns
jsonColumn: knex.raw('JSON_MERGE_PATCH(??,?)',['jsonColumn', JSON.stringify(jsonUpdateObject)]) }
})

Related

Knex : universal way to get the last inserted id

I'm using Knex, because I'm working on an application that I would like to use with multiple database servers, currently Sqlite3, Postgres and MySQL.
I'm realizing that this might be more difficult that I expected.
On MySQL, it appears that this syntax will return an array with an id:
knex('table').insert({ field: 'value'}, 'id');
On postgres I need something like this:
knex('table').insert({ field: 'value'}, 'id').returning(['id']);
In each case, the structure they return is different. The latter doesn't break MySQL, but on SQlite it will throw a fatal error.
The concept of 'insert a record, get an id' seems to exist everywhere though. What am I missing in Knex that lets me write this once and use everywhere?
Way back in 2007, I implemented the database access class for a PHP framework. It was to support MySQL, PostgreSQL, SQLite, Microsoft SQL Server, Oracle, and IBM DB2.
When it came time to support auto-incremented columns, I discovered that all of these implement that feature differently. Some have SERIAL, some have AUTO-INCREMENT (or AUTOINCREMENT), some have SEQUENCE, some have GENERATED, some support multiple solutions.
The solution was to not try to write one implementation that worked with all of them. I wrote classes using the Adapter Pattern, one for each brand of SQL database, so I could implement each adapter class tailored to the features supported by the respective database. The adapter satisfied an interface that I defined in my framework, to allow the primary key column to be defined and the last inserted id to be fetched in a consistent manner. But the internal implementation varied.
This was the only sane way to develop that code, in my opinion. When it comes to variations of SQL implementations, it's a fallacy that one can develop "portable" code that works on multiple brands.

How do I convert RDBMS DDL to Hive DDL script

We've a large and disparate data sources including oracle,db2,mysql. We also need to append few audit columns at the end.
I came across the following Java class org.apache.sqoop.hive.HiveTypes. I am planning to create a simple interpreter that accepts RDBMS DDL and spits out Hive DDL script. Any pointers on how I can achieve this?
Hive QL is more or less similar to normal RDBMS DDL. But there are certain things that it lacks and thats why it does not fully follow ANSI SQL. There is no automated process to convert it.
But you have to try running the SQL queries on Hive and wherever it violates you have to change the query according to hive.
For instance Hive takes only equality condition as join condition which is not the case in RDBMS.
For creating an interpreter yourself you first have to list down the common differences between RDBMS query construct and Hive QL construct. Whenever you encounter a RDBMS construct which according to your list will violate in hive the query gets rebuild as per hive. This replacement logic has to be coded.

UPSERT compatible with mySql and postgreSQL

I've been googling and trying different queries but I haven't managed to get the UPSERT query to work with both mySql and postgreSql. Does anyone here know how to do it?
There is not one, and cannot be one. PostgreSQL doesn't have an UPSERT statement. The new 9.5 statement INSERT ... ON CONFLICT UPDATE ... is syntactically different from MySQL's INSERT ... ON DUPLICATE KEY UPDATE ... because it's also semantically different, i.e. it works differently.
The newer PostgreSQL statement, added in 9.5, was designed with an awareness of MySQL's syntax. The decision not to use the same syntax was intentional because MySQL's statement has big ambiguities around handling of multiple unique indexes etc, where it basically shrugs and says "dunno".
You can possibly hide it behind stored functions, but really, this is why your application should be able to run different SQL on a different DBMS. Trying to always write one statement that works for all target DBMSes is a lost cause even if you're just targeting MySQL and PostgreSQL.

Function Similar with to_char(datetime) that can be used both Oracle and MySQL?

Function Similar with to_char(datetime) that can be used both Oracle and MySQL?
I want to generate the ANSI SQL script to run both in oracle and in MySQL.
But, the generated ANSI SQL is working well. except the the error from to_char().
Is there any function that can be used in both db?
Date formatting abilities couldn't be more different. I think your best chance is to pick one of these:
Run an ALTER SESSION statement when you connect to Oracle to replicate the MySQL default date format and do all date formatting in your client app.
Write a custom wrapper function and use it in your queries. You have to fork function code and maintain two versions.
You still have DBMS-dependent code but it's isolated in your initialisation code (option #1) or your installation script (option #2).
Perhaps there's a third option: tweak your database abstraction library to detect column types in result sets and convert dates to custom objects (e.g., DateTime if you use PHP, Date if you use JavaScript, etc.).
Mysql and Oracle uses different syntax for converting date to string.
You should use different queries.

Oracle to PostgreSQL query converter Possible?

I am thinking to write a converter that takes any oracle query and return Postgresql format of the query assuming table and columns are same.
what I do right now I do timely conversions so I have basic understanding about both and want some expert advice that is it easily possible or not?
Try to use "commercial" version of PostgreSQL - EnterpriseDB. It has an compatibility layer for Oracle.
If you're about to write the "convector" by your own: look at this github project: https://github.com/porcelli/plsql-parser. It's open-source parser for Oracle's SQL dialect. I have to warn you, even if you have AST for Oracle query it is still a lot of to do to convert AST into other SQL dialect. You will also need plenty of sample queries for testing. You can find some sample queries in this project's tests folder.
Also similar project was implemented for MySQL, but I can not find it's homepage now.
Part of the solution is to make available in PostgreSQL the functions available in Oracle. You can have a look at http://orafce.projects.pgfoundry.org/
"The goal of this project is to implemente some functions from Oracle database. Some date functions (next_day, last_day, trunc, round, ...), string functions and some modules (DBMS_ALERT, DBMS_OUTPUT, UTL_FILE, DBMS_PIPE, ...) are implemented now. Funcionality was verified on Oracle 10g and module is useful for production work."
Not possible for every query. They each have syntax and functionality that the other does not -- for example, the MODEL clause in Oracle, or PostgreSQL's special form of "SELECT DISTINCT ON".
Mostly, Oracle has functionality that PostgreSQL doesn't: http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_10002.htm