sqlite where clause "AND" and "IN" - javascript

Objective:
I am trying to do bulk delete in sqlite table, instead of deleting each data with for loop. So, I am trying to use "IN".
Case:
I have two parameters in executing the query. First is type and second is order_id. I want to delete data where the type is "order_book" and order_id are ["B001", "B002", ...].
What I've try but not working:
window.sqlitePlugin.openDatabase({ name: 'dbname.db', location: 'default' }).executeSql("DELETE FROM table_name WHERE type='order_book' AND order_id IN ('B001', 'B002')", [], (res) => { console.log(res.rows); });
// => this is not work
What I've try and works, but, it miss the type parameter:
window.sqlitePlugin.openDatabase({ name: 'dbname.db', location: 'default' }).executeSql("DELETE FROM table_name WHERE order_id IN ('B001', 'B002')", [], (res) => { console.log(res.rows); });
// => data with order_id B001 and B002 deleted
So, whats wrong here? I need to also define what is the type because different type may have same order_id (don't ask why this is happen ...)
Thanks in advance for anyhelp!

If data is stored in mixed case or upper case in the type column then SQLite's case sensitive comparison will not find it. You could check against the data stored or compare strings like this:
WHERE type='order_book' COLLATE NOCASE ...

Related

How to call a Sequelize MySQL JSON query?

I have a User model that includes a json data type. I'm using MySQL as my database, but when looking through their documentation for how to query using JSON, there appears to be nothing on MySQL.
const User = db.define("User", {
UserId: {
primaryKey: true,
type: Sequelize.INTEGER
},
colors: {
type: Sequelize.JSON,
allowNull: false
}
}
I have Users that have an id, and an array with their favorite colors in it.
UserId | colors
1 |["black, "blue"]
2 |["blue"]
3 |["black"]
I want to query for all users that have the favorite color blue. I tried querying like this,
User.findAll({ where: {colors: ["blue"]} })
and expected to be returned users 1 and 2, but this doesn't work and I have not found any sources online that shows what to do. Some stackoverflows have solutions for JSON objects, like this Sequelize, MySQL - Filtering rows in table with JSON column values, but I can't find any sources for arrays. Any solutions?
You can use sequelize.fn and sequelize.col methods to specify an SQL function call and a table column, respectively. This way you can create your own where condition.
User.findAll({
where: sequelize.where(sequelize.fn('JSON_CONTAINS', sequelize.col('colors'), sequelize.literal('blue'), sequelize.literal('$')), 1)
});
It corresponds to below mysql query:
// SELECT * FROM Users WHERE JSON_CONTAINS(colors, 'blue', '$') = 1;
The answer should be:
User.findAll({
where: sequelize.where(sequelize.fn('JSON_CONTAINS', sequelize.literal('colors'), '"blue"', '$'), 1)
});
Note:
The 2nd parameter of JSON_CONTAINS should be string.
Because the data of question is an array of string, so we need to add a " for searching keyword (e.g: "blue").

SQL insertion with two errors

I'm trying to create a transaction in my MMSQL database with Javascript.
I have tried this command which inserts some elements to a table myTable:
const sql = require('mssql');
const sqlConfig = {
user: 'xxx',
password: 'xxx',
server: 'xxx',
database: 'myDatabase',
options: {
encrypt: false
}
};
const result = await connection.query("INSERT INTO [myTable] ([ID],[ClassId],[Active],[LastUpdateDateTime] ,
[LastUpdateUser] ,[Number] ,[ExternalId] ,
[MaterialDefinitionId] ,[CompanyId] ,[IsBlanket] ,
[Type] ,[Subtype] ,[CreatedDate] ,[ValidFromDate] ,
[ValidToDate] ,[OrderedQuantity] ,[DeliveredQuantity] ,
[ReservedQuantity] ,[UnitOfMeasurement] ,[Status],
[Note],[RowVer])
VALUES ('0','0','0','0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0')");
But i get this timestamp error:
RequestError: Cannot insert an explicit value into a timestamp column. Use INSERT with a column list to exclude the timestamp column, or insert a DEFAULT into the timestamp column.
So i removed all the probably time dependent elements (LastUpdateDateTime , CreatedDate , ValidFromDate , ValidToDate).
But i still get a new error:
RequestError: The INSERT statement conflicted with the FOREIGN KEY constraint "FK_MaterialLot_Company". The conflict occurred in database "myDatabase", table "myTable", column 'ID'.
So i'm a bit lost here. Does someone have an idea about the problem?
Thanks a lot!
RequestError: The INSERT statement conflicted with the FOREIGN KEY
constraint "FK_MaterialLot_Company". The conflict occurred in database
"myDatabase", table "myTable", column 'ID'.
The ID value you are attempting to INSERT needs to already exist in another table. Check to see how FK_MaterialLot_Company is defined. Possibly relates to a table called "MaterialLot_Company"?

How do I select everything from a specific column, from a specific table, and then push them into an array?

I'd like to get everything from a column called userID from a table called userdata, and then push all of that to an array to later be used for a forEach() loop, is there a correct way to do this?
Use the SQL query SELECT userID FROM userdata.
Where SELECT tries to select the paramater after it, which is the column userID. It then specifies where to get the data from, FROM userdata - the userdata table.
If you were using better-sqlite3, it would be as simple as:
const rows = <db>.prepare('SELECT userID FROM userdata').all();
// rows: [ { userID: 'foo' }, { userID: 'foo' } ]
// With this array of objects, you are able to use a forEach loop
rows.forEach(object => {
console.log(object.userID);
});

get records after creation using sequelize raw query

I am using sequelize for migration. here I execute an INSERT query with following options but its didnot return created records:
const res = oldUsers.map(u => sequelize.query(
`INSERT INTO ${LP_LOCATIONS_TABLE} (name, address, city)
VALUES (
'${u.email}', '${u.address}', '${u.city}');`,
{ type: DataTypes.QueryTypes.INSERT, raw: true },
))
the output is an array of array like below:
[ [[0],[1]] ]
i expect to get created recorders. specially PK. how can I fix it?
I forgot to put RETURNING * at the end of the raw SQL query.
From the doc, you may have to specify the option returning:true to make this happen. I use mySql, so can't test (the returning option is only for postgres).

In a Nodejs Sequelize model, how to obtain type information of attributes?

I have a working model with Postgres and sequelize in NodeJS. Say the model is Person and has name and age fields. Now I want to dynamically inspect the model class and obtain information about it's attributes, like their name and most of all type.
Using Person.attributes
I get some information:
name:
{ type:
{ options: [Object],
_binary: undefined,
_length: 255 },
But as you can see the type object does not inform about name being a varchar or boolean.
Does anyone know, how to get this information with sequelize
You can iterate over rawAtributes of Model
for( let key in Model.rawAttributes ){
console.log('Field: ', key); // this is name of the field
console.log('Type: ', Model.rawAttributes[key].type.key); // Sequelize type of field
}
So the example for name being a Sequelize.STRING would be
Field: name
Type: STRING
Or you can do almost the same iteration but instead using Model.rawAttributes[key].type.key you can use Model.rawAttributes[key].type.toSql(), which would generate this result
Field: name
Type: VARCHAR(255)
EDIT
Accessing defaultValue of field:
Model.rawAttributes[field].defaultValue
Checking if field allows NULL values:
Model.rawAttributes[field].allowNull
You are looking for native type information, it seems.
I'm not familiar with Sequelize, except I know it uses node-postgres driver underneath, which automatically provides the type information with every query that you make.
Below is a simple example of dynamically getting type details for any_table, using pg-promise:
var pgp = require('pg-promise')(/*initialization options*/);
var db = pgp(/*connection details*/);
db.result('SELECT * FROM any_table LIMIT 0', [], a => a.fields)
.then(fields => {
// complete details for each column
})
.catch(error => {
// an error occurred
});
There are several fields available for each column there, including name and dataTypeID that you are looking for ;)
As an update, following the answer that does use Sequelize for it...
The difference is that here we get direct raw values as they are provided by PostgreSQL, so dataTypeID is raw type Id exactly as PostgreSQL supports it, while TYPE: STRING is an interpreted type as implemented by Sequelize. Also, we are getting the type details dynamically here, versus statically in that Sequelize example.
item.rawAttributes[key].type.key === this.DataTypes.JSONB.key;
#piotrbienias Is above comparison valid ?
(Sorry for writing here as I can't add comments)

Categories

Resources