Inserting multiple SQL statements in codeIgniter - php

I have the following SQL that works directly in MySQL
INSERT INTO `my_tabel` (`data`) VALUES ("my_value");
SELECT * from `my_tabel` ORDER BY `id` DESC LIMIT 1
It inserts a row, and then gets the new row so that I can return the new ID to use later.
When I try to run the SQL in codeIgniter I get an error message stating that I have an error in my SQL
$m = new my_model();
$sql = 'INSERT INTO `my_tabel` (`data`) VALUES ("'.$my_value.'"); SELECT * from `my_tabel` ORDER BY `id` DESC LIMIT 1';
$m->query($sql);
Running a single SQL statement works fine in codeIgniter, but not when I add the second SELECT... statement.
Any ideas (or alternative solutions)?
Thanks

This is not a limitation of CI but that of the database client libraries.
only a single query can be executed at a time.

Why not run two $m->query() statements? That way you can check the success of each individually from CI.
In most SQL interfaces, having multiple statements in a query is problematic because of the different types of result from each. Even when calling a stored procedure, it is necessary to carefully craft the stored procedure not to return extraneous results, though even that can usually be handled with a special, relaxed api which allows multiple results.

insert_id() is your friend!
$this->db->insert_id()
From here http://codeigniter.com/user_guide/database/helpers.html
So something like:
$insert_data = array(
'data' => $my_value
);
$this->db->insert('my_table', $insert_data);
$last_id = $this->db->insert_id();

Instead of running 2 queries, to get the id created after the insert query use:
$this->db->insert_id();

As noted in the other answers, use $this->db->insert_id() is better because there is a chance that another user inserts a row between your two queries. Since PHP can only execute one query at a time, this can become a race condition.

Thanks for everyone's help. The solution that worked for me was
$m = my_model();
$m->data = $value;
$m->save();
echo $m->id;

http://www.codeigniter.com/userguide2/database/active_record.html#caching
You can use Caching to control multiple queries without conflicts.

Related

deleting from two tables in one query mysqli

I want to delete from two tables. I know I can use a join but I came across this post suggesting I could just do it like this with a semicolon:
$query = " DELETE from pupil_data WHERE pupil_id=$pupil_id;
DELETE from pupil_conditions WHERE pupil_id=$pupil_id";
$bob = $conn->query($query);
This doesn't work. If I do each query on their own then its fine.
Why doesn't it work with the semicolon?
try like this
$query = " DELETE from pupil_data WHERE pupil_id=$pupil_id;
DELETE from pupil_conditions WHERE pupil_id=$pupil_id";
$bob = $conn->multi_query($query);
First of all, your query doesn't delete from two tables in one query. There are two separate SQL queries.
Second, you don't need to run 2 queries in one function call. Run two separate queries in two separate function calls. That would be logical and save you a lot of trouble.
Third, never use mysqli_multi_query() for such a whim. This function's purpose is different. Everyone who ask you to use it, never used it in reality and have no idea how to use it properly, helping you to shoot yourself in the foot.
Fourth, you ought to use prepared statements, instead of banging a variable in the query directly.
$stmt = $conn->prepare("DELETE from pupil_data WHERE pupil_id=?");
$stmt->bind_param("s",$pupil_id);
$stmt->execute();
$stmt = $conn->prepare("DELETE from pupil_conditions WHERE pupil_id=?");
$stmt->bind_param("s",$pupil_id);
$stmt->execute();
is the code you have to run.
DELETE table_1, table_2,... FROM table-refs [WHERE conditions]
DELETE FROM table_1, table_2,... USING table-refs [WHERE conditions]
Here is the reference

See how query looks after bind_param() [duplicate]

