Node.js DB2 query with parameters - javascript

I am using node.js to connect to a DB2 database and loading different queries. But I would like to use parameters from user input.
My connection string is:
var ibmdb = require("ibm_db")
, cn = "DATABASE=namedb;HOSTNAME=hst;UID=portal;PWD=portalpwd;PORT=50000;PROTOCOL=TCPIP;"
;
But my query is static, I need to pass parameters/variables from user input.
I am using user input with var rl = require('readline'); but the problem now is how to communicate variables to this query and put dynamic parameters not a single value like name, id etc.
var rows = conn.querySync(
"select name,id,uid,password,type from db21.rep_name fetch first 10 rows only"
);

The Node.js package ibm_db is fully documented. There are several ways you could solve the problem, depending on whether you want to have the async or sync version and whether you want to first prepare, then execute the statement.
The simplest option probably is to use querySync as already done by you. There is an optional parameter bindingParameters to pass in an array of values. Those are bound to all places having a ?. Something like the following should work.
var rows = conn.querySync(
"select name,id,uid,password,type from db21.rep_name where name=? fetch first 10 rows only", ['henrik']
);

Related

Node.js Firestore Query Select List of field paths

I try to create and returns a new Query instance that applies a field mask to the result and returns only the specified subset of fields.
When i use :
let query = firestore.collection('col').select('field1','field2','field3').get() ...
it's ok, the query returns all the collection documents with only the 3 specified fields.
In my context application, the specified fields list is on a configuration document. When i use :
let fieldsList = ['field1','field2','field3'];
let query = firestore.collection('col').select(fieldsList).get() ...
i have an error message "Argument at index 0 is not a valid FieldPath ..."
On the Google documentation, it is specified "You can specify a list of field paths to return"
So, i don't know how to pass a list of field paths to the query select method.
Many thanks for your help !!!
You are working on what is known as spread syntax.
To make it work, it need to add triple dots in front of fieldList:
let query = firestore.collection('col').select(...fieldsList).get() ..

Firebase realtime database : how to check if child value exists

Given the document below.
website:{
uid1:{
foo:"bar",
username:"joff"
},
uid2:{
foo:"bar2",
username:"karla"
}
}
I am trying to check if the username already exist using the query below.
var ref = db.ref('website');
var queryString = 'joff';
ref.orderByChild('username').equalTo(queryString).once('value', function(snap){
if(snap.exists()){
// exists
return
}
console.log('available');
})
This approach is working without a problem, if I change the queryString accordingly I get the result that I want if it exists or not.
Firebase's default query limit is 100 and I can change it to my liking according to the documentation.
But what if I will query though a let's say 10,000 documents? I cant use paginated query here, because what if the query match is on the 2nd page? How do I handle such amount of data? Will it take too long before it respond? What is the right approach to do such query.
PS
I strictly need the data model to be the same as the given above.
Thanks in advance.
I thought that use of equalTo generated a "smart" query, and so the query limit wouldn't be factor in determining if record exists. I'm not positive though. Have you actually verified that having more than 100 records, with your 'joff` being at 100+ in the ordering, results in no match?
If that is the case (which would be very surprising), then you could probably restructure your query something like this:
ref.orderByChild('username').startAt(queryString).endAt(queryString).once('value', function(snap){
if(snap.exists()){
// exists
return
}
console.log('available');
})
... but again, I don't think that is required when using equalTo.

Knex.js insert from select

