Nodejs Mysql Insert is adding backslashes to strings and fails - sql

I'm trying to do a simple sql insert using nodejs and express trying various formats I've found online, but this appears to be the accepted way. When I view the error it's adding extra backslashes to the query and failing.
The code:
console.log(request.body);
var post = {uid: request.session.uid, title: request.body.title, created: request.body.createdAt};
connection.query('INSERT INTO projects (uid, title, created) SET ? ', post, function (error, results, fields) {
console.log(error);
});
The first body console.log:
{ title: 'aewgawegr', createdAt: '1574219119301' }
The error message:
sqlMessage:
'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near \'SET `uid` = 1, `title` = \'aewgawegr\', `created` = \'1574219119301\'\' at line 1',
sqlState: '42000',
index: 0,
sql:
'INSERT INTO projects (uid, title, created) SET `uid` = 1, `title` = \'aewgawegr\', `created` = \'1574219119301\' ' }

For reference: https://dev.mysql.com/doc/refman/8.0/en/insert.html
You cannot combine the two usage syntax:
INSERt INTO `table` (column1, ...) VALUES (value1, ...
with
INSERT INTO `table` SET `column1`='value1', ....

You can do something like this instead of passing json object
"INSERT INTO projects (uid, title, created) VALUES (1, 'Michelle', 'Blue Village 1')";
e.g in your case you can use string interpolation:
`INSERT INTO projects (uid, title, created) VALUES ('${request.session.uid}', '${request.body.title}', '${request.body.createdAt}')`;

Related

{ scientistSeedError: 'syntax error at or near "["' }

I am trying to add some data to a table in postgresql through a seed file I've created. all the routes work and I already created another table. However, on this particular table I'm trying to add an array in one of the columns, but I keep getting this error. Does anyone has an idea of what it could be? or how can I inform a postgresql table I want to add some arrays:
```{ scientistSeedError: 'syntax error at or near "["' }````
below is the query to create the table
const query =
CREATE TABLE "scientist" (
"id" serial NOT NULL,
"first_name" varchar(255) NOT NULL,
"last_name" varchar(255) NOT NULL,
"area_expertise" varchar(255) NOT NULL,
"areaExpertise" TEXT ARRAY NOT NULL,
"field" TEXT ARRAY NOT NULL,
"wiki_link" varchar(255) NOT NULL,
"picture" varchar(255) NOT NULL,
"short_description" varchar(400),
CONSTRAINT "scientist_pk" PRIMARY KEY ("id")
) WITH (
OIDS=FALSE
);`
;
try {
await db.query(query);
res.send("Database successfully created");
} catch(e){
console.log(e.message)
}
};```
**and below a fragment of the query to add the data. As is too large to post here but**
```module.exports.seedPart2 = async (req, res, next) => {
// Scientist query
const scientistsQuery = `
INSERT INTO scientist (first_name,
last_name,
area_expertise,
field,
issue_tackled,
wiki_link,
picture) VALUES
('Eugenie', 'Clark', 'Ichthyologist', 'biology', 'Environmental preservation', 'https://en.wikipedia.org/wiki/Eugenie_Clark', 'http://www.alertdiver.com/cdn/13649.jpg'),
('Susan', 'Solomon', 'Atmospheric Chemist', 'Chemistry', ['Environmental preservation', 'Chemistry'], 'https://en.wikipedia.org/wiki/Susan_Solomon' , 'https://upload.wikimedia.org/wikipedia/commons/thumb/8/80/Susan_Solomon-Desk_With_Globe.jpg/1024px-Susan_Solomon-Desk_With_Globe.jpg'),
('Donna Theo', 'Strickland', 'Physics, Optics, and Lasers', 'Physics', ['Medicine', 'New technologies'], 'https://en.wikipedia.org/wiki/Donna_Strickland', 'https://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Donna_Strickland_EM1B5760_%2846183560632%29_%28cropped%29.jpg/220px-Donna_Strickland_EM1B5760_%2846183560632%29_%28cropped%29.jpg'),
('Linda', 'Brown Buck', 'Biologist', 'Biology', 'Medicine', 'https://en.wikipedia.org/wiki/Linda_B._Buck', 'https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Linda_Buck_2015_%28cropped%29.jpg/200px-Linda_Buck_2015_%28cropped%29.jpg')`;
try {
const {rows} = await db.query(scientistsQuery);
res.status(201).json(rows)
} catch (e) {
console.log({ scientistSeedError: e.message });
}
};
Thank you for any help!!!
Array literals in PosgreSQL are denoted by curly braces, not square braces (see the documentation for details):
const scientistsQuery = `
INSERT INTO scientist (first_name,
last_name,
area_expertise,
field,
issue_tackled,
wiki_link,
picture) VALUES
('Eugenie', 'Clark', 'Ichthyologist', 'biology', 'Environmental preservation', 'https://en.wikipedia.org/wiki/Eugenie_Clark', 'http://www.alertdiver.com/cdn/13649.jpg'),
('Susan', 'Solomon', 'Atmospheric Chemist', 'Chemistry', '{"Environmental preservation", "Chemistry"}', 'https://en.wikipedia.org/wiki/Susan_Solomon' , 'https://upload.wikimedia.org/wikipedia/commons/thumb/8/80/Susan_Solomon-Desk_With_Globe.jpg/1024px-Susan_Solomon-Desk_With_Globe.jpg'),
('Donna Theo', 'Strickland', 'Physics, Optics, and Lasers', 'Physics', '{"Medicine", "New technologies"}', 'https://en.wikipedia.org/wiki/Donna_Strickland', 'https://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Donna_Strickland_EM1B5760_%2846183560632%29_%28cropped%29.jpg/220px-Donna_Strickland_EM1B5760_%2846183560632%29_%28cropped%29.jpg'),
('Linda', 'Brown Buck', 'Biologist', 'Biology', 'Medicine', 'https://en.wikipedia.org/wiki/Linda_B._Buck', 'https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Linda_Buck_2015_%28cropped%29.jpg/200px-Linda_Buck_2015_%28cropped%29.jpg')`;

