when i use this the command inside oracle´s sqldeveloper:
SELECT systimestamp FROM dual;
i get an output in this format:
09-DEC-22 12.36.55.179000000 AM -03:00
but when i use the same command with node-oracle-db i get the output in this format:
2022-12-09T04:17:23.545Z
And i would like to get the same kind of output i get using sqldeveloper
this is my code:
const oracledb = require('oracledb')
const dbCredentials = {
user: "user",
password: "password",
connectString: "localhost:1521/xe",
};
async function timeget(dbConfig) {
let connection;
try {
connection = await oracledb.getConnection(dbConfig);
const result = await connection.execute
(
`SELECT systimestamp FROM dual`,
)
console.log(result.rows)
connection.commit();
return res1
} catch (err) {
console.error(err);
} finally {
if (connection) {
try {
await connection.close();
} catch (err) {
console.error(err);
}
}
}
}
timeget(dbcredentials);
Change the SQL statement in your node.js code to output the timestamp as a formatted string:
SELECT TO_CHAR(
SYSTIMESTAMP,
'DD-MON-RR HH12.MI.SS.FF9 AM TZH:TZM',
'NLS_DATE_LANGUAGE=English'
) AS formatted_timestamp
FROM DUAL
Alternatively, read the Node.js documentation on date handling and fetch the timestamp as a string.
The documentation states (I have not tested it) that you can set this before opening the connection:
oracledb.fetchAsString = [ oracledb.DATE ];
to fetch all dates as strings or set the fetch info within the query:
const result = await connection.execute(
'SELECT systimestamp AS time FROM dual',
[],
{fetchInfo: {'TIME': {type: oracledb.STRING}}}
)
Related
I have multiple tables in Google Cloud Spanner with columns of type Date. Inserting entries with specified dates is not a problem, and reflects appropriately in the database. However, retrieving entries from the database into the Javascript frontend is where the issue lies. I can't seem to figure out in which format these date fields are.
My (Google Cloud Functions) code retrieves a customer from the database as follows:
async function fetch(database, query) {
query.json = true;
try {
const [rows] = await database.run(query);
return rows;
} catch (error) {
console.error("ERROR:", error);
throw error;
} finally {
database.close();
}
}
exports.fetchCustomer = functions.https.onCall(async (data, context) => {
const database = instance.database(data.dataset);
let address = fetch(database, {
sql: `SELECT * FROM addresses WHERE addressId = '${data.id}'`,
});
let customer = fetch(database, {
sql: `SELECT * FROM customers WHERE customerId = '${data.id}'`,
});
try {
[address, customer] =
await Promise.all([address, customer]);
return [address[0], customer[0]];
} catch (error) {
console.error("ERROR:", error);
throw error;
}
});
On the front-end side, I have:
const fetchCustomer = httpsCallable(firebaseFunctions, 'fetchCustomer');
await fetchCustomer({dataset: this.dataset, id: this.customerId})
.then((res) => {
this.address = res.data[0];
this.customer = res.data[1];
}
The object this.customer then has a property dateOfBirth which seems to be an infinitely nested object, which I can't make sense of. How can I convert that property to a String with the format 'yyyy-mm-dd' or any other appropriate date format?
Any advice or information on the matter would be appreciated. Thanks in advance!
This sample has an example (https://cloud.google.com/spanner/docs/samples/spanner-query-with-date-parameter#spanner_query_with_date_parameter-nodejs):
rows.forEach(row => {
const date = row[2]['value'];
const json = row.toJSON();
console.log(
`VenueId: ${json.VenueId}, VenueName: ${json.VenueName},` +
` LastContactDate: ${JSON.stringify(date).substring(1, 11)}`
); });
I'm trying to update the document but the error says the query has already been executed.
MongooseError: Query was already executed: footballs.updateOne({ date: 'January 4' }, {})
app.post('/api/bookslot', async (req, res) => {
console.log(req.body);
try {
const token = req.headers['x-access-token'];
const decoded = jwt.verify(token, 'secret123');
const email = decoded.email;
const user = await UserModel.findOne({ email: email });
let sportname = req.body.selectedSport.toLowerCase();
const time = req.body.slotTime;
const seats = req.body.availableSeats - 1;
if (!sportname.endsWith('s')) {
sportname = sportname.concat('s');
}
const NewSlotModel = mongoose.model(sportname, slotSchema);
var update = {};
update[time] = seats - 1;
console.log(update);
const a = await NewSlotModel.updateOne(
{ date: req.body.slotDate },
{ $set: update },
function (err, success) {
if (err) return handleError(err);
}
);
return res.json({ status: 'ok' });
} catch (e) {
console.log(e);
res.json({ status: 'error' });
}
});
where am I going wrong?
You are using both async/await and callbacks in your code, causing mongoose to throw an error.
The actual effect of using them both is exactly the error type that you are receiving:
Query was already executed
Mongoose v6 does not allow duplicate queries.
Mongoose no longer allows executing the same query object twice. If
you do, you'll get a Query was already executed error. Executing the
same query instance twice is typically indicative of mixing callbacks
and promises, but if you need to execute the same query twice, you can
call Query#clone() to clone the query and re-execute it. See gh-7398
Duplicate Query Execution
To fix the issue, just remove the third argument from the await
NewSlotModel.updateOne
Making it:
const a = await NewSlotModel.updateOne(
{ date: req.body.slotDate },
{ $set: update }
);
Mongoose v6. Don't support callbacks any longer.. check the image.
const productCount = await Product.countDocuments((count) => count) BAD
const productCount = await Product.countDocuments(); GOOD
I am stuck at my problem because I am really new to oracle-db for node-js and JavaScript in general.
I wrote API-endpoints with JavaScript and each endpoint does an oracledb “select query”. However, my colleagues need only one endpoint which gives all results of all oracle select-queries as one JSON object. All queries are dependent on the first query, i.e. the result of the first query has to be used as a bind-parameter for the second query and so forth.
In this js-file I tried to execute two oracle-sql queries (one after the other) and use one value of the result-JSON-object of the first query as a parameter for the second query and give all results as response for the API client. But that does not work. What am I doing wrong here? With only one sql and therefore only one result it works. Thanks in advance!
Here is my code I wrote:
const oracledb = require('oracledb');
const config = require('../config/config')
oracledb.autoCommit = true
oracledb.fetchAsString = [ oracledb.DATE, oracledb.NUMBER ]
module.exports= async (req, res) => {
let connection;
try {
var sql, binds, options, result, result2, time
connection = await oracledb.getConnection(config.oracledbconnection)
// Query the data
sql = `SELECT FIRSTNr, SECONDNR,STARTTIME,MACHINE FROM MACHINELOGS WHERE Machine=:Machine AND ENDTIME > CURRENT_DATE -1 ORDER BY RUNNO ASC`;
binds = {Machine:req.params.machine}
options = {
outFormat: oracledb.OUT_FORMAT_OBJECT // query result format
//outFormat: oracledb.OBJECT // is the same as above // extendedMetaData: true, // get extra metadata
// prefetchRows: 100, // internal buffer allocation size for tuning
// fetchArraySize: 100 //internal buffer allocation size for tuning
};
result = await connection.execute(sql, binds, options);
// console.log("Metadata: ");
// console.dir(result.metaData, { depth: null });
// console.log("Query results: ");
// console.dir(result.rows, { depth: null });
//
// Show the date. The value of ORA_SDZT affects the output
sql = `SELECT TO_CHAR(CURRENT_DATE, 'DD-Mon-YYYY HH24:MI') AS CD FROM DUAL`;
time = await connection.execute(sql, binds, options);
// console.log("Current date query results: ");
// console.log(result2.rows[0]['CD']);
sql = `SELECT GRADE FROM NOTES WHERE SECONDNR=:Secondnr`
binds = {Secondnr:result.rows[0]['SECONDNR']}
result2 = await connection.execute(sql,binds,options);
options = {
outFormat: oracledb.OUT_FORMAT_OBJECT //
};
}
catch (err)
{
console.error(err);
}
finally
{
if (connection)
{
try {
await connection.close();
}
catch (err) {
console.error(err);
}
}
}
res.send(result,result2)
}
Take it back to basics. This works:
'use strict';
process.env.ORA_SDTZ = 'UTC';
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
if (process.platform === 'darwin') {
oracledb.initOracleClient({libDir: process.env.HOME + '/Downloads/instantclient_19_8'});
}
let sql, options, result1, result2;
options = { outFormat: oracledb.OUT_FORMAT_OBJECT };
async function run() {
let connection;
try {
connection = await oracledb.getConnection(dbConfig);
result1 = await connection.execute(
`select 1 as myval from dual`,
[], options);
console.dir(result1.rows, { depth: null });
result2 = await connection.execute(
`select sysdate from dual where 1 = :bv`,
{bv: result1.rows[0].MYVAL},
options);
console.dir(result2, { depth: null });
} catch (err) {
console.error(err);
} finally {
if (connection) {
try {
await connection.close();
} catch (err) {
console.error(err);
}
}
}
}
run();
Then try with your datatypes.
I'm not sure what you want to do with returning 'all results'. You can build up any JS object and convert to and from JSON easily with JSON.stringify and JSON.parse.
For efficiency, you could review whether you can do all your 'queries' in a single SQL statement.
I'm trying to run an aggregation query in Mongo using their nodejs driver, that takes some of my fields and adds/finds averages etc. I built the aggregation in Mongo Cloud and exported it to node, but when I run the code, I get the following responses from Mongo:
this.res could not be serialized.
steps.update_mongo.res:null
Here's the code (history field is an array of objects):
const agg = [
{
'$addFields': {
'avgGrowth': {
'$ceil': {
'$avg': '$history.growth'
}
},
'avgDecline': {
'$ceil': {
'$avg': '$history.decline'
}
}
}
},
{
'$merge': {
'into': {'db':'mydb', 'coll':'test'},
'on': '$_id'
},
}
];
const coll = await db.collection('test');
this.res = await coll.aggregate(agg, async(cmdErr, result) => {
await assert.equal(null, cmdErr);
});
this.res = await coll.aggregate(agg, async(cmdErr, result) => {
await assert.equal(null, cmdErr);
});
Is an incorrect syntax. You either provide a callback OR use await, not both.
Try using is as follow :
this.res = await coll.aggregate(agg);
Im using v6.3.1 of node mssql.
My query includes multiple columns of the type date.
In node mssql the output of all Date columns are in the format: 2020-10-20T00:00:00.000Z
When I make the same query in Azure Data Studio I get: 2020-10-20
My problem is when I need to update the database as I get an error using the YYYY-MM-DD format.
is there a way to update the database without having to check each field if its a date and then add "0T00:00:00.000Z" to it?
Current code is this:
// Runs at server startup
const sql = require('mssql')
const poolPromise = sql.connect({
server: process.env.SQL_SERVER,
user: process.env.SQL_USER,
password: process.env.SQL_PASSWORD,
database: process.env.SQL_DATABASE
})
// Runs at query
async function updateSqlRecord(fields) {
// Adding fields below for demonstration
let fields = {id: 1, name: 'test', date: '2020-10-12' }
let database = process.env.SQL_DATABASE
let table = 'Test'
let querystring = `UPDATE [${database}].[dbo].[${table}] SET `
Object.entries(fields).forEach(field => {
const [key, value] = field;
querystring += `${key} = '${value}', `
});
querystring = querystring.slice(0, -2)
querystring += ` WHERE projektNr = ${fields.projektNr}`
try {
let pool = await poolPromise
let result = await pool.request()
// .input('projektNr', sql.Int, value)
.query(querystring)
console.log(result)
return result.rowsAffected
} catch (err) {
console.log('SQL request Error',err)
}
}
If possible you could try to use moment.js to parse the date before adding it to the database
var moment = require('moment');
...
var formatedDate = moment(myDate).format('YYYY/MM/DD HH:MM:SS').toISOString();