Passing sort order as a parameter - javascript

Referring to the sample SQL statement below. I'm able to pass parameter values to the placeholder '?' in the statement. However I'm wondering whether it is possible to pass in the sort order in the same way?
So instead of this:
//Create SQL query
var getAccountsTransactionsStatement = WL.Server.createSQLStatement(
"SELECT transactionId, fromAccount, toAccount, transactionDate, transactionAmount, transactionType " +
"FROM accounttransactions " +
"WHERE accounttransactions.fromAccount = ? OR accounttransactions.toAccount = ? " +
"ORDER BY transactionDate DESC " +
"LIMIT 20;"
);
Can I have this:
//Create SQL query
var getAccountsTransactionsStatement = WL.Server.createSQLStatement(
"SELECT transactionId, fromAccount, toAccount, transactionDate, transactionAmount, transactionType " +
"FROM accounttransactions " +
"WHERE accounttransactions.fromAccount = ? OR accounttransactions.toAccount = ? " +
"ORDER BY ? DESC " +
"LIMIT 20;"
);
And to invoke it:
//Invoke prepared SQL query and return invocation result
function getAccountTransactions1(accountId){
return WL.Server.invokeSQLStatement({
preparedStatement : getAccountsTransactionsStatement,
parameters : [accountId, accountId, transactionDate]
});
}

Two things:
This query piece:
WHERE accounttransactions.fromAccount = ? OR accounttransactions.toAccount = ?
Could be replaced with this:
WHERE ? in (accounttransactions.fromAccount, accounttransactions.toAccount)
No you can't. Parameters are values - kind of static stuff - while column names are not. You could probably work around the issue somehow in limited way by using s.t. like this:
ORDER BY
CASE ?
WHEN 'transactionDate' THEN transactionDate
WHEN 'someotherdate' THEN someotherdate
ELSE DATE '2010-01-01'
END
Note however that's a messy construction. Also depending on the type of the database you're using you might want to cast all the columns into one data type i.e. string. so to_char(transactionDate,'yyyy-mm-dd hh24:mm:ss') might be in order but you need to ensure that the sorting is proper in your case (as number tend to mess stuff up like '2' > '13').

Related

Two similar SQLite case statements, one works, the other does not

The first statement works, the second comes back with the error below. The strange thing is except for variable names, they are the same statement, so if one works, the other should work as well.
"Error: SQLITE_ERROR: no such column: RAF60"
Where RAF60 is my data. I thought that I may have a quote in the wrong place as it's trying to read my data as a column but can't see it, also looked for somewhere I may have swapped my data with an expression, but could not see that either.
The RFID1,2,3 and the CarPlates1,2,3 are formatted as text
Statement one exactly as it appears below.
msg.topic = 'SELECT "RFID1", "RFID2", "RFID3", case when "RFID1" = ' + readrfid + ' then RFID1 when "RFID2" = ' + readrfid + ' then RFID2 when "RFID3" = ' + readrfid + ' then RFID3 else null end dbrfid FROM SiteDB'
The output below from Node-Red, I reformatted it to make it easily readable. It shows that the data is populating the right fields and this code works. Its the above statement with the data inserted, just prior to being sent to SQLite
topic:
"SELECT "RFID1", "RFID2", "RFID3", case
when "RFID1" = 149544749819338 then RFID1
when "RFID2" = 149544749819338 then RFID2
when "RFID3" = 149544749819338 then RFID3
else null
end dbrfid FROM SiteDB"
payload: "149544749819338"
_msgid: "232263a1.02d34c"
_event: "node:ad044b82.8c419
0: object
Statement two, the sql query exactly as it appears below
msg.topic = 'SELECT "CarPlate1", "CarPlate2", "CarPlate3", "dbcarplate", case when "CarPlate1" = ' + readlpr + ' then CarPlate1 when "CarPlate2" = ' + readlpr + ' then CarPlate2 when "CarPlate3" = ' + readlpr + ' then CarPlate3 else null end dbcarplate FROM SiteDB
The output below from Node-Red, I reformatted it to make it easily readable. It also shows that the data is populating the right fields, but comes back with an error message, the statement below is the data just before its sent to SQLite
topic: "SELECT "CarPlate1", "CarPlate2", "CarPlate3", "dbcarplate", case
when "CarPlate1" = RAF60 then CarPlate1
when "CarPlate2" = RAF60 then CarPlate2
when "CarPlate3" = RAF60 then CarPlate3
else null
end dbcarplate FROM SiteDB"
payload: " RAF60 "
_msgid: "f2831f05.42c24"
_event: "node:61abb27f.bc684c"
It does not run in SQLite, and I get the error message.
"Error: SQLITE_ERROR: no such column: RAF60"

