PetaPoco query complaining about incorrect order by syntax - petapoco

Given this seemingly easy query:
var sql = Sql.Builder
.Append("SELECT * FROM Log")
.Append("WHERE ApplicationId=#0", 1)
.Append("ORDER BY #0 #1", "Timestamp", "ASC");
return _db.Page<Log>(1, 25, sql);
Incorrect syntax near '#2'. (#2 ends up evaluating to #1 in the last append)
What am I doing wrong?

The problem is in .Append("ORDER BY #0 #1", "Timestamp", "ASC"); because Timestamp and ASC are being interpreted as params.
You will need to concatenate the string there:
.Append(String.Format("ORDER BY {0} {1}", "Timestamp", "ASC"));
BEWARE that this it's a possible sql injection attack vector. Sanitize your inputs.

Related

Apache Calcite Fails to Parse Its Own Google BigQuery Output

I'm new to Apache Calcite and am running into a strange "gap" - given a simple select query:
select * from orders
I parse it using:
SqlParser.Config sqlParserConfig = SqlParser
.configBuilder()
.setConformance(SqlConformanceEnum.LENIENT)
.build();
SqlParser parser = SqlParser.create(sqlQuery, sqlParserConfig);
SqlNode parseAst = parser.parseQuery();
CalciteCatalogReader catalogReader = buildCatalogReader(schema, typeFactory);
SqlValidator.Config validatorConf = SqlValidator.Config.DEFAULT.withSqlConformance(SqlConformanceEnum.BIG_QUERY);
validatorConf = validatorConf.withIdentifierExpansion(true);
SqlValidator validator = SqlValidatorUtil.newValidator(SqlStdOperatorTable.instance(),
catalogReader, typeFactory,
validatorConf)
validator.validate(parseAst).toSqlString(BigQuerySqlDialect.DEFAULT).toString();
Which results in:
SELECT ORDERS.o_orderkey, ORDERS.o_custkey, ORDERS.o_orderstatus, ORDERS.o_totalprice, ORDERS.`o_order date`, ORDERS.o_orderpriority, ORDERS.o_clerk, ORDERS.o_shippriority, ORDERS.o_comment
FROM ORDERS AS ORDERS
(reasonable, note the quoted identifier for `o_order date`, necessary due to whitespace in columnname)
If I then take that query string and pass it back through (setting conformance to SqlConformanceEnum.BIG_QUERY) the parse fails with:
org.apache.calcite.sql.parser.SqlParseException: Lexical error at line 1, column 95. Encountered: "`" (96), after : ""
Puzzling on face, I tried again with a parse config:
SqlParser.Config sqlParserConfig = SqlParser
.configBuilder()
.setConformance(getConformance(SqlConformanceEnum.BIG_QUERY))
.setQuoting(Quoting.BACK_TICK_BACKSLASH)
.build();
to force handling backtick-quoted identifiers and I up with:
SELECT ORDERS.o_orderkey AS O_ORDERKEY, ORDERS.o_custkey AS O_CUSTKEY, ORDERS.o_orderstatus AS O_ORDERSTATUS, ORDERS.o_totalprice AS O_TOTALPRICE, ORDERS.`o_order date`, ORDERS.o_orderpriority AS O_ORDERPRIORITY, ORDERS.o_clerk AS O_CLERK, ORDERS.o_shippriority AS O_SHIPPRIORITY, ORDERS.o_comment AS O_COMMENT
FROM ORDERS AS ORDERS
which is usable... but
why is the "default" conformance for BigQuery setting DOUBLE_QUOTE when bigquery uses backticks
why does loop-parsing lead to a different query than on the input? (running the aliased query back through a second time gets itself back, so it does stabilize, but the initial inconsistency is weird

Fetching attribute from JSON string with JSON_VAL cause "<attribute> is invalid in the used context" error

A proprietary third-party application stores JSON strings in it's database like this one:
{"state":"complete","timestamp":1614776473000}
I need the timestamp and found out that
DB2 offers JSON functions. Since it's stored as string in the PROF_VALUE column, I guess that converting with SYSTOOLS.JSON2BSON is required, before I can use JSON_VAL to fetch the timestamp:
SELECT SYSTOOLS.JSON_VAL(SYSTOOLS.JSON2BSON(PROF_VALUE), "timestamp", "f")
FROM EMPINST.PROFILE_EXTENSIONS ext
WHERE PROF_PROPERTY_ID = 'touchpointState'
This causes an error that timestamp is invalid in the used context ( SQLCODE=-206, SQLSTATE=42703, DRIVER=4.26.14). The same error is thown when I remove the JSON2BSON call like this
SELECT SYSTOOLS.JSON_VAL(PROF_VALUE, "timestamp", "f")
Also not working with the same error (different data-types):
SELECT SYSTOOLS.JSON_VAL(SYSTOOLS.JSON2BSON(PROF_VALUE), "state", "s:1000")
SELECT SYSTOOLS.JSON_VAL(PROF_VALUE) "state", "s:1000")
I don't understand this error. My syntax is like the documented JSON_VAL ( json-value , search-string , result-type) and it is the same like in the examples, where they show how to fetch the name field of an object.
I also played around a bit with JSON_TABLE to use raw input data for testing (instead of the database data), but it seems not suiteable for that.
SELECT *
FROM TABLE(SYSTOOLS.JSON_TABLE( SYSTOOLS.JSON2BSON('{"state":"complete","timestamp":1614776473000}'), 'state','s:32')) DATA
This gave me a table with one row: Type = 2 and Value = complete.
I had two problems in my query: First it seems that double quotes " are for object references. I wasn't aware that there is any difference, because in most databases I used yet, both single ' and double quotes " are equal.
The second problem is, that JSON_VAL needs to be called without SYSTOOLS, but the reference is still needed on SYSTOOLS.JSON2BSON(PROF_VALUE).
With those changes, the following query worked:
SELECT JSON_VAL(SYSTOOLS.JSON2BSON(PROF_VALUE), 'timestamp', 'f')
FROM EMPINST.PROFILE_EXTENSIONS ext
WHERE PROF_PROPERTY_ID = 'touchpointState'

Rails query to SQL statement

I'm trying to write an write this:
Team.last.players.sum("goals")
erb:
SELECT SUM("players"."goals")
FROM "players"
WHERE "players"."team_id" = $1 [["team_id", 2]]
how to rewrite this so that I could use it in a method:
def sql_search
sql = "SELECT SUM \"players\".\"goals\" FROM \"players\" WHERE \"players\".\"team_id\" = $1 [[\"team_id\", #{self.id}"
connection.execute(sql);
end
keep getting this error:
PG::SyntaxError: ERROR: syntax error at or near "."
LINE 1: SELECT SUM "players"."goals" FROM "players" WHERE "players"....
Any ideas would be appreciated
You don't need to add \" in sql statement, just remove them.
def sql_search
sql = "SELECT sum(goals) FROM players WHERE team_id = #{self.id};"
connection.execute(sql);
end
Is there some reason that you want to hard code the SQL query? It's generally bad practice to use string interpolation to insert parameters to SQL queries because of SQL injection attacks. Instead it's recommended to use ActiveRecord's SQL query parameter binding like this:
user_input = 5
Player.where('team_id = ?', user_input).sum(:goals)
Basically what this does is insert the parameter 5 after sanitization. This means you're safe from attacks where a hacker attempts to insert arbitrary SQL into parameter variables attempting to return sensitive data or delete data entirely!

DB2 query error during the retrieval of a CLOB field

From Java I am doing the following query on DB2:
SELECT * FROM PRV_PRE_ACTIVATION WHERE TRANSACTION_ID = ?
The field TRANSACTION_ID is a VARCHAR of length 32. I set the parameter in the preparedStatement using the setString method.
I get the error:
com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error: SQLCODE=-270, SQLSTATE=42997, SQLERRMC=63, DRIVER=3.59.81
at com.ibm.db2.jcc.am.dd.a(dd.java:676)
at com.ibm.db2.jcc.am.dd.a(dd.java:60)
at com.ibm.db2.jcc.am.dd.a(dd.java:127)
at com.ibm.db2.jcc.am.bn.c(bn.java:2546)
at com.ibm.db2.jcc.am.bn.d(bn.java:2534)
at com.ibm.db2.jcc.am.bn.a(bn.java:2026)
at com.ibm.db2.jcc.t4.cb.g(cb.java:140)
at com.ibm.db2.jcc.t4.cb.a(cb.java:40)
at com.ibm.db2.jcc.t4.q.a(q.java:32)
at com.ibm.db2.jcc.t4.rb.i(rb.java:135)
at com.ibm.db2.jcc.am.bn.gb(bn.java:1997)
at com.ibm.db2.jcc.am.cn.pc(cn.java:3009)
at com.ibm.db2.jcc.am.cn.b(cn.java:3786)
at com.ibm.db2.jcc.am.cn.bc(cn.java:678)
at com.ibm.db2.jcc.am.cn.executeQuery(cn.java:652)
Where the sqstate means "Capability is not supported by this version of the DB2 application requester, DB2 application server, or the combination of the two." But I don't use any strange functionality.
I have tried using an squ client the query:
SELECT * FROM PRV_PRE_ACTIVATION where transaction_id='A'
And it goes ok.
What is the cause of the problem?
UPDATE: The code where the statement is prepared:
s = con.prepareStatement(sSQL,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
Try changing to a specified list of columns in the select list -- my guess is you have a user defined column type (or some other type) which is not supported by your driver. For example, does the statement
SELECT TRANSACTION_ID FROM PRV_PRE_ACTIVATION WHERE TRANSACTION_ID = ?
work? If so then start adding columns in and you will find the problem column.
I've came across this problem lately, and after some searching on web, I've came across this link:
DB2 SQL error: SQLCODE: -270, SQLSTATE: 42997, SQLERRMC: 63
, which specifies this:
A column with a LOB type, distinct type on a LOB type, or
structured type cannot be specified in the select-list of an
insensitive scrollable cursor.
With help from an colleague, we came to this conclusion:
1, Q: When will you get this "SQLCODE=-204, SQLSTATE=42704" exception?
A: When a scrollable PreparedStatement is prepared & executed, yet there are [B|C]LOB fields exist in the select list. e.g.:
String strQuery = "SELECT NUMBER_FIELD, CHAR_FIELD, CLOB_FIELD FROM TABLE_NAME WHERE CONDITION IS TRUE;"
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, REsultSet.CONCUR_READ_ONLY);
rs = stmt.executeQuery(strQuery); //and this exception will be thrown here
2, Q: So what's the solution if we want to get rid of it when [B|C]LOB fields are queried?
A: Try to use ResultSet.TYPE_FORWARD_ONLY while creating the query statement.e.g.:
stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
Or simply try this one:
stmt = conn.createStatement();
Note that the same rules apply to conn.prepareStatement() too. You may refer to Java API doc for more information.

Django Raw SQL give me TypeError not enough arguments

code:
diary=models.SablogArticles.objects.raw("SELECT articleid,DATE_FORMAT(from_unixtime(dateline),'%Y-%m')\
as newtime,count(*) as howmany FROM sablog_articles group by newtime")
The result gave me :
In template d:\python\project\tpl\base.html, error at line 68 Caught
TypeError while rendering: not enough arguments for format string
The raw SQL is a string with formatting parameters, which means that % indicates a parameter to format. Your string has % in it. You need to double them to protect them from interpretation:
diary = models.SablogArticles.objects.raw("""
SELECT
articleid,
DATE_FORMAT(from_unixtime(dateline),'%%Y-%%m') as newtime,
count(*) as howmany
FROM sablog_articles group by newtime
""")