Node mssql: return id after SQL insertion - javascript

I am working on an integration between Mongodb and SQL Server, inserting and updating registers from MongoDb to SQL Server database with a scheduled process, using the mssql package to achieve this.
Each time a new register is inserted, I want the new row id to be retrieved back, because I need it to perform another insertions of subregisters.
I tried the following, expecting to have some information retrieved in the result of the query. The query actually inserts the row, but result is returned as undefined:
var sql = require('mssql');
var connectionConfig = 'xxxxxxxxxxxx';
var insertionQuery = 'xxxxxxxxxxxx';
sql.connect(connectionConfig).then(pool => {
pool
.request()
.query(insertionQuery);
}).then(result => {
//I expect 'result' to have information of the inserted row, but it comes undefined instead
cosole.log(result);
}).catch(err => {
console.err(err);
});
I think using stored procedures may work around this, but I just want to avoid using a stored procedure for simple inserts.
Does anyone knows how to have the new row id back after insertion?
EDIT
I did include OUTPUT SCOPE_IDENTITY() in my SQL statement - my query now looks like:
INSERT INTO TABLE (columns...)
OUTPUT SCOPE_IDENTITY()
VALUES (values...)
If I run the query in my SQL Server Management Studio, it works just fine and I got my new row id returned, but when running the query through the mssql package's query method, result is returned like this:
[ { '': null } ]

I quote from node-mssql insert returning undefined recordset:
INSERT statement doesn't return a recordset so recordset is
undefined. Please see this section of the docs to learn more
about how to get number of affected rows.
An option to solve this is to add a SELECT statement after your INSERT and ask for SCOPE_IDENTITY() or ##IDENTITY. That will get you the ID of the last inserted objects, i.e.:INSERT INTO table (...) VALUES (...); SELECT SCOPE_IDENTITY() AS id;

If anyone comes having problems with GUID, since you cannot set it as an Identity column, you must do something like:
const result = await pool
.request()
.input('orgName', sql.VarChar, orgName)
.input('tier', sql.Int, tier)
.input('status', sql.Int, status)
.input('createDate', sql.Date, new Date())
.input('statusChangeDate', sql.Date, new Date())
.query(`INSERT INTO app.Organizations (OrgName,
Tier, Status, CreateDate, StatusChangeDate)
OUTPUT inserted.OrgID
VALUES (#orgName, #tier, #status, #createDate, #statusChangeDate);
`)
Where the orgID is the auto generated GUID. Also don't follow my new Date() example as it inserts the date as tomorrow... I need to fix that.

Related

How to order document .add() data in firestore in Javascript

Ive been struggling with ordering the documents in Cloud Firestore.
Im using the collection.add() method. And reading the data and displaying it on the screen.
Heres how i write it into the database:
let shared = {
category : category,
username : user.displayName,
createdAt : date,
}
// Add a new document with a generated id.
const sharedRef = db.collection('shared');
sharedRef.orderBy('createdAt', "desc");
sharedRef.add(shared)
.then(function() {
console.log("Saved to database");
}).catch(function(error) {
console.error("Error adding document: ", error);
});
And to Read the data I just use doc.data forEach.
I Read the data with doc.data() forEach
Is there anyway i can order the shared documents by the date created?
orderBy is for queries that read data, not for adding data. You can't set the order at the time you call add(). The order you see in the console by default is always going to sort by the document ID, which is random for every call to add().
You shouldn't be concerned about the order that the documents appear in the console. You should only be concerned about putting fields in each document that you can use later to sort them in a query.

Using a variable in a WHERE clause MySQL/Node

I'm trying to make a MySQL query to filter data from a table. Effectively what I want to do is:
SELECT data FROM table WHERE column IN ?
The filter is coming from checkboxes in a form on a webpage, so I can pass an array or object fairly easily, but it'll be a varying number of parameters for the IN each time, so I can't us multiple ?. I tried making a for loop to make multiple queries concatenate the arrays that the queries returned, but I ran into scope issues with that. I also tried passing an array directly to the query, but that throws a syntax error. I'm sure there's a straightforward answer to this but I'm not sure how to do it.
Edit: source code added:
Here's where I'm at:
const filterShowQuery = `SELECT sl_Show.showId, sl_Band.BandName,
sl_Show.date, sl_Venue.venueName,
sl_Show.length, sl_Show.attendance, sl_Show.encore FROM sl_Show
JOIN sl_Band on sl_Show.BandID = sl_Band.BandId
JOIN sl_Venue on sl_Show.VenueId = sl_Venue.VenueId
WHERE sl_Band.BandName IN (?)
ORDER BY sl_Band.BandName;`;
Trying to get an array into the ? in WHERE sl_Band.BandName IN
const getShows = (req, res,next) =>{
var {bands, venues} = req.body;
var i = 0; //left over from previous attempt
var data = [];
for (b in bands){
mysql.pool.query(filterShowQuery, bands[b], (err, result) => {
if(err){
console.log('filter band error');
next(err);
return;
}
data = data.concat(result);
console.log(data); //data concatenates property and increases through for loop
})
// same action to be performed with venues once solved
// for (v in venues){
// conditions[i] = venues[v];
// i++;
console.log(data); //data is empty when logging from here or using in res
res.json({rows:data});
}
}
SECURITY WARNING!
I must to say: NEVER, NEVER PASS DATA DIRECTLY TO YOUR SQL!
If you don't know why, just google for SQL Injection. There are lots of examples on how it is done, how easily it can be done, and how to protect your application from this sort of attack.
You should always parametrize your queries. But in the very rare case which you really need to insert data concatenating a string into your sql, validate it before.
(E.g.) If it's a number, than use a Regex or some helper method to check if the value you are inserting into your SQL String is really and only a number and nothing else.
But aside that, you did not provide any source code, so it's really hard to give any help before you do that.