Sql dynamic query syntax error

This is my sql query
"select * from applicant where email =ABC.Com"
I want table name, colum name and value after where clause dynamic in form of variables there. Can you tell me the right syntax? I have tried this so far
"select * from " tableNameVariable+"where "columnNameVariable+"= "inputedEmailVariable
now this query is giving an error near =inputedEmailVariable.
Note : I want to use this string in nodejs function. Please tell me right syntax?
Try:
"select * from " + tableNameVariable + " where " + columnNameVariable + " = '" + inputedEmailVariable + "'"
You're missing some + operators, and also missing a space before where.
var sql = "select * from " + tableNameVariable + " where " + columnNameVariable + " = " + inputedEmailVariable
You should be very careful if the variables are coming from user input, since this can result in SQL injection. Make sure the variables contain table and column values that they're allowed to access.
And if you're compareing the column with a string, you'll need quotes around the string. But it would be better to use a placeholder at that point, rather than concatenating the variable.

JS: how to filter table using variable

I have a function that I need to use for filtering table rows:
setFilterString("Filter");
But I have a problem. I can set it to
setFilterString("OrderID = 5");
and it will filter out row where OrderID is equal to 5 but if i try using a variable that has a value taken before like this
setFilterString("OrderID = vOrderID");
I get error "Invalid column name 'vOrderID'." (as vOrderID is variable and not a column, I guess)
I have seen somewhere in filter section inputting something like this ("OrderID = '" & vOrderID & "'") but it doesn't have any result at all for me. Doesn't even throw any error in the console.
JavaScript assumes you are just passing a string to the function. If you want to use the variable, you should try this:
setFilterString("OrderID = '" + vOrderID + "'"); // Results in OrderID = '5'
or
setFilterString("OrderID = " + vOrderID); // Results in OrderID = 5
depending on the body of your function.
Use + instead of &: setFilterString("OrderID = " + vOrderID) should work.
Use "+" for merge strings:
setFilterString("OrderID = " + vOrderID)
You can also try to use ${idvOrderID} inside string:
setFilterString("OrderID = ${vOrderID}")
Or:
setFilterString(sprintf("OrderID = %s", vOrderID))
Remember about difference between ' and "

BIRT report optional parameter script