This question already has answers here:
Getting raw SQL query string from PDO prepared statements
(16 answers)
Closed 6 years ago.
In PHP, when accessing MySQL database with PDO with parametrized query, how can you check the final query (after having replaced all tokens)?
Is there a way to check what gets really executed by the database?
So I think I'll finally answer my own question in order to have a full solution for the record. But have to thank Ben James and Kailash Badu which provided the clues for this.
Short Answer
As mentioned by Ben James: NO.
The full SQL query does not exist on the PHP side, because the query-with-tokens and the parameters are sent separately to the database.
Only on the database side the full query exists.
Even trying to create a function to replace tokens on the PHP side would not guarantee the replacement process is the same as the SQL one (tricky stuff like token-type, bindValue vs bindParam, ...)
Workaround
This is where I elaborate on Kailash Badu's answer.
By logging all SQL queries, we can see what is really run on the server.
With mySQL, this can be done by updating the my.cnf (or my.ini in my case with Wamp server), and adding a line like:
log=[REPLACE_BY_PATH]/[REPLACE_BY_FILE_NAME]
Just do not run this in production!!!
You might be able to use PDOStatement->debugDumpParams. See the PHP documentation .
Using prepared statements with parametrised values is not simply another way to dynamically create a string of SQL. You create a prepared statement at the database, and then send the parameter values alone.
So what is probably sent to the database will be a PREPARE ..., then SET ... and finally EXECUTE ....
You won't be able to get some SQL string like SELECT * FROM ..., even if it would produce equivalent results, because no such query was ever actually sent to the database.
I check Query Log to see the exact query that was executed as prepared statement.
I initially avoided turning on logging to monitor PDO because I thought that it would be a hassle but it is not hard at all. You don't need to reboot MySQL (after 5.1.9):
Execute this SQL in phpMyAdmin or any other environment where you may have high db privileges:
SET GLOBAL general_log = 'ON';
In a terminal, tail your log file. Mine was here:
>sudo tail -f /usr/local/mysql/data/myMacComputerName.log
You can search for your mysql files with this terminal command:
>ps auxww|grep [m]ysqld
I found that PDO escapes everything, so you can't write
$dynamicField = 'userName';
$sql = "SELECT * FROM `example` WHERE `:field` = :value";
$this->statement = $this->db->prepare($sql);
$this->statement->bindValue(':field', $dynamicField);
$this->statement->bindValue(':value', 'mick');
$this->statement->execute();
Because it creates:
SELECT * FROM `example` WHERE `'userName'` = 'mick' ;
Which did not create an error, just an empty result. Instead I needed to use
$sql = "SELECT * FROM `example` WHERE `$dynamicField` = :value";
to get
SELECT * FROM `example` WHERE `userName` = 'mick' ;
When you are done execute:
SET GLOBAL general_log = 'OFF';
or else your logs will get huge.
What I did to print that actual query is a bit complicated but it works :)
In method that assigns variables to my statement I have another variable that looks a bit like this:
$this->fullStmt = str_replace($column, '\'' . str_replace('\'', '\\\'', $param) . '\'', $this->fullStmt);
Where:
$column is my token
$param is the actual value being assigned to token
$this->fullStmt is my print only statement with replaced tokens
What it does is a simply replace tokens with values when the real PDO assignment happens.
I hope I did not confuse you and at least pointed you in right direction.
The easiest way it can be done is by reading mysql execution log file and you can do that in runtime.
There is a nice explanation here:
How to show the last queries executed on MySQL?
I don't believe you can, though I hope that someone will prove me wrong.
I know you can print the query and its toString method will show you the sql without the replacements. That can be handy if you're building complex query strings, but it doesn't give you the full query with values.
I think easiest way to see final query text when you use pdo is to make special error and look error message. I don't know how to do that, but when i make sql error in yii framework that use pdo i could see query text

Why can't I bind a value to this parameter when using PDO? [duplicate]

