Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MySQL Prepared statements with a variable size variable list

Tags:

How would you write a prepared MySQL statement in PHP that takes a differing number of arguments each time? An example such query is:

SELECT `age`, `name` FROM `people` WHERE id IN (12, 45, 65, 33) 

The IN clause will have a different number of ids each time it is run.

I have two possible solutions in my mind but want to see if there is a better way.

Possible Solution 1 Make the statement accept 100 variables and fill the rest with dummy values guaranteed not to be in the table; make multiple calls for more than 100 values.

Possible Solution 2 Don't use a prepared statement; build and run the query checking stringently for possible injection attacks.

like image 238
smarthall Avatar asked Nov 29 '08 06:11

smarthall


People also ask

How do you create a prepared statement in MySQL?

In order to use MySQL prepared statement, you use three following statements: PREPARE – prepare a statement for execution. EXECUTE – execute a prepared statement prepared by the PREPARE statement. DEALLOCATE PREPARE – release a prepared statement.

What is Max_prepared_stmt_count?

That means that you can run the server out of prepared statements if a lot of connections “leak” prepared statements. The variable is called max_prepared_stmt_count . You can see the number of prepared statements created, globally, by looking at prepared_stmt_count .

Does MySQL support prepared statement?

MySQL 8.0 provides support for server-side prepared statements. This support takes advantage of the efficient client/server binary protocol. Using prepared statements with placeholders for parameter values has the following benefits: Less overhead for parsing the statement each time it is executed.

Which of the following is correct syntax for prepared statement?

$stmt->bind_param("sss", $firstname, $lastname, $email); This function binds the parameters to the SQL query and tells the database what the parameters are. The "sss" argument lists the types of data that the parameters are. The s character tells mysql that the parameter is a string.


2 Answers

I can think of a couple solutions.

One solution might be to create a temporary table. Do an insert into the table for each parameter that you would have in the in clause. Then do a simple join against your temporary table.

Another method might be to do something like this.

$dbh=new PDO($dbConnect, $dbUser, $dbPass); $parms=array(12, 45, 65, 33); $parmcount=count($parms);   // = 4 $inclause=implode(',',array_fill(0,$parmcount,'?')); // = ?,?,?,? $sql='SELECT age, name FROM people WHERE id IN (%s)'; $preparesql=sprintf($sql,$inclause);  // = example statement used in the question $st=$dbh->prepare($preparesql); $st->execute($parms); 

I suspect, but have no proof, that the first solution might be better for larger lists, and the later would work for smaller lists.


To make @orrd happy here is a terse version.

$dbh=new PDO($dbConnect, $dbUser, $dbPass); $parms=array(12, 45, 65, 33); $st=$dbh->prepare(sprintf('SELECT age, name FROM people WHERE id IN (%s)',                           implode(',',array_fill(0,count($parms),'?')))); $st->execute($parms); 

like image 100
Zoredache Avatar answered Nov 14 '22 18:11

Zoredache


There is also the FIND_IN_SET function whose second parameter is a string of comma separated values:

SELECT age, name FROM people WHERE FIND_IN_SET(id, '12,45,65,33') 
like image 37
Gumbo Avatar answered Nov 14 '22 18:11

Gumbo