I am using SpagoBI, and I am trying to create report with optional parameter. I have problem with beforeOpen() script. Here is the query.
select C."CUSTOMERNAME", C."CITY", D."YEAR", P."NAME"
from "CUSTOMER" C, "DAY" D, "PRODUCT" P, "TRANSACTIONS" T
where C."CUSTOMERID" = T."CUSTOMERID"
and D."DAYID" = T."DAYID"
and P."PRODUCTID" = T."PRODUCTID"
and C."REGION" in (?)
and the script
if (params["cityparam"].value != null){
this.queryText = this.queryText + "and C.\"CITY\" in ( ?,'" +params["cityparam"].value + "')";
}
else{
var str = reportContext.getParameterValue("regionparam");
q3 = this.queryText + "and C.\"CITY\" in (?,( select \"CUSTOMER\".\"CITY\" from \"CUSTOMER\" where \"CUSTOMER\".\"REGION\" in ('"+ str +"')))";
this.queryText =q3;
}
I have 2 parameters, regionparam and cityparam the second one is optional. I am trying to modify the query in this way, that when cityparam isn't set, I am comparing C."CITY" to all it's possible values in selected region. The generated query works in my PGadmin. But there are problems in SpagoBI studio. It's says:
Subquery returned more than 1 value. This is not permitted
Is there any BIRT master? I would be greatfull for help. Thanks.
Here is a technique I'm using for handling optional parameters for BIRT reports in SpagoBI. By rewriting the query, we can utilize a single query without modifying it based on parameter values.
Steps
Rewrite the query so that optional parameters may be null OR the database field is equal to some value. For every optional parameter, you'll have two '?' in the query. The first test is against null and the second test is a test for a value to match a field. For required parameters, you'll still only have one '?' in the query.
In the BIRT Data Set's parameters, for optional parameters, define two matching named parameters to correspond to the first and second '?' in the query for that parameter. Required parameters will only have 1 named parameter mapping to them.
Below are simplified samples from an existing report.
Example SQL query (SQLServer) with three optional parameters for user status, last login, and role
SELECT
ar.role_name,
au.user_id,
au.Lname,
au.FName,
au.Email,
au.Last_Login,
au.status,
au.Creation_Date
FROM account_user au WITH (NOLOCK)
INNER JOIN account_role ar WITH (NOLOCK)
ON ar.account_id = au.account_id
AND ar.role_id = au.role_id
WHERE au.account_id = 9999
AND ( (? IS NULL) OR (AU.status = ?) )
AND ( (? IS NULL) OR (AU.last_login <= ?) )
AND ( (? is null) OR (ar.role_id = ?))
ORDER BY role_name, Lname, Fname
Here is what the BIRT Data Set's Parameters look like, for three optional parameters.
Once again I managed to solve my problem. :)
First of all delete You'r optional parameter from data set. We' ll be setting it inside our beforeOpen() script.
Here's my query
select C."CUSTOMERNAME", C."CITY", D."YEAR", P."NAME"
from "CUSTOMER" C, "DAY" D, "PRODUCT" P, "TRANSACTIONS" T
where C."CUSTOMERID" = T."CUSTOMERID"
and D."DAYID" = T."DAYID"
and P."PRODUCTID" = T."PRODUCTID"
and script
if (params["cityparam"].value != null){
this.queryText = this.queryText +"and C.\"REGION\" in (?, '" + params["regionparam"].value + "' ) "
+ "and C.\"CITY\" in ( '" + params["cityparam"].value + "')";
}
else{
var str = reportContext.getParameterValue("regionparam");
this.queryText = this.queryText +"and C.\"REGION\" in (?, '" + params["regionparam"].value + "' ) "
+ "and C.\"CITY\" in (select \"CUSTOMER\".\"CITY\" from \"CUSTOMER\" where \"CUSTOMER\".\"REGION\" in ('"+ str +"'))";
}
As You can see the "?" is necessary only when parameter is declared in data set.
Without it We can compare single row to more than 1 values returned from subquery.

How to use IN with a query parameter?

I have a query like this.
SELECT * FROM player_details where name in ('messi','neymar','suarez','alves')
I want to execute this query in titanium.
I tried like this
var in = ['messi','neymar','suarez','alves'];
db.execute('SELECT * FROM player_details where name in ?',in);
But above code producing error.
How can i add IN and NOT IN condition in sqlite in titanium ?
A single parameter ? replaces a single expression.
When you have four values, you need four parameters:
db.execute('SELECT * FROM player_details where name in (?,?,?,?)', in);
If the length of the array is dynamic try something like this:
var params = ["messi", "neymar", "suarez", "alves"],
qMarks = new Array(params.length).join("?,") + "?";
db.execute("SELECT * FROM player_details WHERE name in (" + qMarks + ");", params);

Categories