I'm building a dynamic SQL statement, that will insert one or more sets of VALUES
via a prepared DBI statement, my question is this:
Since I have a dynamic number of VALUES
sets, and I will need to add as many ( ?, ?, ?),( ?, ?, ?)
etc as necessary to extend the statement INSERT INTO `tblname` ( $columnsString ) VALUES
in order to submit only one query using placeholders and bind values- is this the preferred method(most efficient, etc., - reasoning behind efficiency would be helpful in your answer if possible) or should I just be building this as a query string with sprintf
and dbh->quote()
?
(As a little extra information: I'm actually using AnyEvent::DBI right now, which only exposes placeholders & bind values and not the quote()
method so this wouldn't be easy for me to accomplish without creating another straight DBI $dbh
and using another db server connection just to use the quote()
method, or without altering the AnyEvent::DBI module myself.)
Normally I would just execute the statements as necessary but in this heavy workload case I'm trying to batch inserts together for some DB efficiency.
Also, if anyone could answer if it is possible( and then how to ) insert an sql DEFAULT
value using placeholders and bind values that'd be awesome. Typically if I ever needed to do that I'd append the DEFAULT
s to the string directly and use sprintf and $dbh->quote()
only for the non DEFAULT
values.
UPDATE:
Worked out the misunderstanding in a quick chat. User ikegami suggested that instead of building the query string myself without placeholders, that I just intermingle VALUES and placeholders such as:
$queryString .= '(DEFAULT,?,?),(DEFAULT,DEFAULT,DEFAULT)';
Some of the reasoning behind my first asking of this question on SO was because I was somewhat against this intermingling due to my thought that it made the code less readable, though after being assured that sql 'DEFAULT' couldn't be in a placeholder bind value, this was the method I had begun implementing.
Using placeholders where possible does seem to be the more accepted method of building queries, and if you want an SQL DEFAULT
you just need to include it in the same query building as the placeholders. This does not apply to NULL
values, as those CAN be inserted with placeholders and a bind value of undef
.
Update 2:
The reasoning I asked about performance, the 'acceptance' of building your own query with quote() vs building with placeholders, and why I've gone with a solution that involves using all columns for the SQL INSERT INTO tblname (cols)
is because I have roughly 2-4 million rows a day going into a terrible db server, and my code is running on an equally terrible server. With my requirements of needing DEFAULT
sql values, and these terrible performance constraints, I've chosen a solution for now.
For future devs who stumble upon this - take a look at @emazep's solution of using SQL::Abstract, or if for some reason you need to build your own, you might consider either using @Schwern's subroutine solution or possibly incorporating some of @ikegami's answer into it as these are all great answers as to the 'Current state of affairs' regarding the usage of DBI and building dynamic queries.