Spring Boot Autoimport import.sql file - Getting a "Column Not found" Error

So I have a table in postgresql and I want to fill it with some values on application start. Here is the Entity (in Kotlin):
#Entity
class CalculationType(
#Id #GeneratedValue(strategy = GenerationType.AUTO)
var id: Long = 0,
var guid: String = "",
var title: String = "",
var modified: Date,
var creation: Date
)
my import.sqlfile is located under ..\.\resources. it looks like this:
insert into calculation_type (guid, title, modified, creation) VALUES ("test", "title", "2013-12-12", "2013-12-12");
I am getting an error in German, traslated it says Column »test« does not exist.
Thats quite strange because test is in my values, not in my column definitions.
Does anyone know whats going on?
Character constants need single quotes
insert into calculation_type (guid, title, modified, creation) VALUES ('test", 'title', '2013-12-12', '2013-12-12');

Laravel DB::update don't working, doing nothing at all, without any errors

I am learning how to run raw SQL queries and stuck at UPDATE operation.
I have route for INSERT:
Route::get('/insert', function (){
DB::insert('insert into posts (title, content) values (?, ?)', ['PHP with Laravel', 'Just testing']);
return 'after insert';
});
And route for SELECT:
Route::get('/read', function (){
$results = DB::select('select * from posts');
return var_dump($results);
});
After SELECT query I see:
/home/pavel/www_mysite/TestLaravel/routes/web.php:31:
array (size=1)
0 =>
object(stdClass)[239]
public 'id' => int 11
public 'title' => string 'PHP with Laravel' (length=16)
public 'content' => string 'Just testing' (length=12)
public 'created_at' => null
public 'updated_at' => null
public 'is_admin' => int 0
And at least UPDATE query:
Route::get('/update', function (){
DB::update('update posts set title = "Nothing here"');
});
After that query the new SELECT query shows the same data and in PHPPgAdmin I found no changes. I installed LaravelDebugBar and may see it at the bottom of the browser at pages for INSERT and SELECT queries, but don't see it at the page for UPDATE query. I cannot realize, where is the mistake.
try to use where clause.
example :
$affected = DB::update('update users set votes = 100 where name = ?', ['John']);
I tested you code too and it work
see this picture
I run your update code on my local environment (laravel 5.2, mysql 5.1). It's updated OK.
How about your log?
After some extra research I found that PostrgreSQL may store case-sensitive names of tables and columns. For that case you need to take their names in double quotes in your query. I think that when PostrgreSQL found double quotes in the query - it "thinks" that it is table/column name. But there is no column with those name.

Upsert in KnexJS

I have an upsert query in PostgreSQL like:
INSERT INTO table
(id, name)
values
(1, 'Gabbar')
ON CONFLICT (id) DO UPDATE SET
name = 'Gabbar'
WHERE
table.id = 1
I need to use knex to this upsert query. How to go about this?
So I solved this using the following suggestion from Dotnil's answer on Knex Issues Page:
var data = {id: 1, name: 'Gabbar'};
var insert = knex('table').insert(data);
var dataClone = {id: 1, name: 'Gabbar'};
delete dataClone.id;
var update = knex('table').update(dataClone).whereRaw('table.id = ' + data.id);
var query = `${ insert.toString() } ON CONFLICT (id) DO UPDATE SET ${ update.toString().replace(/^update\s.*\sset\s/i, '') }`;
return knex.raw(query)
.then(function(dbRes){
// stuff
});
Hope this helps someone.
As of knex#v0.21.10+ a new method onConflict was introduced.
Official documentation says:
Implemented for the PostgreSQL, MySQL, and SQLite databases. A
modifier for insert queries that specifies alternative behaviour in
the case of a conflict. A conflict occurs when a table has a PRIMARY
KEY or a UNIQUE index on a column (or a composite index on a set of
columns) and a row being inserted has the same value as a row which
already exists in the table in those column(s). The default behaviour
in case of conflict is to raise an error and abort the query. Using
this method you can change this behaviour to either silently ignore
the error by using .onConflict().ignore() or to update the existing
row with new data (perform an "UPSERT") by using
.onConflict().merge().
So in your case, the implementation would be:
knex('table')
.insert({
id: id,
name: name
})
.onConflict('id')
.merge()
I've created a function for doing this and described it on the knex github issues page (along with some of the gotchas for dealing with composite unique indices).
const upsert = (params) => {
const {table, object, constraint} = params;
const insert = knex(table).insert(object);
const update = knex.queryBuilder().update(object);
return knex.raw(`? ON CONFLICT ${constraint} DO ? returning *`, [insert, update]).get('rows').get(0);
};
Example usage:
const objToUpsert = {a:1, b:2, c:3}
upsert({
table: 'test',
object: objToUpsert,
constraint: '(a, b)',
})
A note about composite nullable indices
If you have a composite index (a,b) and b is nullable, then values (1, NULL) and (1, NULL) are considered mutually unique by Postgres (I don't get it either).
Yet another approach I could think of!
exports.upsert = (t, tableName, columnsToRetain, conflictOn) => {
const insert = knex(tableName)
.insert(t)
.toString();
const update = knex(tableName)
.update(t)
.toString();
const keepValues = columnsToRetain.map((c) => `"${c}"=${tableName}."${c}"`).join(',');
const conflictColumns = conflictOn.map((c) => `"${c.toString()}"`).join(',');
let insertOrUpdateQuery = `${insert} ON CONFLICT( ${conflictColumns}) DO ${update}`;
insertOrUpdateQuery = keepValues ? `${insertOrUpdateQuery}, ${keepValues}` : insertOrUpdateQuery;
insertOrUpdateQuery = insertOrUpdateQuery.replace(`update "${tableName}"`, 'update');
insertOrUpdateQuery = insertOrUpdateQuery.replace(`"${tableName}"`, tableName);
return Promise.resolve(knex.raw(insertOrUpdateQuery));
};
very simple.
Adding onto Dorad's answer, you can choose specific columns to upsert using merge keyword.
knex('table')
.insert({
id: id,
name: name
})
.onConflict('id')
.merge(['name']); // put column names inside an array which you want to merge.

Change Spring Data Rest default message for DataIntegrityViolationException

I have a basic JPA Entity that I would like to expose via Spring-Data-Rest
#Entity
#Table(name='test')
class Test{
#Id
Long id
#Column(name='other_id', unique = true)
String otherId
#Column(name='other_crm_id')
String otherCrmId
#Column(name='created_date')
Date createdDate
#Column(name='created_by')
String createdBy
}
I would like to change the exception message that is thrown when the Unique constraint on 'otherId' fires. Currently the default ExceptionHandler for Spring Data Rest displays the following
{
-cause: {
-cause: {
cause: null
message: "Unique index or primary key violation:
\"UK_PJCWVB8DO3C89YTD1PNF85HQR_INDEX_2 ON PUBLIC.TEST(OTHER_ID) VALUES
( /* key:1 */ 2, NULL, NULL, 'ABC123424', '123')\"; SQL statement:\
insert into test (id, created_by, created_date, other_crm_id,
other_id) values (null, ?, ?, ?, ?) [23505-175]"
}
message: "could not execute statement"
}
message: "could not execute statement; SQL [n/a]; constraint
[\"UK_PJCWVB8DO3C89YTD1PNF85HQR_INDEX_2 ON PUBLIC.TEST(OTHER_ID) VALUES ( /* key:1
*/ 2, NULL, NULL, 'ABC123424', '123')\"; SQL statement:\ insert into test (id,
created_by, created_date, other_crm_id, other_id) values (null, ?, ?, ?, ?)
[23505-175]]; nested exception is
org.hibernate.exception.ConstraintViolationException: could not execute statement"
}
Not a big fan of the sql and table information being returned in the Response, so I've been attempting to change the message. I created a ExceptionHandlingController annotated with #ControlAdvice, but the ExceptionHandlers in AbstractRepositoryRestController.java take precedence.
My question is: What is the best way to change the error response for the DataIntegrityViolationException in Spring-Data-Rests default RepositoryEntityController?