php zend db profiler INSERT and UPDATE queries - php

I am trying to use the zend db profiler to record the queries. I read the documentation from the zend website and it works fine except that I am not able to get the values for the insert and the update queries. I just see the query as below with the ? for values. I tried using the getQueryParams to atleast see if I can get the values in the array and it works only with getLastQueryProfile and not the getQueryProfile to get it for all queries. Can some one please let me know how I can get the "?" with the actual values? I am not concerned about the Array as anyways it doesn't do the purpose.
INSERT INTO `myTable` (`id`, `lname`, `fname`) VALUES (?, ?, ?)
thanks.

I don't think it's possible.
According to php's PDO Manual there's no way to retrieve a query after a prepare() statement. In the examples it's easy to understand because using the PDO manually you know the order of the parameters and have the statement. Looking after Zend clases (Zend_Db_Table_Abstract) i see that the order is maintained and that's the proper way because it uses question mark parameters.
Reading Zend_Db_Adapter_Pdo_* clases you should get it clearer

Related

How do you combine inserting mass values with prepared statements in php

In the old question asked below the top answer describes how to speed up the MySQL insert process. Since this an old question I'm curious on how to do this with prepared statements. I use MySQL with innoDB. I'll paste in an example from the answer here for people who don't want to check the link.
Here I'll describe 3 methods for inserting data, ranging from slow to
fast:
The following is extremely slow if you have many rows to insert:
INSERT INTO mytable (id,name) VALUES (1,'Wouter');
INSERT INTO mytable (id,name) VALUES (2,'Wouter');
INSERT INTO mytable (id,name) VALUES (3,'Wouter');
This is already a lot faster:
INSERT INTO mytable (id, name) VALUES
(1, 'Wouter'),
(2, 'Wouter'),
(3, 'Wouter');
And this is usually the fastest:
Have CSV file that looks like this:
1,Wouter
2,Wouter
3,Wouter
And then run something like
LOAD DATA FROM INFILE 'c:/temp.csv' INTO TABLE mytable
old question
This is obvious an old answer. I want to know how to do this with prepared statements in a way that will insert as fast as possible, but let's go one step at a time. First I want to know how to do this with a prepared statements. Any examples that can be given will be much appreciated. I will reply or edit this question with any extra information that you may need.
I'm using mysqli_ *Edited for Rick James's question.
I'm going to do my best and make an educated guess on how this can be done. Please correct me if I'm wrong.
I think I can convert
INSERT INTO mytable (id, name) VALUES
(1, 'Wouter'),
(2, 'Wouter'),
(3, 'Wouter');
into
$bindParamsToBuild = '($myArray[key], ?,?),'
for (i = 0; i < count($myArray); i++)
{
if (i === count($myArray))
{
$bindParamsToBuild += '($myArray[key], ?,?);';
}
else
{
$bindParamsToBuild += '($myArray[key], ?,?),';
}
}
"INSERT INTO mytable (id, name) VALUES".$bindParamsToBuild;
Are you using PDO or mysqli?
If using mysqli, use real_escape_string() separately on each item in the list. It is a bit tedious but can be made easier by gradually building the insert string. I suggest not putting more than 100 items into a single INSERT.
https://stackoverflow.com/a/780046/1766831 is a pretty good discussion of the details. (But be sure to use mysqli_*, not mysql_*.)
Plan A: Construct the query as discussed in some of those links. Use real_escape_string and PHP string operations instead of "prepare".
Plan B: Build a string with lots of question mark. Simultaneously, build an array with the values to put into those question marks. Then do a single "prepare" to finish the multi-row INSERT statement.

Insert a POINT() value in mysql using Fat Free Framework

I need to insert a POINT value into my MySQL table using Fat Free Framework. I was hoping to do this using the F3 Mapper, but I got the impression that is not possible.
So I tried to use $db-exec()
This is my current code, based on various searches here and on google.
$geopoint = "POINT($lat $long)";
$db->exec("INSERT INTO event_dates ('eventGeoPoint') VALUES ($geopoint)");
This throws an error:
PDOStatement: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '52.8583742))' at line 1
I have also tried
$db->exec("INSERT INTO event_dates ('eventGeoPoint') VALUES (GeomFromText($geopoint))");
Please tell me how to correctly insert a POINT() value into my database using Fat Free Framework, either the mapper or exec
You need to correct your INSERT statement, which you are mixed with UPDATE statement.
INSERT INTO mytable SET myGeoPoint = 'GeomFromText($geopoint)
should be
INSERT INTO mytable(myGeoPoint) values (GeomFromText($geopoint))
Also, you need to use Prepared Statement to avoid SQL Injection.
Searching on after #Ravi's comments I found the answer in this post.
I changed my statement to
$result= $db->exec("INSERT INTO mytable (GeoPoint) VALUES (PointFromText(CONCAT('POINT(',$lat,' ',$long,')')))");
And it works!

