Blob insert/update in jooq - jooq

Getting "error occurred during batching: ORA-00933 SQL command not properly ended.
I'm trying to update/insert byte array in Oracle BLOB column using jooq syntax as follows:-
Map<Field<Object>, Object> fieldValueMap = new HashMap<>();
fieldValueMap.put(field("BLOB_COLUMN"), "test".getBytes());
Query = DSLContext.update(table(tablename)).set(fieldValueMap).where(condition)
Formed query for blob column as follows:-
Update tablename set BLOB_COLUMN = X'74657374' where condition.
Please help with the above issue.

X'74657374' is the default rendering of bytes[] inline literals for unknown dialects, as well as a few known dialects, including e.g. H2, HSQLDB, MariaDB, MySQL, SQLite. If you had used the SQLDialect.ORACLE dialect, then you'd have gotten something like hextoraw('74657374') as generated SQL, which wouldn't produce the error you've seen.
But you probably don't want to get inline literals anyway. This probably happened because you either:
Used static statements
Explicitly used inline literals

Related

Azure Logic Apps: How to use variables in a dynamic query?

Trying to add values from the JSON Parser into a dynamic Oracle query but always shows up as blank/empty.
Same results trying to use the formal parameters and declaring them within the Oracle query as well.
Is this possible?
Service Bus trigger. Message comes in and goes into the "For each message" loop. It then gets parsed in the "Parse JSON Message" and when I try to use the dynamic content from that in an Oracle query (e.g. #body('Parse_JSON_Message')?['contentData']?['dynamicValue']), they always show up as nothing/blank.
I can use this same reference later (again #body('Parse_JSON_Message')?['contentData']?['dynamicValue']) with no issues but it always ends up blank in the query.
Even using formal parameterized key values shows the #body('Parse_JSON_Message')?['contentData']?['dynamicValue']) to be NULL.
So my queries are coded as:
SELECT thisValue
WHERE columnName = #body('Parse_JSON_Message')?['contentData']?['dynamicValue'] (have also tried #{body('Parse_JSON_Message')?['contentData']?['dynamicValue']})
But are coming out as:
SELECT thisValue
WHERE columnName =
...with no result obviously.
This query does work if I hard code the value.
If I use dynamic values in my output (where I'm mapping data), it works fine. So how should I correctly dynamic values in this Oracle query?

Knex + SQL Server whereIn query 8-12s -- raw version returns NO results but if I input the .toQuery() result directly I get results

The database is in Azure cloud and not being used in production currently. There are 80.000 rows and a uprn is a VARCHAR(100);
I'm already using JOI to validate each UPRN as well;
I'm using KNEX with a SQL Server database with the following whereIn query:
knex(LOCATIONS.table).whereIn(LOCATIONS.uprn, req.body.uprns)
but this takes 8-12s to complete and sometimes timesout. if I use .toQuery() on the same thing, SSMS will return the result within 1-2.
If I do a raw query, the resulting .toQuery() or toString() works in SSMS and returns results. But if I try to use the raw directly, it will return 0 results.
I'm looking to either fix what's making whereIn so slow or get the raw query working.
EDIT 1:
After much debugging and trying -- it seems that the bug is due to how knex deals with arrays, so I made a for-of loop to add ? ? ? for each array element and then inputed the array for all params.
This led me to realizing the performance issue is due to SQL server way of parameterising.
I ended up building a raw query string with all of the parameters and validating the input with Joi string/regex config:
Joi.string()
.min(1)
.max(35)
.regex(/^[a-z\d\-_\s]+$/i)
allowing only for alphanumeric, dashes and spaces which should prevent sql injection.
I'm going to look deeper into security issues with this and might make a separate login that can only SELECT data from that table and nothing more to run with these queries.
Needed to just handle it raw and validate separately.

Curly brackets in OrmLite select query throws error

It seems like OrmLite plain select extension method (Select<T>) tries to format the query string (like SelectFmt<T>), and so it throws an error if the query string contains curly brackets, which it assumes are missing arguments.
Example query:
db.Select<Company>("Website='http://www.test.com/?session={123}'");
Error thrown:
Index (zero based) must be greater than or equal to zero and less than the size of the argument list.
Ideally, Select<T> should just execute the query verbatim, without any string formatting.
Is it a bug in OrmLite, or something else?!
Update: Seems like the issue is here in OrmLiteDialectProviderBase class. It should have a check for params length etc.
You can use SqlList<T> API's for executing Custom SQL that skips pre-processing by OrmLite, but you'll need to provide the full SQL Statement, e.g:
var results = db.SqlList<Company>(
"SELECT * FROM Company WHERE Website='http://www.test.com/?session={123}'");

Parameterized query in Postgresql with a json array

I would like to invoke array_prepend into a json[] using a parameterized query. I am using pg-promise npm package but this uses the normal node-postgres adapter under the hood.
My query is:
db.query(`update ${schema}.chats set messages =
array_prepend('{"sender":"${sender}","tstamp":${lib.ustamp()},"body":$1}',messages) where chat_id = ${chat_id}`
, message));
Same with "$1".
It works with a non-parameterized query.
Above code produces :
{ [error: syntax error at or near "hiya"]
Main reason for this is to avoid sql injection (docs say that they escape adequately when using the parameterized queries).
There are 2 problems in your query.
The first one is that you are using ES6 template strings, while also using sql formatting with ${propName} syntax.
From the library's documentation:
Named Parameters are defined using syntax $*propName*, where * is any of the following open-close pairs: {}, (), [], <>, //, so you can use one to your liking, but remember that {} are also used for expressions within ES6 template strings.
So you either change from ES6 template strings to standard strings, or simply switch to a different variable syntax, like $/propName/ or $[propName], this way you will avoid the conflict.
The second problem is as I pointed earlier in the comments, when generating the proper SQL names, use what is documented as SQL Names.
Below is a cleaner approach to the query formatting:
db.query('update ${schema~}.chats set messages = array_prepend(${message}, messages) where chat_id = ${chatId}', {
schema: 'your schema name',
chatId: 'your chat id',
message: {
sender: 'set the sender here',
tstamp: 'set the time you need',
body: 'set the body as needed'
}
}
);
When in doubt about what kind of query you are trying to execute, the quickest way to peek at it is via pgp.as.format(query, values), which will give you the exact query string.
And if you still want to use ES6 template strings for something else, then you can change the string to:
`update $/schema~/.chats set messages = array_prepend($/message/, messages) where chat_id = $/chatId/`
That's only one example, the syntax is flexible. Just remember not to use ES6 template string formatting to inject values into queries, because ES6 templates have no knowledge about how to properly format JavaScript types to comply with PostgreSQL, only the library knows it.

Subsonic - Bit operation in Where Clause

I'm trying to make something like this:
int count = new Select().From(tblSchema).Where("Type & 1").IsEqualTo("1").GetRecordCount();
And the error message is:
Incorrect syntax near '&'.
Must declare the scalar variable "#Deleted".
Is it possible to do that with SubSonic?
Must declare the scalar variable
"#Deleted"
The second error would be caused by using logical deletes on the table you are querying (the table has an isDeleted or Deleted column).
But I'm looking through the code, I'm not sure how that parameter is getting in there. The SqlQuery.GetRecordCount method doesn't call CheckLogicalDelete(), from what I can tell. Is that error message unrelated?
This seems to be a bug in the way SubSonic is naming it's parameters when it generates the SQL to be executed.
What's happening is that SubSonic is looking at "Type & 1" and then creating a parameter to compare against called #Type&10 which is not a valid SQL parameter name. So you'll end up with the following SQL from your original query. You should submit a bug to http://code.google.com/p/subsonicproject/
Meanwhile you can workaround the bug for now by using an inline query:
http://subsonicproject.com/docs/Inline_Query_Tool
It is a little fuzzy as to what you are trying to accomplish but here is a best guess.
int count = new Select().From(tbl.Schema).Where(tbl.TypeColumn).IsEqualTo(true).GetRecordCount();

Resources