I am trying to pass a nodejs variable to a sql query
Below is my code:
var b= 101;
connection = await oracledb.getConnection( {
user : dbConfig.user,
password : dbConfig.password,
connectString : dbConfig.connectString
});
sql = 'SELECT * FROM mytab where id= b';
binds = {};
options = {
outFormat: oracledb.OBJECT // query result format
};
result = await connection.execute(sql, binds, options);
try something along these lines:
sql = 'SELECT * FROM mytab where id= $1::int';
options = {
outFormat: oracledb.OBJECT // query result format
};
result = await connection.execute(sql, [ b ], options);
Related
I have an array projectIds with ids. I want to select all rows from a database that have a value for project_id that exists in the array:
const { sequelize } = require("./db"); //The db and sequelize work correctly in other places, so can be assumed to be set up correctly.
const { QueryTypes } = require("sequelize");
const projectIds = [1,2,3,4];
let rows = await sequelize.query(
"SELECT * FROM `table_name` WHERE project_id IN = ?",
{
replacements: [`${projectIds}`],
type: QueryTypes.SELECT,
}
);
The query returns UnhandledPromiseRejectionWarning: Error. What is wrong with this code?
You should use (?) or (:projectIds) instead of ? and pass the projectIds array as is:
let rows = await sequelize.query(
"SELECT * FROM `table_name` WHERE project_id IN (?)",
{
replacements: [projectIds],
type: QueryTypes.SELECT,
}
);
OR
let rows = await sequelize.query(
"SELECT * FROM `table_name` WHERE project_id IN = (:projectIds)",
{
replacements: { projectIds },
type: QueryTypes.SELECT,
}
);
There is a table A and jsonb field 'context', it looks like:
{
"variable": {},
"other_stuff": {}
}
I need to add a new property to 'varialbe' every time i run query. So It should do smth like:
query1
{
"variable": {
"var1": "var1Value"
},
"other_stuff": {}
}
query2
{
"variable": {
"var1": "var1Value1",
"var2": "var1Value2"
},
"other_stuff": {}
}
And if variable already has this field, it should replace it.
I run this sql, and it works:
let sql = UPDATE chatbots.A SET context = context || jsonb_set(context, '{variable, var1}', 'var1Value1')
It works but when i need to replace 'var1' and 'var1Value1' by parameters ($1 and $2) - it doesn't work (in node-postgres)
I realized that i can replace second parameter by
to_jsonb($2::text)
But what should i do with the first one?
My javascript code
async setUsersVariables(params: {users: ChatUser[], variable_name: string, variable_value: string}) {
const {users, variable_name, variable_value} = params
if (!users.length) return false
let sql = "UPDATE chatbots.A SET context = context || jsonb_set(context, '{variable, $1}', to_jsonb($2)::text) WHERE chat_user_id IN ( "
const parsedUsers = users.map(e=> e?.chat_user_id)
let sqlParams: any[] = [variable_name, variable_value]
let idx = 3;
({ sql, idx, params: sqlParams } = addSqlArrayParams(sql, parsedUsers, idx, sqlParams));
sql += ` RETURNING chat_id, chat_user_id, platform, platform_user_id`;
const filteredUsers: any = (await this.pool.query(sql, sqlParams)).rows
return filteredUsers
}
I'm trying to extract data from a MongoDb database and insert them into a SQL Server table, via a NodeJS program.
However, when I run it, it gives me almost 1 million lines and a huge SQL statement (with multiple "INSERT INTO", one for each row to avoid any limit) but it doesn't update my table.
I also tried to save the whole query in a text file and import it as a script in SSMS, but the file is too big (~300 mo) so SSMS is crashing.
What can I do? How can I maybe divide my query into smaller batches (like each 100 000 records) or pause it?
Here's my code :
var sql = require('mssql');
const fs = require('fs');
var config = { user: 'xxxxxx',
password: 'xxxxx',
server: 'xxxxx',
database: 'xxxx',
stream: true,
requestTimeout: 2000000,
};
exports.insertElementsInSql = function(elements, callback) {
let dateStr = new Date().toISOString().slice(0, 10);
sql.connect(config, function(err, conn) {
if (err) {
callback(err);
} else {
var request = new sql.Request();
request.stream = true;
var query = "";
var count=0;
query = query + "SET ANSI_WARNINGS OFF;";
query = query + "DELETE FROM [xxxx].[dbo].[xxxxx];";
for(var i in elements){
query = query + "INSERT INTO [xxxx].[dbo].[xxxxx] VALUES ";
query = query +"('" + dateStr + "'";
query = query + ",'"+elements[i].OrgaCode+ "'";
query = query + ","+elements[i].nbWidgets;
query = query + ","+elements[i].nbTabs;
query = query + ",'"+elements[i].Segment+ "'";
query = query + ",'"+elements[i].SitesList+ "'";
query = query + ",'"+elements[i].Columns+ "'";
query = query + ") ";
count++;
};
query = query + "SET ANSI_WARNINGS ON;";
console.log(query);
console.log("The query INSERT INTO is complete. Nb of lines : "+count);
fs.writeFile('request.txt', query, (err) => {
if (err) throw err;
console.log('Query saved!');
});
request.query(query, function(err, results) {
if (err) {
console.log("Failure ");
console.log(err);
callback(err);
} else {
callback(null);
console.log("Yay");
}
});
}
});
};
I get :
The query INSERT INTO is complete. Nb of lines: 919045
Thanks for any help!
I currently have the following function that works perfectly fine:
const sql = require('mssql');
const config = require('../../config/credentials');
const Hardware = function () { };
Hardware.prototype.create = function (body) {
return new sql.ConnectionPool(config).connect().then(function (pool) {
return pool.query
`SELECT *
FROM my_table
WHERE hardware_guid = ${id}
});
};
But I want "my_table" in the query to be a variable, like ${my_table}. If I do it in the same way, I get the following error:
Must declare the table variable "#param1"
Looking at the documentation of the mssql package (https://www.npmjs.com/package/mssql), specifically at the section of ConnectionPool, I can see that they declare this parameters in the following way:
const sql = require('mssql')
sql.connect(config).then(pool => {
// Query
return pool.request()
.input('input_parameter', sql.Int, value)
.query('select * from mytable where id = #input_parameter')
}).then(result => {
console.dir(result)
}).catch(err => {
// ... error checks
})
sql.on('error', err => {
// ... error handler
})
So I tried to do something similar, this is what I did:
var sql = require("mssql")
var config = require("./test");
var id='1'
const pool1 = new sql.ConnectionPool(config);
pool1.connect().then(pool => {
return pool1.request() // or: new sql.Request(pool1)
.input('mytable', sql.NVarChar, 'nvs_central.software_governance')
.query(`SELECT *
FROM #mytable
WHERE software_guid = ${id}`)
}).then(result => {
console.dir(result)
}).catch(err => {
console.dir(err)
});
pool1.on('error', err => {
console.dir(err)
});
But I still get the "Must declare the table variable "#mytable" error. Note that if I replace "#mytable" in that last piece of code for "my_table_name" (so I put the actual name of the table instead of a variable/parameter) it retrieves the expected data perfectly fine.
So what do I need to do?
Thanks!
You can still use the .inputs to protect you against SQL injections; you just need to pump them through EXEC() in a stringified form:
const result = await pool.request()
.input("TableName", $ddi.app.services.sql.lib.VarChar(50), oData.TableName)
.input("TableColumn", $ddi.app.services.sql.lib.VarChar(50), oData.TableColumn)
.input("ID", $ddi.app.services.sql.lib.VarChar(50), oData.ID)
.query(`
EXEC('SELECT ' + #TableColumn + ' FROM ' + #TableName + ' WHERE ' + #TableColumn + ' = ' + #ID + ';');
`)
;
in sql server #table_name means it is a temporary table variable. you are essentially telling it that you have declared a variable temporary table and you want to select from that. so it attempts to look for it in tempdb and when it doesn't find it, it throws a syntax error.
you will need to switch it back to the "working" example way if you want it to work as using #table in the from clause makes sql server assume you are using a variable temp table.
I inserted the table name the 'oldschool' way:
const queryString = "SELECT * FROM DocuManager." + tableName + " WHERE id = #id";
const result = await pool.request()
.input('id', sql.Int, id)
.query(queryString);
That works fine.
From the npm docs, only visible prepared statements are for insert. Does these prepared statement work for Select, update, and delete?
I tried for select, there isn't a .each function where the rows are called back. Anyone been able to do this or have links to resources, cause I can sure as hell unable to find any.
According to the node-sqlite3 API documentation, you can use parameters in your SQL queries in several different ways:
// Directly in the function arguments.
db.run("UPDATE tbl SET name = ? WHERE id = ?", "bar", 2);
// As an array.
db.run("UPDATE tbl SET name = ? WHERE id = ?", [ "bar", 2 ]);
// As an object with named parameters.
db.run("UPDATE tbl SET name = $name WHERE id = $id", {
$id: 2,
$name: "bar"
});
Yes, prepared statements are supported.
With node-sqlite3:
var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database('data.db');
db.serialize(function() {
var stmt = db.prepare("INSERT INTO users VALUES (?,?)");
for (var i = 0; i < 10; i++) {
stmt.run("user " + i, "email " + i);
}
stmt.finalize();
stmt = db.prepare("SELECT * FROM users WHERE id=?");
stmt.each(userId, function(err, row) {
console.log(row.name, row.email);
}, function(err, count) {
stmt.finalize();
});
});
With better-sqlite3:
var Database = require('better-sqlite3');
var db = new Database('foobar.db', options);
var stmt = db.prepare("INSERT INTO users VALUES (?,?)");
for (var i = 0; i < 10; i++) {
stmt.run("user " + i, "email " + i);
}
var stmt = db.prepare('SELECT * FROM users WHERE id=?');
var row = stmt.get(userId);
console.log(row.name, row.email);