SELECT and INSERT not selecting

When I execute
INSERT INTO `survey`
(`id`,`name`,`date_start`,`date_end`)
values
(:id,:name,NULL,DATE_ADD(NOW(), INTERVAL 1 MINUTE))
on duplicate key UPDATE `name`=:name;
SELECT coalesce(:id,LAST_INSERT_ID()) as 'id'
it inserts a new data fine, but doesn't select the id (which is needed later on in my php code)
I've tried this suggestion
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
but this SQL throws errors (due to duplicate parameters)
SELECT ASCII(substr(`perm` FROM floor(:i/8)+1))&(1<<(:i%8))>0 as perm FROM `user` WHERE `id`=:id
I'm in a lose-lose situation, re-writing all my SQL code to not have duplicate parameters would be very messy, doing a separate select straight after inserting may not return the id I want. Any suggestions would be great
You cannot run two queries at the same time, only one at the time.
If you want to do the whole thing at once then create a stored procedure.
Same goes for complex queries, when it gets complicated you want to have your logic in the database.
Here is an example:
DELIMITER //
CREATE PROCEDURE sp_insert_survey(IN `p_id`,
IN `p_name`,
IN `p_date_start`,
IN `p_date_end`)
BEGIN
INSERT INTO `survey`(`id`,`name`,`date_start`,`date_end`)
VALUES (p_id, p_name, p_date_start, p_date_end);
SELECT `id`,`name`,`date_start`,`date_end`
FROM survey WHERE `id` =LAST_INSERT_ID();
END //
DELIMITER ;
Call the sp from PDO:
$stmt = $db->prepare('CALL sp_insert_survey(?, ?, ?, ?)');
then fetch the data as a SELECT query.
Upon typing this up, one of the similar questions that came up on the right getting last inserted row id with PDO (not suitable result) gave a suitable answer in the question itself, although I'm a little dubious considering the method is being questioned itself.
$db->lastInsertId();
Seems to work for me, but in the question linked it isn't working as desired for the questioner, so I'm not entirely settled with this answer. It does seem to be a bit of a hack.

Lithium PHP Framework - SQL Insert Ignore / If not exists

is there any way to execute Lithium Model::save() functions with INSERT IGNORE and/or IF NOT EXISTS statements?
The only way to do so is executing RAW-SQL-Statements. But this would be a design violation...so any help would be great.
Thanks in advise.
/creality
There isn't a way to do that with Lithium unless you do the raw SQL. You can see that only "INSERT INTO ..." is supported with the lithium\data\source\Database object.
The reason that this isn't supported is that saving a new object will automatically populate the primary key (id) of the object and an INSERT IGNORE would really complicate the issue.
The best strategy is to run a SELECT based on the key values and then toss out any values that have matching records.

Using Php PDO Insert statement

Someone told me that when you are working with PDO, you cannot use "INSERT INTO .... SET" to insert data into database, because it will not work on databases other than MySQL. I'm not sure what exactly he means, maybe he means I should use the other method of inserting like,
INSERT INTO table (column1, column2) VALUES (?, ?)
I tried searching on the internet for this, but I couldn't find anything. Please let me know about this.
Thank you.
You should use the INSERT INTO table (column1, column2) VALUES (?, ?) statement instead of the INSERT INTO table SET column1=? statement, because that's the correct syntax for SQL based database languages. Although MySQL accepts it, others may not.
The INSERT INTO ... SET syntax is not part of the ANSI SQL standard and therefore is not supported as widely across different RDBMS implementations. If you are designing your application such that it is tightly coupled to MySQL, using this syntax would be OK. If you are trying to design such that your application is not tightly coupled with the RDBMS implementation, then you should use the more standard INSERT INTO table (columns) VALUES (values) syntax.
Positional parameters in PHP PDO is just fine. The other option is named parameters. If I remember correctly from what I've seen in the PDO C code, it is PHP and not the DBM that does the replacements.
http://php.net/manual/en/pdo.prepared-statements.php
As stated in this the only metioned difference, b/n mysql driver and others is stated below. Suppose this is the a simple, query:
<?php
$stmt = $db->query('SELECT * FROM table');
$row_count = $stmt->rowCount();
echo $row_count.' rows selected';
Now, let's read how the documentation states how/why that query can return count of affected_rows only when the mysql driver
NOTE: Though the documentation says this method is only for returning
affected rows from UPDATE, INSERT, DELETE queries, with the PDO_MYSQL
driver (and this driver only) you can get the row count for SELECT
queries. Keep this in mind when writing code for multiple databases.
This is because MySQL's protocol is one of the very few that give this
information to the client for SELECT statements. Most other database
vendors don't bother divulging this information to the client as it
would incur more overhead in their implementations.
So, there is that little difference, as far as I know.

Categories