Firestore query returning empty snapshot

I have a node websocket listener set to query some data from my database. Currently however the query returns an empty snapshot even though I know that the query should return something.
I'm making a simple node based forum (although I'm pretty new to Node so it's not that good lol) and I'm trying to query post data from the server to send back to the client. I've tried checking to see if my post references were correct and double checked that the values I'm querying exist within the collection. I've also already checked that the data was sent through the socket correctly so I'm at a loss.
let query = db.collection('posts').where('id','==',postID);
query.get().then(snapshot => {
if (snapshot.empty) {
client.emit('resPost', 'Failed');
return;
}
snapshot.forEach(doc => {
console.log(doc.data());
client.emit('resPost', doc.data());
});
});
When I load the post page I get the response tied to the empty snapshot.
Edit: As suggested by #Phil I've included a log for the postID variable.
console.log('postID', typeof postID, JSON.stringify(postID))
Output:
postID string "0"
Here's a screenshot of the console if needed. The ClientID is the ID of the websocket connection.
https://imgur.com/a/MdtwEvu
I'm quite surprised there isn't a duplicate question anywhere but here's your answer...
Firestore's query equality conditionals are type-sensitive. If your collection property is an integer, you need to compare it to an integer instead of a string.
For example
db.collection('posts').where('id', '==', parseInt(postID, 10))

Parse Javascript SDK - Query causing 500 Internal Server Error

I have some Parse Cloud code that fetches and updates data in the Parse database.
app.get('/endpoint', function(request, response) {
var username = "name";
var something = "something";
var userFetchQuery = new Parse.Query(Parse.User);
userFetchQuery.equalTo("username", username);
userFetchQuery.first().then(function(foundUser) {
var fetchQuery = new Parse.Query("Call");
fetchQuery.equalTo("initiator", foundUser);
//fetchQuery.equalTo("status", 5);
return fetchQuery.first();
}).then(function(currentObject) {
var callObjectId = currentObject.id;
currentCall.set("something", something);
return currentCall.save();
}).then(function(success) {
response.send(ourResponse);
});
});
The code above works fine, however if I try to uncomment the line where I query the table by status (fetchQuery.equalTo("status", 5);), then I get the 500 internal error. Basically, I can't seem to query with both criteria (user and status).
Can't we have two equalTo() calls to the Parse.Query object? What could be wrong here?
======== EDIT 1 ========
If I query by both user and status, then I get no results back. If I query by just one of them, then I get data back. So, the question is: why are the two equalTo() statements causing the query to fail? I am 100% sure that I have appropriate data.
======== EDIT 2 ========
I have tried to isolate the issue by querying by any 2 fields of the table. Whenever there are two equalTo() statements, the query doesn't return anything. I have hardcoded the values for the equalTo() to make sure and result is always the same. Having more than one equalTo()s for Parse.Query() object results in 0 query results.

WebSQL return object

Can someone show me a web SQL select query that returns the results as an object rather than alerting or logging to the console.
I want to centralize my select queries rather than repeating the select / execute and process results code in the specific functions.
If we presume that the question relates to the API required under Web SQL to execute the query and obtain a result set you can proceed as shown below. I've not given much detail as the question is a tad vague and shows little evidence of homework...
Initiate a readTransaction (you did say 'query' so I'll presume "select") on an open database:
db.readTransaction(onStartTransaction); // less locking overhead with a readTransaction
The onStartTransaction function looks like this:
function onStartTransaction(tx) {
tx.executeSql(sql, params, onExecuteSqlOk, onExecuteSqlFail);
}
Just pass your sql and a [] for params if you don't need any.
Your results will be returned to your 'onExecuteSqlOk' function:
function onExecuteSqlOk(tx, result) {
//
// tx: an SqlTransaction object
// results: an SqlResultSet object
//
The goodies are in the SqlResultSet object.
it has a structure with a 'rows' property. Each row contains the fields specified in the sql select statement.
var len = results.rows.length; // how many rows did we get
var firstRow = results.rows.item(0);
Thus you get an "object" back as the results from a Web Sql query. Note that the api shown is asynchronous so you will probably want to use a further callback function....

Categories

Resources