I have a MySql database, and I'm connecting to it from a .Net app using Dapper. I have the following code:
await connection.ExecuteAsync(
"DELETE FROM my_data_table WHERE somedata IN (#data)",
new { data = datalist.Select(a => a.dataitem1).ToArray() },
trans);
When I do this with more than a single value, I get the following error:
MySqlConnector.MySqlException: 'Operand should contain 1 column(s)'
Is what I'm trying to do possible in MySql / Dapper, or do I have to issue a query per line I wish to delete?
Your original code was almost fine. You just need to remove the parentheses around the parameter. Dapper will insert those for you:
await connection.ExecuteAsync(
"DELETE FROM my_data_table WHERE somedata IN #data",
new { data = datalist.Select(a => a.dataitem1).ToArray() },
trans);
Related
I'm trying to use Prisma (ORM) to manage my MySQL database.
When I used MySQL directly I could run mysql_insert_id() after insert command to get the auto_increment indexes values I've just inserted.
How can I achieve this in Prisma?
The return value of insert is the affected rows, not the indexes.
EDIT
If you use the prisma.create() it does return the object with it's new id.
But if you use prisma.createMany() it return only the count of affected rows ?!?!
Someone care to explain the design behind this?
You would need to use Raw Query to execute the insert statement which returns indexes values.
From the documentation:
Use $queryRaw to return actual records.
Use $executeRaw to return a count of affected rows
So you would need to use the queryRaw method.
You can use like this:
const now = new Date();
const createdRecord = await this.prisma.post.create({
data: {
title: input.title!,
content: input.content!,
created_at: now,
updated_at: now
}
})
// now you can access id of created record by createdRecord.id
const id = createdRecord.id
// ...whatever you want with id
So, I started to develop in nodejs and mysql. I read in some forums that the correct way to do the insertion in mysql would be using variables to prevent mysql injection, however I tried in several ways to insert them and I couldn't. I was only able to do them manually as follows:
db.query('UPDATE spreadsheetUsers SET weight="1" WHERE weekDay="1" AND idStudent="1" ', (error,results) =>
How could I do to insert them using variables?
The way I was trying was like this:
db.query('UPDATE spreadsheetUsers SET weight=? WHERE weekDay=? AND idStudent=? '
,{weight:value[0], weekDay:daySelected, idStudent:idStudent }, (error,results) =>
I guess im missing something, could someone help?
https://github.com/mysqljs/mysql#escaping-query-values
{weight:value[0], weekDay:daySelected, idStudent:idStudent }, (error,results) =>
the parameterized query should be array not object
db.query('UPDATE spreadsheetUsers SET weight=? WHERE weekDay=? AND idStudent=?'
,[value[0], daySelected, idStudent], (error,results) =>
You can use this style also
db.query({
sql: 'UPDATE spreadsheetUsers SET weight=? WHERE weekDay=? AND idStudent=?',
values: [value[0], daySelected, idStudent']
}, function (error, results, fields) {
// error will be an Error if one occurred during the query
// results will contain the results of the query
// fields will contain information about the returned results fields (if any)
});
I'm trying to convert my SQL into KNEX. what I have so far is:
SQL:
SELECT name from students where attendance = "90" AND timestamp between "2020-05-14" AND "2020-05-18";
my attempt to convert to KNEX:
const from = req.query.from;
const to = req.query.to
router.get('/students/attendance?from=&to='
req.db.from('students').select("*").where('attendance', '=', req.params.attendance).andWhere('timestamp', 'between', [from, to])
MYSQL code works and returns what I want but I'm assuming my syntax is wrong with the Knex. Push in the right direction please
Where between is documented here https://knexjs.org/#Builder-whereBetween
await req.db
.from('students')
.select("*")
.where('attendance', req.params.attendance)
.whereBetween('timestamp', [from, to])
Also you can use .toSQL() to inspect the built query query.
I have the following code that I used for inserting into MySQL (MariaDB)....
import mysql from "mysql";
const INSERT_QUERY = "INSERT INTO CALL_DATE SET ? ON DUPLICATE KEY UPDATE MADE_DATE = VALUES(MADE_DATE)";
insertCallDate(callId, server, date){
const callDate = {
...
};
return connection.query(
INSERT_QUERY,
callDate
);
}
When I move to oracleDB I would like to do something like that again but the closest I can find is something like...
const INSERT_QUERY = "INSERT INTO CALL_DATE SET (ID, ...) values (:1, ...)";
Is there something similar to MySQL so I can pass a prestructured JSON object to Oracle? Specifically using the Node JS oracledb library?
There's a short section on JSON in the node-oracledb documentation. To quote an example:
const data = { "userId": 1, "userName": "Chris", "location": "Australia" };
const s = JSON.stringify(data); // change JavaScript value to a JSON string
const result = await connection.execute(
`INSERT INTO j_purchaseorder (po_document) VALUES (:bv)`,
[s] // bind the JSON string
);
There are also two runnable examples: selectjson.js and selectjsonblob.js.
Most of the JSON technology in Oracle is not specific to node-oracledb, so the Oracle manual Database JSON Developer’s Guide is a good resource.
You may be interested in SODA, which is also documented for node-oracledb and has an example, soda1.js. It lets you store 'documents' in the DB. These documents can be anything, but by default JSON documents are used.
I am trying to get the records from the 'many' table of a one-to-many relationship and add them as a list to the relevant record from the 'one' table.
I am also trying to do this in a single database request.
Code derived from Linq to Sql - Populate JOIN result into a List almost achieves the intended result, but makes one database request per entry in the 'one' table which is unacceptable. That failing code is here:
var res = from variable in _dc.GetTable<VARIABLE>()
select new { x = variable, y = variable.VARIABLE_VALUEs };
However if I do a similar query but loop through all the results, then only a single database request is made. This code achieves all goals:
var res = from variable in _dc.GetTable<VARIABLE>()
select variable;
List<GDO.Variable> output = new List<GDO.Variable>();
foreach (var v2 in res)
{
List<GDO.VariableValue> values = new List<GDO.VariableValue>();
foreach (var vv in v2.VARIABLE_VALUEs)
{
values.Add(VariableValue.EntityToGDO(vv));
}
output.Add(EntityToGDO(v2));
output[output.Count - 1].VariableValues = values;
}
However the latter code is ugly as hell, and it really feels like something that should be do-able in a single linq query.
So, how can this be done in a single linq query that makes only a single database query?
In both cases the table is set to preload using the following code:
_dc = _db.CreateLinqDataContext();
var loadOptions = new DataLoadOptions();
loadOptions.LoadWith<VARIABLE>(v => v.VARIABLE_VALUEs);
_dc.LoadOptions = loadOptions;
I am using .NET 3.5, and the database back-end was generated using SqlMetal.
This link may help
http://msdn.microsoft.com/en-us/vcsharp/aa336746.aspx
Look under join operators. You'll probably have to change from using extension syntax other syntax too. Like this,
var = from obj in dc.Table
from obj2 in dc.Table2
where condition
select