This question already has answers here:
Getting raw SQL query string from PDO prepared statements
(16 answers)
Closed 6 years ago.
In PHP, when accessing MySQL database with PDO with parametrized query, how can you check the final query (after having replaced all tokens)?
Is there a way to check what gets really executed by the database?
So I think I'll finally answer my own question in order to have a full solution for the record. But have to thank Ben James and Kailash Badu which provided the clues for this.
Short Answer
As mentioned by Ben James: NO.
The full SQL query does not exist on the PHP side, because the query-with-tokens and the parameters are sent separately to the database.
Only on the database side the full query exists.
Even trying to create a function to replace tokens on the PHP side would not guarantee the replacement process is the same as the SQL one (tricky stuff like token-type, bindValue vs bindParam, ...)
Workaround
This is where I elaborate on Kailash Badu's answer.
By logging all SQL queries, we can see what is really run on the server.
With mySQL, this can be done by updating the my.cnf (or my.ini in my case with Wamp server), and adding a line like:
log=[REPLACE_BY_PATH]/[REPLACE_BY_FILE_NAME]
Just do not run this in production!!!
You might be able to use PDOStatement->debugDumpParams. See the PHP documentation .
Using prepared statements with parametrised values is not simply another way to dynamically create a string of SQL. You create a prepared statement at the database, and then send the parameter values alone.
So what is probably sent to the database will be a PREPARE ..., then SET ... and finally EXECUTE ....
You won't be able to get some SQL string like SELECT * FROM ..., even if it would produce equivalent results, because no such query was ever actually sent to the database.
I check Query Log to see the exact query that was executed as prepared statement.
I initially avoided turning on logging to monitor PDO because I thought that it would be a hassle but it is not hard at all. You don't need to reboot MySQL (after 5.1.9):
Execute this SQL in phpMyAdmin or any other environment where you may have high db privileges:
SET GLOBAL general_log = 'ON';
In a terminal, tail your log file. Mine was here:
>sudo tail -f /usr/local/mysql/data/myMacComputerName.log
You can search for your mysql files with this terminal command:
>ps auxww|grep [m]ysqld
I found that PDO escapes everything, so you can't write
$dynamicField = 'userName';
$sql = "SELECT * FROM `example` WHERE `:field` = :value";
$this->statement = $this->db->prepare($sql);
$this->statement->bindValue(':field', $dynamicField);
$this->statement->bindValue(':value', 'mick');
$this->statement->execute();
Because it creates:
SELECT * FROM `example` WHERE `'userName'` = 'mick' ;
Which did not create an error, just an empty result. Instead I needed to use
$sql = "SELECT * FROM `example` WHERE `$dynamicField` = :value";
to get
SELECT * FROM `example` WHERE `userName` = 'mick' ;
When you are done execute:
SET GLOBAL general_log = 'OFF';
or else your logs will get huge.
What I did to print that actual query is a bit complicated but it works :)
In method that assigns variables to my statement I have another variable that looks a bit like this:
$this->fullStmt = str_replace($column, '\'' . str_replace('\'', '\\\'', $param) . '\'', $this->fullStmt);
Where:
$column is my token
$param is the actual value being assigned to token
$this->fullStmt is my print only statement with replaced tokens
What it does is a simply replace tokens with values when the real PDO assignment happens.
I hope I did not confuse you and at least pointed you in right direction.
The easiest way it can be done is by reading mysql execution log file and you can do that in runtime.
There is a nice explanation here:
How to show the last queries executed on MySQL?
I don't believe you can, though I hope that someone will prove me wrong.
I know you can print the query and its toString method will show you the sql without the replacements. That can be handy if you're building complex query strings, but it doesn't give you the full query with values.
I think easiest way to see final query text when you use pdo is to make special error and look error message. I don't know how to do that, but when i make sql error in yii framework that use pdo i could see query text

In PHP with PDO, how to check the final SQL parametrized query? [duplicate]

This question already has answers here:
Getting raw SQL query string from PDO prepared statements
(16 answers)
Closed 6 years ago.
In PHP, when accessing MySQL database with PDO with parametrized query, how can you check the final query (after having replaced all tokens)?
Is there a way to check what gets really executed by the database?
So I think I'll finally answer my own question in order to have a full solution for the record. But have to thank Ben James and Kailash Badu which provided the clues for this.
Short Answer
As mentioned by Ben James: NO.
The full SQL query does not exist on the PHP side, because the query-with-tokens and the parameters are sent separately to the database.
Only on the database side the full query exists.
Even trying to create a function to replace tokens on the PHP side would not guarantee the replacement process is the same as the SQL one (tricky stuff like token-type, bindValue vs bindParam, ...)
Workaround
This is where I elaborate on Kailash Badu's answer.
By logging all SQL queries, we can see what is really run on the server.
With mySQL, this can be done by updating the my.cnf (or my.ini in my case with Wamp server), and adding a line like:
log=[REPLACE_BY_PATH]/[REPLACE_BY_FILE_NAME]
Just do not run this in production!!!
You might be able to use PDOStatement->debugDumpParams. See the PHP documentation .
Using prepared statements with parametrised values is not simply another way to dynamically create a string of SQL. You create a prepared statement at the database, and then send the parameter values alone.
So what is probably sent to the database will be a PREPARE ..., then SET ... and finally EXECUTE ....
You won't be able to get some SQL string like SELECT * FROM ..., even if it would produce equivalent results, because no such query was ever actually sent to the database.
I check Query Log to see the exact query that was executed as prepared statement.
I initially avoided turning on logging to monitor PDO because I thought that it would be a hassle but it is not hard at all. You don't need to reboot MySQL (after 5.1.9):
Execute this SQL in phpMyAdmin or any other environment where you may have high db privileges:
SET GLOBAL general_log = 'ON';
In a terminal, tail your log file. Mine was here:
>sudo tail -f /usr/local/mysql/data/myMacComputerName.log
You can search for your mysql files with this terminal command:
>ps auxww|grep [m]ysqld
I found that PDO escapes everything, so you can't write
$dynamicField = 'userName';
$sql = "SELECT * FROM `example` WHERE `:field` = :value";
$this->statement = $this->db->prepare($sql);
$this->statement->bindValue(':field', $dynamicField);
$this->statement->bindValue(':value', 'mick');
$this->statement->execute();
Because it creates:
SELECT * FROM `example` WHERE `'userName'` = 'mick' ;
Which did not create an error, just an empty result. Instead I needed to use
$sql = "SELECT * FROM `example` WHERE `$dynamicField` = :value";
to get
SELECT * FROM `example` WHERE `userName` = 'mick' ;
When you are done execute:
SET GLOBAL general_log = 'OFF';
or else your logs will get huge.
What I did to print that actual query is a bit complicated but it works :)
In method that assigns variables to my statement I have another variable that looks a bit like this:
$this->fullStmt = str_replace($column, '\'' . str_replace('\'', '\\\'', $param) . '\'', $this->fullStmt);
Where:
$column is my token
$param is the actual value being assigned to token
$this->fullStmt is my print only statement with replaced tokens
What it does is a simply replace tokens with values when the real PDO assignment happens.
I hope I did not confuse you and at least pointed you in right direction.
The easiest way it can be done is by reading mysql execution log file and you can do that in runtime.
There is a nice explanation here:
How to show the last queries executed on MySQL?
I don't believe you can, though I hope that someone will prove me wrong.
I know you can print the query and its toString method will show you the sql without the replacements. That can be handy if you're building complex query strings, but it doesn't give you the full query with values.
I think easiest way to see final query text when you use pdo is to make special error and look error message. I don't know how to do that, but when i make sql error in yii framework that use pdo i could see query text

