how to input nodejs variable into oracle sql query - sql

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

SQL query to select all rows with a value included in an array

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,
}
);

How to Add a new field to nested jsonb object in Node-Postgres using parameters?

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
}

How to execute large SQL statement

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!

How do I execute a query with variable table name in node.js MSSQL?

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.

Does SQLite3 have prepared statements in Node.js?

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);