I have a stored procedure that returns two tables data. While I am executing stored procedure from the server side script I got tow tables data together as individual rows.
But on response I couldn't figure out which row belongs to which table.
Can anyone help me to solve this
Here is my code
server.js
var pool = new ConnectionPool(poolConfig, config);
var sqlGet = "exec dbo.getTableData";
var data = [];
pool.acquire(function (err, tconnection) {
if (err) {
console.error(err);
return;
}
var request = new Request(sqlGet, function(err, result){
tconnection.release();
if(err)
console.log(err);
res.send(data);
});
request.on('row', function(columns) {
var row = {};
columns.forEach(function(column) {
row[column.metadata.colName] = column.value;
});
data.push(row);
});
tconnection.execSql(request);
});
My Stored procedure code:
CREATE PROCEDURE [dbo].[getTableData]
AS
SELECT * FROM table1;
SELECT * FROM table2;
RETURN
On below code I get list of columns returning from stored procedure, on column I got this response
request.on('row', function(columns) {
var row = {};
columns.forEach(function(column) {
row[column.metadata.colName] = column.value;
});
data.push(row);
});
Thanks #PrashanthReddyBalemula, As from his comment, I solved my problem by returning table name from the stored procedure
CREATE PROCEDURE [dbo].[getTableData]
AS
SELECT *, 'MyTable1' as TableName FROM table1;
SELECT *,'MyTable2' as TableName FROM table2;
RETURN
By this I can get the table's name from the field TableName
Related
This is the code in nodejs:
//Insert an employee
app.post('/employees', (req, res) => {
let emp = req.body;
var sql = "SET #EmpID = ?; SET #Name = ?; SET #EmpCode = ?; SET #Salary = ?; \
CALL EmployeeAddOrEdit(#EmpID,#Name,#EmpCode,#Salary);";
mysqlConnection.query(sql,[emp.EmpID, emp.Name, emp.EmpCode, emp.Salary],(err, rows, fields) => {
if (!err)
rows.forEach(element => {
if (element.constructor == Array)
res.send('Inserted employee id : ' + element[0].EmpID);
});
else
console.log(err);
})
});
I don't know if you will be able to see the image.
In the postman it keeps giving me this message:
Inserted employee id : null
Not getting the id number. In mysql workbench created the db with all the data proper settings, had 4 names, the delete process with postman was successful, but can't simply insert the data
You cannot return more than one response. So you can't use res.send in a loop.
But you can create an array and add all the ids to the array and present them in the response.
//Insert an employee
app.post('/employees', (req, res) => {
let emp = req.body;
var sql = "SET #EmpID = ?; SET #Name = ?; SET #EmpCode = ?; SET #Salary = ?; \
CALL EmployeeAddOrEdit(#EmpID,#Name,#EmpCode,#Salary);";
const container = []; //Create an empty array
mysqlConnection.query(sql, [emp.EmpID, emp.Name, emp.EmpCode, emp.Salary], (err, rows, fields) => {
if (!err) {
rows.forEach(element => {
if (element.constructor == Array)
container.push(row.insertedId); //Push the ids to the array
});
res.send('Inserted employee ids : ' + container.join());
}
else
console.log(err);
})
});
When an existing SQL record exists I want to use it rather than adding another, but if it doesn't yet exist I want to add it. The issue I am having is that when my Node.js app's endpoint is called it's not executing in the correct order so the SQL lookup to find existing records is happening after I check it's length to see if I need to add a new record.
// it does this second
let existingGet = "SELECT * FROM Items WHERE name = '" + productName + "'";
let existingItem = async () => {
db.query(existingGet, function (err, rows, fields) {
return rows;
});
};
// it does this first
if (await existingItem().length > 0) {
// Existing found, use existing
itemId = existingItem.ID;
} else {
// Item not found, create new
var sql = "INSERT INTO Items (...) VALUES (...)";
await db.query(sql, async function (err, result) {
itemId = existingItem.affectedRows.ID;
});
}
The desired outcome is that it does the first section before the second section because the second section needs the results of the first.
Try removing the outer brackets so that the existingItem will receive the result from the query
// it does this second
let existingGet = "SELECT * FROM Items WHERE name = '" + productName + "'";
//removed outer brackets
let existingItem = async () =>
db.query(existingGet, function (err, rows, fields) {
return rows;
});
// it does this first
if (await existingItem().length > 0) {
// Existing found, use existing
itemId = existingItem.ID;
} else {
// Item not found, create new
var sql = "INSERT INTO Items (...) VALUES (...)";
await db.query(sql, async function (err, result) {
itemId = existingItem.affectedRows.ID;
});
}
Do it in a single db call using sql command
"INSERT INTO Items (...) VALUES (...)
WHERE NOT EXISTS (SELECT 1 FROM Items WHERE name = ...)"
And use sql command parameters instead of concatenation to avoid sql injection.
sql.get(`SELECT * FROM scores ORDER BY points DESC`).then(allScores => {
console.log(allScores);
});
This should give me all of the rows ordered by points, but I'm only getting the first row.
How do I access all of the other rows using javascript?
Use sql.all instead of sql.get refer http://www.sqlitetutorial.net/sqlite-nodejs/query/
Define your db instance as follows:
const sqlite3 = require('sqlite3').verbose();
// open the database
let db = new sqlite3.Database('./db/yourCoolDB');
And then,
let sql = `SELECT * FROM scores ORDER BY points DESC`;
db.all(sql, [], (err, rows) => {
if (err) {
throw err;
}
rows.forEach((row) => {
console.log(row.Id); // You can use row.yourAnotherAttributeName
});
});
I have an array of customer objects, that I wish to insert to the SQL database.
The customer objects are retrieved from the req data.
I am using Tedious for the request, and Tedious Connectionpool in order to have multiple connections at the same time.
When looping over the objects i am getting an error when trying to insert, the error being
{ [RequestError: Violation of PRIMARY KEY constraint `'PK__Customer__A4AE64D873A5400C'. Cannot insert duplicate key in object 'dbo.Customer'. The duplicate key value is (2).]`
Note that I only have 3 object being send in the req at this time. It looks to me that it is only the last object that are being handled and inserted. But since I am new to using tedious with Node.js i cant spot my mistake. Any suggestions ?
router.post('/',jsonParser, function(req, res) {
var customers = req.body.customers;
var companies = req.body.companies;
var Connection = require('tedious').Connection;
var Request = require('tedious').Request;
var TYPES = require('tedious').TYPES;
var config = {
userName: '*************',
password: '*************',
server: '***********.database.windows.net',
// When you connect to Azure SQL Database, you need these next options.
options: {encrypt: true, database: '*******'}
};
var poolConfig = {
min: 1,
max: 3,
log: true
};
var pool = new ConnectionPool(poolConfig, config);
for (var i = 0; i < customers.length; i++) {
console.log('Inserting '+customers[i].firstname);
var firstname = customers[i].firstname;
var count = i;
pool.acquire(function (err, connection) {
if (err)
console.error(err);
//use the connection as normal
var request = new Request("INSERT INTO dbo.Customer" +
" (Firstname,CustomerId)" +
"VALUES" +
" (#Firstname,#CustomerId);", function (err, rowCount) {
if (err)
console.error(err);
console.log('rowCount: ' + rowCount);
//release the connection back to the pool when finished
connection.release();
});
request.addParameter('Firstname', TYPES.VarChar,firstname);
request.addParameter('CustomerId', TYPES.Int, count);
request.on('row', function (columns) {
console.log('value: ' + columns[0].value);
});
connection.execSql(request);
});
pool.on('error', function (err) {
console.error(err);
});
}
});
The scope of your variables count and firstName are global. By the time the pool.acquire( function get's executed the for loop has completed and it is inserting the last customer twice. One possible solution would be to put an anonymous function inside the for loop e.g. (it doesn't have to be anonymous though)
for (var i = 0; i < customers.length; i++) {
(function(count, firstName) {
...do insert here...
}(i, customers[i].firstname));
}
I'm trying to retrieve all data from a db table into json object, like so:
function getTableData()
{
var vals = {};
var data = [];
try {
var dbCon = $.db.getConnection();
var query = 'SELECT * FROM SAPPRD.ZUSERDATATAB';
var pstmt = dbCon.prepareStatement(query);
var rs = {};
rs = pstmt.executeQuery();
while (rs.next()) {
vals.team = rs.getString(1);
vals.fname = rs.getString(3);
vals.lname = rs.getString(2);
data.push(vals);
$.response.status = $.net.http.OK;
}
$.response.setBody(JSON.stringify(data));
// $.response.contentType = contentType;
// $.response.headers.set('Content-Disposition', 'filename=' + filename);
} catch (e) {
$.response.setBody('errors: ' + e.message);
}
}
The query works only partially, because in data I get number of rows x last row content, like so:
[{"team":"I313766","fname":"0","lname":"LEGOWSKI"},
{"team":"I313766","fname":"0","lname":"LEGOWSKI"},
etc. etc.]
How would I make it retrieve all the data instead of one row number of times?
Okay, I got the solution. Moving a single line declaring array vals into the while statement solved the problem - the array vals was initialized as an empty array each time, therefore allowing the proper .push of each row, instead of pushing last row from db table into data multiple times. Thanks to everybody who took time and tried answering.
function getTableData()
{
var data = [];
try {
var dbCon = $.db.getConnection();
var query = 'SELECT * FROM SAPPRD.ZUSERDATATAB';
var pstmt = dbCon.prepareStatement(query);
var rs = pstmt.executeQuery();
while (rs.next()) {
var vals = {}; // this is the moved line of code...
vals.team = rs.getString(1);
vals.fname = rs.getString(3);
vals.lname = rs.getString(2);
data.push(vals);
$.response.status = $.net.http.OK;
}
$.response.setBody(JSON.stringify(data));
// $.response.contentType = contentType;
// $.response.headers.set('Content-Disposition', 'filename=' + filename);
} catch (e) {
$.response.setBody('errors: ' + e.message);
}
}
solution above just in case someone needs it in future.
This is XSJS(server side JS) and not SAPUI5. The read of DB is pretty similar to the JDBC framework in Java to read DB tables and the result set collection will have the data and you iterate over them and move them to a local object.
There is only call to the DB during execute_query and rs.next() is just a loop to read each row.