Multiple values in where with prepared SQL-Statements? - sql

Is there a way to select multiple values with prepared statements in (My-)SQL?
I'm trying to select a couple of rows from a table with the IN-keyword, something like:
SELECT *
FROM table
where id IN (1, 2, 3)
The "1, 2, 3" should be passed as a parameter of the statement.
Is this possible with PHP/PDO or do I have to concaterate the values and insert it directly in the statement (I've got a bad feeling about this because of injections).

If you have an array of "something" that comes from the user, you can build a list of placeholders with array_fill, generate a string like "?, ?, ?, ..." by calling implode on the array. Alternatively you can make sure everything in the array is an integer (using intval, for example) and use it directly to build the query.

I would pass in an array of integers, and then do String.Join to bring them together within your prepared statement. You can't inject anything into an integer!

Try passing you in-list as aconcatenated string and do this (not very performant but it should work: I think I saw an answer from Joel Spolsky somewhere using this technique):
SELECT * FROM table where concat('|',id,'|') like '%|1|2|3|%'

Related

How do I treat a special string as an array and select the second object from it in postgreSQL

I have a column in my table which has values like this
1923195445602;182343;en
or
1830310365602;175824;en;EVENT
Data is split by ";"
I want to select the second value of it. My thought is to find a way to treat this string as an array. Or is there a better way?
you can use select split_part(colname,';',2);

Braces inside the array - postgresql

I have a table "temp" with two attributes: integer, text[].
I would like to insert a record with the brace inside the array.
For example a record like this:
1, {'1{c}1','a'}
where 1 is the integer and '1{c}1' is the first element of the array and 'a' the second element of the array.
I tried a simply insert like this:
INSERT INTO temp VALUES (id, '{'1{c}1','a'}');
but it says that is malformed.
As an addition, it's also possible to use array constructors, I think it's more safe to use, because array elements are just SQL constants and you also could use expressions inside the array constructors:
insert into "temp" values(1, array['1{c}1','a']);
it's clear that this is array of strings, and this too
insert into "temp" values(1, array['1','2']);
According to the PostgreSQL documentation for arrays,
You can put double quotes around any element value, and must do so if it contains commas or curly braces.
A correct syntax would like this:
INSERT INTO "temp" VALUES (1, '{"1{c}1",a}');
You can see a complete, working example on SQL fiddle.
You don't want those inner single quotes.
INSERT INTO temp VALUES (id, '{1{c}1,a}');

Array parameter for TADOQuery in Delphi 2010

I need to execute a simple query:
SELECT * FROM MyTable WHERE Id IN (:ids)
Obviously, it returns the set of records which have their primary key 'Id' in the given list. How can I pass an array of integer IDs into ADOQuery.Parameters for parameter 'ids'? I have tried VarArray - it does not work. Parameter 'ids' has FieldType = ftInteger by default, if it matters.
There is no parameter type that can be used to pass a list of values to in. Unfortunately, this is one of the shortcomings of parameterized SQL.
You'll have to build the query from code to either generate the list of values, or generate a list of parameters which can then be filled from code. That's because you can pass each value as a different parameter, like this:
SELECT * FROM MyTable WHERE Id IN (:id1, :id2, :id3)
But since the list will probably have a variable size, you'll have to alter the SQL to add parameters. In that case it is just as easy to generate the list of values, although parametereized queries may be cached better, depending on which DB you use.
The IN param just takes a comma separated string of values like (1,2,3,4,5) so I assume you set the datatype to ftstring and just build the string and pass that...? Not tried it but it's what I would try...

Insert Comma Separated Values to SQL

I would like to take a list that I have in a text file, of values which are separated by commas:
Example - 1,2,3,4,5,6,7,8,9,0
then put the values in a database table(I'm going to use this table for auto-complete with jQuery).
I would have done an array for the auto-complete but I have something like 1000 values so I think its better to pull from SQL(am i right?)
Try to explain it to me slowly cause I'm a novice and this is so confusing :)
If those are 1000 constant values (like countries), put them in array.
If they are fairly dynamic, put them in a table
Assuming the table is called T1 and has one field F1, you need to transform the string
1,2,3,4,5,6,7,8....N
to
INSERT INTO T1
VALUES (1),(2),(3),(4),(5),(6),(7),(8)......(N);

SQL: Use the same string for both INSERT and UPDATE?

The INSERT syntax I've been using is this
INSERT INTO TableName VALUES (...)
The UPDATE syntax I've been using is
UPDATE TableName SET ColumnName=Value WHERE ...
So in all my code, I have to generate 2 strings, which would result in something like this
insertStr = "(27, 'John Brown', 102)";
updateStr = "ID=27, Name='John Brown', ItemID=102";
and then use them separately
"UPDATE TableName SET " + updateStr + " WHERE ID=27 " +
"IF ##ROWCOUNT=0 "+
"INSERT INTO TableName VALUES (" + insertStr + ")"
It starts bothering me when I am working with tables with like 30 columns.
Can't we generate just one string to use on both INSERT and UPDATE?
eg. using insertStr above on UPDATE statement or updateStr on INSERT statement, or a whole new way?
I think you need a whole new approach. You are open to SQL Injection. Provide us with some sample code as to how you are getting your data inputs and sending the statements to the database.
alt text http://goose.ycp.edu/~weddins/440/S09%20IFS440%20Bobby%20Drop%20Tables.PNG
As far as I'm aware, what you're describing isn't possible in ANSI SQL, or any extension of it that I know. However, I'm mostly familiar with MySQL, and it likely depends completely upon what RDBMS you're using. For example, MySQL has "INSERT ... ON DUPLICATE KEY UPDATE ... " syntax, which is similar to what you've posted there, and combines an INSERT query with an UPDATE query. The upside is that you are combining two possible operations into a single query, however, the INSERT and UPDATE portions of the query are admittedly different.
Generally, this kind of thing can be abstracted away with an ORM layer in your application. As far as raw SQL goes, I'd be interested in any syntax that worked the way you describe.
Some DBMS' have an extension to do this but why don't you just provide a function to do it for you? We've actually done this before.
I'm not sure what language you're using but it's probably got associative arrays where you can wrote something like:
pk{"ID"} = "27"
val{"Name"} = "'John Brown'"
val{"ItemID"} = "102"
upsert ("MyTable", pk, val)
and, if it doesn't have associative arrays, you can emulate them with multiple integer-based arrays of strings.
In our upsert() function, we just constructed a string (update, then insert if the update failed) and passed it to our DBMS. We kept the primary keys separate from our other fields since that made construction of the update statement a lot easier (primary key columns went in the where clause, other columns were just set).
The result of the calls above would result in the following SQL (we had a different check for failed update but I've put your ##rowcount in for this example):
update MyTable set
Name = 'John Brown',
ItemID = 102
where ID = 27
if ##rowcount=0
insert into MyTable (ID, Name, ItemID) values (
27,
'John Brown',
102
)
That's one solution which worked well for us. No doubt there are others.
Well, how about no statements? You might want to look into an ORM to handle this for you...
Some databases have proprietary extensions that do exactly this.
I agree that the syntax of INSERT and UPDATE could be more consistent, but this is just a fact of life now -- it ain't gonna change now. For many scenarios, the best option is your "whole new way": use an object-relational mapping library (or even a weak-tea layer like .NET DataSets) to abstract away the differences, and stop worrying about the low-level SQL syntax. Not a viable option for every application, of course, but it would allow you to just construct or update an object, call a Save method and have the library figure out the SQL syntax for you.
If you think about it, INSERT and UPDATE are exactly the same thing. They map field names to values, except the UPDATE has a filter.
By creating an associative array, where the key is the field name and the value is the value you want to assign to the field, you have your mapping. You just need to convert it to a the proper string format depending on INSERT or UPDATE.
You just need to create a function that will handle the conversion based on the parameters given.
SQL Server 2008:
MERGE dbo.MyTable AS T
USING
(SELECT
#mykey AS MyKey
#myval AS MyVal
) AS S
ON (T.MyKey = S.MyKey)
WHEN MATCHED THEN
UPDATE SET
T.MyVal = S.MyVal
WHEN NOT MATCHED THEN
INSERT (MyKey, MyVal)
VALUES (S.MyKey, S.MyVal)
MySQL:
INSERT (MyKey, MyVal)
INTO MyTable
VALUES({$myKey}, {$myVal})
ON DUPLICATE KEY UPDATE myVal = {$myVal}