Write SELECT CASE Statement with PostgreSQL pg and Node JS - sql

I am using a RESTful API with Node.js/Express and a PostgreSQL database ( PostgreSQL version is 12.4). I'm not using an ORM just straight SQL. I am trying to create a "SELECT CASE" statement but I keep running into errors. The error messages I am getting are "confirmed_member is not a column". Can anyone see what is wrong with my syntax here:
var query = ['SELECT *, CASE WHEN confirmed = true THEN "confirmed_member" ELSE "pending" END AS "status" FROM members WHERE groupid = $1']
try {
const member = await pool.query(query, [groupid]);
res.status(200).json(member.rows)
} catch (err) {
res.status(400).json({ message: err.message })
}
Note: The query works fine in Valentina DB.
EDIT: In response to answers below, I switched to double quotes because this was the error I was getting in the IDE when I used single quotes

Use single quotes for string literals in SQL. Some flavors of SQL (e.g. SQLite) also accept double quotes, but you should not rely on this behavior.
var query = ["SELECT *, CASE WHEN confirmed = true THEN 'confirmed_member' ELSE 'pending' END AS status FROM members WHERE groupid = $1"];

You need to use single quote for the literals as follows:
SELECT *,
CASE WHEN confirmed = true THEN 'confirmed_member' ELSE 'pending' END AS "status"
FROM members WHERE groupid = $1

For anyone who comes across the same issue: I got it working by enclosing the SQL statement in double quotes and escaping the double quotes for the column name.
var query = ["SELECT *, CASE WHEN confirmed = true THEN 'confirmed_member' ELSE 'pending' END AS \"status\" FROM members WHERE groupid = $1"]

Related

LINQ generating wrong SQL for empty string

I have the following code:
var approver = _context.approver.Where(x => x.ApproverName != "").Select(x => x.ApproverUserId).Distinct();
And the generated SQL is
SELECT DISTINCT "x"."approveruserid"
FROM "approver" "x"
WHERE (("x"."approvername" <> '') OR "x"."approvername" IS NULL )
I'm expecting the SQL should be
SELECT DISTINCT "x"."approveruserid"
FROM "approver" "x"
WHERE (("x"."approvername" <> '') OR "x"."approvername" IS NOT NULL )
So, the generated SQL is missing the NOT clause and this causes to return wrong result. By the way, I'm using Oracle Database. In Oracle, null equals to empty string.
How to fix it?
[UPDATE]: I'm using
var approver = _context.approver.Where(x => x.ApproverName.Length > 0).Select(x => x.ApproverUserId).Distinct();
as a workaround. But I'm open to another suggestion that can generate the SQL properly for empty string checking.
The generated SQL is correct. You are asking for the string to be something other than "", and null != "".
String.IsNullOrEmpty() is not supported by Linq to SQL but your workaround works fine.
Alternatively you can use something like this:
_context.approver.Where(x => (x.ApproverName ?? "" ) != "")

Ruby PG conn.exec_params SQL structure