I'm trying to generate a query like the following via Knex.js:
INSERT INTO table ("column1", "column2")
SELECT "someVal", 12345
WHERE NOT EXISTS (
SELECT 1
FROM table
WHERE "column2" = 12345
)
Basically, I want to insert values only if a particular value does not already exist. But Knex.js doesn't seem to know how to do this; if I call knex.insert() (with no values), it generates an "insert default values" query.
I tried the following:
pg.insert()
.into(tableName)
.select(_.values(data))
.whereNotExists(
pg.select(1)
.from(tableName)
.where(blah)
);
but that still just gives me the default values thing. I tried adding a .columns(Object.keys(data)) in hopes that insert() would honor that, but no luck.
Is it possible to generate the query I want with knex, or will I just have to build up a raw query, without Knex.js methods?
I believe the select needs to be passed into the insert:
pg.insert(knex.select().from("tableNameToSelectDataFrom")).into("tableToInsertInto");
Also in order to select constant values or expressions you'll need to use a knex.raw expression in the select:
knex.select(knex.raw("'someVal',12345")).from("tableName")
This is my first post and I didn't test your specific example but I've done similar things like what you're asking using the above techniques.
The most comprehensive answer I've found (with explicit column names for INSERT, and custom values in the SELECT-statement) is here:
https://github.com/knex/knex/issues/1056#issuecomment-156535234
by Chris Broome
here is a copy of that solution:
const query = knex
// this part generates this part of the
// query: INSERT "tablename" ("field1", "field2" ..)
.into(knex.raw('?? (??, ??)', ['tableOrders', 'field_user_id', 'email_field']))
// and here is the second part of the SQL with "SELECT"
.insert(function() {
this
.select(
'user_id', // select from column without alias
knex.raw('? AS ??', ['jdoe#gmail.com', 'email']), // select static value with alias
)
.from('users AS u')
.where('u.username', 'jdoe')
});
console.log(query.toString());
and the SQL-output:
insert into "orders" ("user_id", "email")
select "user_id", 'jdoe#gmail.com' AS "email"
from "users" as "u"
where "u"."username" = 'jdoe'
another one approach (by Knex developer): https://github.com/knex/knex/commit/e74f43cfe57ab27b02250948f8706d16c5d821b8#diff-cb48f4af7c014ca6a7a2008c9d280573R608 - also with knex.raw
I've managed to make it work in my project and it doesn't look all that bad!
.knex
.into(knex.raw('USER_ROLES (ORG_ID, USER_ID, ROLE_ID, ROLE_SOURCE, ROLE_COMPETENCE_ID)'))
.insert(builder => {
builder
.select([
1,
'CU.USER_ID',
'CR.ROLE_ID',
knex.raw(`'${ROLES.SOURCE_COMPETENCE}'`),
competenceId,
])
.from('COMPETENCE_USERS as CU')
.innerJoin('COMPETENCE_ROLES as CR', 'CU.COMPETENCE_ID', 'CR.COMPETENCE_ID')
.where('CU.COMPETENCE_ID', competenceId)
.where('CR.COMPETENCE_ID', competenceId);
Note that this doesn't seem to work properly with the returning clause on MSSQL (it's just being ignored by Knex) at the moment.

SuiteScript: How does the dynamic mode of nlobjColumn.setURL work?

In NetSuite, I have a scripted search of transactions that is expected to return results of several different transaction types. The results are then rendered in an nlobjList. I would like one of the columns of said list to be a link to the transaction that the list row represents.
In all NetSuite examples, this is accomplished something like:
var column = list.addColumn('number', 'text', 'Number', 'left');
column.setURL(nlapiResolveURL('RECORD','salesorder'));
column.addParamToURL('id','id', true);
Unfortunately, transaction is not an acceptable record type to pass to nlapiResolveURL, so I would need to dynamically detect the record type for each row. The setURL function does accept a second Boolean parameter that makes it dynamic per row, but I am not sure how this actually works. There are no examples, and the JSDocs do not explain its usage.
Does anyone have any guidance on generating a list with dynamic URLs in NetSuite?
If you set the dynamic argument to true, then the first argument should be a column listed in the data source that will contain the base URL.
column.setURL('base_url', true);
column.addParamToURL('id','id', true);
Then, on each record of your results, make sure you have a base_url that is set to the url you are looking for.
Note, the following example assumes a regular javascript object instead of the search result object.
rec.base_url = nlapiResolveURL('RECORD', rec.type)
Transaction field is just an abstraction for all transaction types. You can search them but can't load them.
The field you need to retrieve is recordtype. Sample code is below.
var recs = nlapiSearchRecord('transaction',null,null,new nlobjSearchColumn('recordtype'));
for(var i in recs)
url = nlapiResolveURL('RECORD',recs[i].getValue('recordtype'));

Trying to build a map/hashmap in javascript

I'm trying to run a query in javascript and pass the results to other querys to pull more data. I also want to be able to display this data all in one table so I'm trying to get the results arranged in a javascript map but I seem to be having issues.
This is being built inside of salesforce.com with their AJAX toolkit
The code I have is...
var cn = Query("select id, LastName, FirstName, Middle_Name__c, Gender__c, HomePhone, Birthdate, Birth_City__c," +
"Birth_Country__c, SSN_Encrypted__c, Provider_NPI_ID__c, Primary_Specialty__c," +
"Practicing_Specialty__c, Title, GlobalProviderID__c from contact where Name like " +
"'%" + sBox + "%'");
var PFA;
for (var i = 0; i < cn.length; i++) {
var x = new Array();
var PFA = Query("select id, First_Scheduled_Date__c, Region__c " +
"from Provider_Facility_Associations__c where Provider__c='" + cn[i].Id + "'");
m['cn'] = cn[i];
m['PFA'] = PFA;
m[i] = x;
}
console.log(m['cn']);
Any help would be greatly appreciated.
You can use a basic javascript object as a map.
So
var map = {};
map["key1"] ="value1"
map["key2"] = "value2"
will create an object like this:
map = {
key1:"value1",
key2:"value2"
}
When you pass an integer i to your m object it will try to treat it as an array though rather than an object.
You have deeper issues than this though since you should not be running SQL queries from javascript. That will allow anyone to run arbitrary queries on your database when accessing your website.
Please read up about how relationships work in Salesforce and their specific "joins" that look weird at the beginning but actually save your bacon many many times in common development situations like that.
SELECT Id, FirstName, LastName,
(SELECT Id, First_Scheduled_Date__c, Region__c
FROM Provider_Facility_Associations__r)
FROM contact
WHERE Name LIKE '%Smith%'
(note the "__r" in the "subquery")
This will give you Contacts and each of them will have a "field" called Provider_Facility_Associations__r that will be an array of items (or just empty array if nothing found).
Salesforce security model is not a silver bullet, you should worry about performance and SQL injections. People can't use them to delete stuff they shouldn't but they can learn information you didn't intend to expose.
Last but not least - this will perform better and be more secure if you'd have the query server side and just pass the variable (part of contact's name) there. This can be apex exposed as webservice or if you're in Visualforce - action function, JavaScript remoting... There are plenty of options!
I'm not saying the AJAX toolkit is an abomination... But it should be used very rarely if at all. It's an artifact from so-called SControl days and with introduction of Visualforce (hmm... 4 years now?) many of it's use cases can be done faster & in more secure way.
Running SQL from JS is a bad idea usually unless you are using a sql-lite localstorage engine of some sort. Anyways, I believe your problem may be that your m's and x's are mixed up. Also, running queries in a for loop where using an IN in the second query or a JOIN and just doing one query would probably be better.

Categories

Resources