How to execute SELECT and INSERT in single query with PHP/MYSQL?

I have a table user_name with 3 fields, id, Name, Email (id is auto_increment field). I want to execute the following query in PHP, but its not returning any result.
INSERT INTO user_name (Name, Email) VALUES ('Example', 'example#xyz.com');
SELECT LAST_INSERT_ID() AS 'userid';
When I am executing the above query in PHP as below then its not returning anything.
$_SQL="INSERT INTO user_name (Name,Email) VALUES ('Example', 'example#xyz.com');
SELECT LAST_INSERT_ID() AS 'userid';";
$result_last_id = #mysql_query($_SQL);
$rs_insert = mysql_fetch_array($result_last_id);
$new_userid = $rs_insert['userid'];
Can anyone please tell me how to execute both queries into one.
Give a look to the mysql_insert_id() function.
mysql_query($insertStatementOnly);
$new_userid = mysql_insert_id();
It appears you don't need to execute multiple queries, but I included how to do it below. What you want is the last inserted id, which you get from mysql_insert_id.
To execute multiple queries
From comments on documentation of mysql_query:
The documentation claims that "multiple queries are not supported".
However, multiple queries seem to be supported. You just have to pass flag 65536 as mysql_connect's 5 parameter (client_flags). This value is defined in /usr/include/mysql/mysql_com.h:
#define CLIENT_MULTI_STATEMENTS (1UL << 16) /* Enable/disable multi-stmt support */
Executed with multiple queries at once, the mysql_query function will return a result only for the first query. The other queries will be executed as well, but you won't have a result for them.
Alternatively, have a look at the mysqli library, which has a multi_query method.
Simple answer really: You just can't do it.
http://php.net/mysql_query
May I also suggest you avoid the error-suppression operator '#' in mysql_query as you may not be made aware of any mysql errors. At the very least do
mysql_query($sql) or die("error: " . mysql_error()) ;
If you are using the Zend Framework with a PDO defined MySQL database, you would just use:
$database=Zend_Db::factory('PDO_MySQL',Array('hostname'=>'localhost','username'=>'x','password'=>'y','dbname'=>'z');
$connectionHandle=$database->getConnection();
$rowsInserted=$connectionHandle->insert('database_name','INSERT INTO x (a,b) VALUES (c,d)');
if ($rowsInserted>0) {
$autoIncrementValue=$connectionHandle->lastInsertId();
}
Yes You can using Shell command <BR>
mysql -user -p -h database -e '
SQL STATEMENT 1;
SQL STATEMENT 2;
SQL STATEMENT 3;
.......;
'
Php / MYSQL Programmer
this might do what u want:
insert into table1 (Name,Emails) values ('qqq','www');
select max(id) as lastinserted from table1;

Categories