I'm getting an error on a simple statement through PG:
require 'pg'
conn = PG.connect( dbname: 'myDB' )
#res = conn.exec_params( 'SELECT count(id) FROM users WHERE username = $1 AND status = "active"', ['johnny5'] )
The error:
/Users/rich/app.rb:14:in `exec_params': ERROR: column "active" does not exist (PG::UndefinedColumn)
LINE 1: ...unt(id) FROM users WHERE username = $1 AND status = "active"
^
"active" is a field value, not a column.
My question: I have fixed this by entering the value "active" as another placeholder. Are quoted values in the SQL not permitted? I assumed that quoted aspects of the SQL would have been fine.
String literals in SQL use sigle quotes, double quotes are for identifiers (such as table and column names). So, when you mention "active", the database complains that there is no such column.
The solution is to use a placeholder:
#res = conn.exec_params(
%q{SELECT count(id) FROM users WHERE username = $1 AND status = $2},
['johnny5', 'active']
)
or use single quotes inside the SQL:
#res = conn.exec_params(
%q{SELECT count(id) FROM users WHERE username = $1 AND status = 'active'},
['johnny5']
)
Switching from '...' to %q{...} for your SQL string literal makes the internal quoting problems a bit easier to deal with.

Multiple parameter values

I have a problem with BIRT when I try to pass multiple values from report parameter.
I'm using BIRT 2.6.2 and eclipse.
I'm trying to put multiple values from cascading parameter group last parameter "JDSuser". The parameter is allowed to have multiple values and I'm using list box.
In order to be able to do that I'm writing my sql query with where-in statement where I replace text with javascript. Otherwise BIRT sql can't get multiple values from report parameter.
My sql query is
select jamacomment.createdDate, jamacomment.scopeId,
jamacomment.commentText, jamacomment.documentId,
jamacomment.highlightQuote, jamacomment.organizationId,
jamacomment.userId,
organization.id, organization.name,
userbase.id, userbase.firstName, userbase.lastName,
userbase.organization, userbase.userName,
document.id, document.name, document.description,
user_role.userId, user_role.roleId,
role.id, role.name
from jamacomment jamacomment left join
userbase on userbase.id=jamacomment.userId
left join organization on
organization.id=jamacomment.organizationId
left join document on
document.id=jamacomment.documentId
left join user_role on
user_role.userId=userbase.id
right join role on
role.id=user_role.roleId
where jamacomment.scopeId=11
and role.name in ( 'sample grupa' )
and userbase.userName in ( 'sample' )
and my javascript code for that dataset on beforeOpen state is:
if( params["JDSuser"].value[0] != "(All Users)" ){
this.queryText=this.queryText.replaceAll('sample grupa', params["JDSgroup"]);
var users = params["JDSuser"];
//var userquery = "'";
var userquery = userquery + users.join("', '");
//userquery = userquery + "'";
this.queryText=this.queryText.replaceAll('sample', userquery);
}
I tryed many different quote variations, with this one I get no error messages, but if I choose 1 value, I get no data from database, but if I choose at least 2 values, I get the last chosen value data.
If I uncomment one of those additional quote script lines, then I get syntax error like this:
The following items have errors:
Table (id = 597):
+ An exception occurred during processing. Please see the following message for details: Failed to prepare the query execution for the
data set: Organization Cannot get the result set metadata.
org.eclipse.birt.report.data.oda.jdbc.JDBCException: SQL statement does not return a ResultSet object. SQL error #1:You have an error in
your SQL syntax; check the manual that corresponds to your MySQL
server version for the right syntax to use near 'rudolfs.sviklis',
'sample' )' at line 25 ;
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to
your MySQL server version for the right syntax to use near
'rudolfs.sviklis', 'sample' )' at line 25
Also, I should tell you that i'm doing this by looking from working example. Everything is the same, the previous code resulted to the same syntax error, I changed it to this script which does the same.
The example is available here:
http://developer.actuate.com/community/forum/index.php?/files/file/593-default-value-all-with-multi-select-parsmeter/
If someone could give me at least a clue to what I should do that would be great.
You should always use the value property of a parameter, i.e.:
var users = params["JDSuser"].value;
It is not necessary to surround "userquery" with quotes because these quotes are already put in the SQL query arround 'sample'. Furthermore there is a mistake because userquery is not yet defined at line:
var userquery = userquery + users.join("', '");
This might introduce a string such "null" in your query. Therefore remove all references to userquery variable, just use this expression at the end:
this.queryText=this.queryText.replaceAll('sample', users.join("','"));
Notice i removed the blank space in the join expression. Finally once it works finely, you probably need to make your report input more robust by testing if the value is null:
if( params["JDSuser"].value!=null && params["JDSuser"].value[0] != "(All Users)" ){
//Do stuff...
}

JSON Parser Has Issue With Sql Syntax But Query Works

To start, I had this error:
Error parsing data org.json.JSONException: Value You of type java.lang.String cannot be converted to JSONObject
After some searching, I found a potential solution using substring to see if there were just some phantom characters causing an issue: 'json.substring(3)'
After trying different substring amounts, I got to json.substring(36) and it finally showed me more than 5 letters at a time:
Error parsing data org.json.JSONException: Expected literal value at character 0 of ; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AND from_user = 277976949048048 AND (status = 'pending' OR status = 'accepted'))' at line 2
Maybe this new 'expected literal' thing is caused by doing the substring 36, but either way, it seems like there is an issue with my SQL syntax even though I tested it directly with the server and it works perfectly. here is my sql query.
$result = mysql_query("SELECT status FROM users join requests on users.facebook_id=requests.from_user
WHERE (to_user = $id AND from_user = $fbid AND (status = 'pending' OR status = 'accepted'))
OR (from_user = $id AND to_user = $fbid AND (status = 'pending' OR status = 'accepted'))
LIMIT 1") or die(mysql_error());
Any help much appreciated because now I'm officially stumped.
I had some issues in the past with parsing JSON files including huge integer numbers.
The number 277976949048048 seems too large to be treated as an integer, I would suggest treating it as a string.

dynamically set the db in a sql query

I try to run the same query in several dbs in mysql:
def m='xxx'
def dbs = ['DB05DEC05','DB06DEC06','DB07DEC07','DB08DEC08','DB09DEC09','DB10DEC10']
def sql =Sql.newInstance("jdbc:mysql://localhost:3306", "root","", "org.gjt.mm.mysql.Driver")
dbs.each{
db-> sql.eachRow("select * from ${db}.mail where mid=$m", { println "\t$db ${it.mid}"} );
}
This gives an error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''DBJAN05DEC05'.mail where mid='xxx'
Groovy apparently does some custom stuff with quotes and asks you not to use quotes in the sql (notice mid=$m, if you use mid='$m' it warns you against using the quotes).
The problem is that in the first $ I dont know want quotes at all, the quotes are the problem...
groovy 1.7 on vista.
thanks
editing: I have found a similar question, but it does not have an accepted answer either... Groovy GString issues
The problem is that the SQL query method sees the GString, with its embedded variable references, and turns each reference into a ? in a prepared statement.
So:
sql.query("select * from table where col = ${value}")
... is equivalent to:
sql.query("select * from table where col = ?", [ value ])
But also:
sql.query("select * from ${db}.table where col = ${value}")
is equivalent to:
sql.query("select * from ?.table where col = ?", [ db, value ])
... which fails at the DB layer because the select statement is not valid.
The obvious workaround is to use the explicit prepared statement version of query().
dbs.each{ db->
sql.eachRow("select * from ${db}.mail where mid=?", m, {
println "\t$db ${it.mid}"
});
}
However, the Sql class gives you an expand() method, that appears to be designed for this purpose.
dbs.each{ db ->
sql.eachRow(
"select * from ${Sql.expand(db)}.mail where mid=${m}",
{ println "\t$db ${it.mid}"} );
}