Binding parameters with sequelize fails if multiple - postgresql

Database is Postgres (and in Sequelize there is support for bind parameter for Postgres).
Strange thing.
When running raw query and binding parameters this way:
return models.sequelize.query(q, {bind: ['33', 'test']}).then(function (data) {
Then sequelize seems to fail in binding parameters.
The query itself is something like
select * from A where id = $1
As soon as I remove the second element in the array passed to bind, the binding works.
But when there are more than one element, the $1 is not transformed to value. This is what I can see in the log.
The query when only a bind parameter is present will print
select * from A where id = 33
While the query when more than one bind parameter is added will print
select * from A where id = $1

My bad. I didn't look at the real error message sent ot the client.
It had nothing to do with the number of parameters.
The problem was that using LIKE I had something like:
and name LIKE '%$2%'
This gives the error:
bind message supplies 2 parameters, but prepared statement requires 1
Which was the real issue.

I realize this is an old thread. However, it may be a workaround for those facing this issue and using postgresql.
let array = ['33', 'test'];
let query = `SELECT * FROM A WHERE id::text IN(SELECT UNNEST(STRING_TO_ARRAY($1, ','))::text)`
// Now we can run the query.
models.sequelize.query(q, {bind: [array.toString()]})

Related

Passing None into tokio postgres sql client query method

I am using tokio postgres in a Rust project where I have query parameters.
rows = client.query(QUERY, &[&input1, &input2.unwrap()]).await.expect("error");
where QUERY looks like this
QUERY: &str = "SELECT * FROM Table WHERE Name=$1 AND Address= COALESCE($2, Address);"
input2 is of type Rust option for which I will have to unwrap input2 before inserting it into the query method. Is there a way to make the query method handle "None" directly.
I can write conditional statements outside but that will make the source code unmanageable for the case where I have multiple optional queries.
You work with raw queries, tokio_postgres couldn't to manage None. In my experience best solution will write your own query builder.
You do not need to .unwrap() at all and can pass &input2 as-is. Option<T> implements ToSql where T: ToSql, if the value is None then it will pass NULL to the database:
let rows = client.query(
"SELECT * FROM Table WHERE Name=$1 AND Address=COALESCE($2, Address)",
&[&input1, &input2],
).await?;
Full working code that I tested on my local database is available here.

spring data jpa issue with postgres - Tried to send an out-of-range integer as a 2-byte value

quoteEntitiesPage = quoteRepository.findAllByQuoteIds(quoteIds, pageRequest);
The above query gives me the error "Tried to send an out-of-range integer as a 2-byte value" if the count of quoteIds parameter is above Short.MAX_VALUE.
What is the best approach to get all quote entities here? My Quote class has id(long) and quoteId(UUID) fields.
When using a query of the type "select ... where x in (list)", such as yours, Spring adds a bind parameter for each list element. PostgreSQL limits the number of bind parameters in a query to Short.MAX_VALUE bind, so when the list is longer than that, you get that exception.
A simple solution for this problem would be to partition the list in blocks, query for each one of them, and combine the results.
Something like this, using Guava:
List<QuoteEntity> result = new ArrayList<>();
List<List<Long>> partitionedQuoteIds = Lists.partition(quoteIds, 10000);
for (List<Long> partitionQuoteIds: partitionedQuoteIds) {
result.addAll(quoteRepository.findAllByQuoteIds(partitionQuoteIds))
}
This is very wasteful when paginating, but it might be enough for your use case.

FsSql Not working when Parameterizing Columns

Using F# , FsSql and PostGres
So I'm using this function
let getSqlParameter value =
let uniqueKey = Guid.NewGuid().ToString("N")
let key = (sprintf "#%s" uniqueKey)
(key,Sql.Parameter.make(key,value))
to get me a parameter of anything I pass in dynamically
Which I then append to a query and I get something like this
select * from (select * from mytable) as innerQuery where #a29c575b69bb4629a9971dac2808b445 LIKE '%#9e3485fdf99249e5ad6adb6405f5f5ca%'
Then I take a collection of these and pass them off
Sql.asyncExecReader connectionManager query parameters
The problem that I'm having is that when I don't run this through my parameterization engine, it works fine. When I do, it doesn't work. It just returns empty sets.
The only thing I can think of is that the column names can't be parameterized. This is a problem because they're coming from the client. Is there a way to do this?
Okay so the answer here is that you can't parameterize column names as far as I can tell.
What I ended up doing was creating a whitelist of acceptable column names and then compare what was coming in to my whitelist. If it doesn't exist then I drop it.
By far a sub-optimal solution. I really wish there was a way to do this.

PHP and sanitizing strings for use in dynamicly created DB2 queries

I'm relatively new to DB2 for IBMi and am wondering the methods of how to properly cleanse data for a dynamically generated query in PHP.
For example if writing a PHP class which handles all database interactions one would have to pass table names and such, some of which cannot be passed in using db2_bind_param(). Does db2_prepare() cleanse the structured query on its own? Or is it possible a malformed query can be "executed" within a db2_prepare() call? I know there is db2_execute() but the db is doing something in db2_prepare() and I'm not sure what (just syntax validation?).
I know if the passed values are in no way effected by the result of user input there shouldn't be much of an issue, but if one wanted to cleanse data before using it in a query (without using db2_prepare()/db2_execute()) what is the checklist for db2? The only thing I can find is to escape single quotes by prefixing them with another single quote. Is that really all there is to watch out for?
There is no magic "cleansing" happening when you call db2_prepare() -- it will simply attempt to compile the string you pass as a single SQL statement. If it is not a valid DB2 SQL statement, the error will be returned. Same with db2_exec(), only it will do in one call what db2_prepare() and db2_execute() do separately.
EDIT (to address further questions from the OP).
Execution of every SQL statement has three stages:
Compilation (or preparation), when the statement is parsed, syntactically and semantically analyzed, the user's privileges are determined, and the statement execution plan is created.
Parameter binding -- an optional step that is only necessary when the statement contains parameter markers. At this stage each parameter data type is verified to match what the statement text expects based on the preparation.
Execution proper, when the query plan generated at step 1 is performed by the database engine, optionally using the parameter (variable) values provided at step 2. The statement results, if any, are then returned to the client.
db2_prepare(), db2_bind_param(), and db2_execute() correspond to steps 1, 2 and 3 respectively. db2_exec() combines steps 1 and 3, skipping step 2 and assuming the absence of parameter markers.
Now, speaking about parameter safety, the binding step ensures that the supplied parameter values correspond to the expected data type constraints. For example, in the query containing something like ...WHERE MyIntCol = ?, if I attempt to bind a character value to that parameter it will generate an error.
If instead I were to use db2_exec() and compose a statement like so:
$stmt = "SELECT * FROM MyTab WHERE MyIntCol=" . $parm
I could easily pass something like "0 or 1=1" as the value of $parm, which would produce a perfectly valid SQL statement that only then will be successfully parsed, prepared and executed by db2_exec().

SELECT query in PostgreSQL

I am trying to retrieve values from a PostgreSQL database in a variable using a WHERE clause, but I am getting an error.
The query is:
select age into x from employee where name=name.GetValue()
name is the textcontrol in which I am entering a value from wxpython GUI.
I am getting an error as name schema doesn't exist.
What is the correct method for retrieving values?
"name.GetValue()" is a literal string, you are sending that to your db which knows nothing about wxpython and nothing about the variables in your program. You need to send the value of that data to your db, probably using bound parameters. Something like:
cur.execute("select age from employee where name=%s", [name.GetValue()])
x = cur.fetchone()[0] # returns a row containing [age] from the db
is probably what you're after. This will create a query with a placeholder in the database, then bind the value of name.GetValue() to that placeholder and execute the query. The next line fetches the first row of the result of the query and assigns x to the first item in that row.
I'm not positive what you are trying to do, but I think your issue might be syntax (misuse of INTO instead of AS):
SELECT age AS x FROM employee WHERE name = ....