I have the below function that i want it to retrieve matching records from MySQL Database:
public function GetUserData($conn){
$username = $_SESSION['username'];
$stmt = $conn->prepare("CALL GetUserData(?)") or die("Query fail: " . mysqli_error($conn));
$stmt->bind_param("s",$username);
$stmt->execute() or die("Query fail: " . mysqli_error($conn));
while($row = $stmt->fetch()){
print_r($row);
}
exit;
}
GetUserData is a stored procedure as below:
CREATE DEFINER=`root`#`localhost` PROCEDURE `GetUserData`(IN `StoredUsername` VARCHAR(255))
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
select firstname from users where username=StoredUsername;
END
My problem, is that the print_r($row) only prints "1"
In case the matching rows is two, it prints "11"
I can't seem to figure out what am i using/doing wrong.
Thanks in advance for your assistance.
mysqli_stmt_fetch() is doing not what you think
Username should be passed via parameters
While connection should be a class variable
After getting result, you have to move over additional result returned by procedure, in order to be able to run other queries.
public function GetUserData($username){
$stmt = $this->conn->prepare("CALL GetUserData(?)");
$stmt->bind_param("s",$username);
$stmt->execute();
$data = $stmt->get_result()->fetch_all();
$this->conn->next_result();
return $data;
}
Also, instead of checking result of every database command manually, tell mysqli to throw errors by itself, automatically. Add this line before mysqli_connect and forget all these ugly or die forever:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
Related
I have stored procedure that I created in MySQL and want PHP to call that stored procedure. What is the best way to do this?
-MySQL client version: 4.1.11
-MySQL Server version: 5.0.45
Here is my stored procedure:
DELIMITER $$
DROP FUNCTION IF EXISTS `getNodeName` $$
CREATE FUNCTION `getTreeNodeName`(`nid` int) RETURNS varchar(25) CHARSET utf8
BEGIN
DECLARE nodeName varchar(25);
SELECT name into nodeName FROM tree
WHERE id = nid;
RETURN nodeName;
END $$
DELIMITER ;
What is the PHP code to invoke the procedure getTreeNodeName?
I now found solution by using mysqli instead of mysql.
<?php
// enable error reporting
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
//connect to database
$connection = mysqli_connect("hostname", "user", "password", "db", "port");
//run the store proc
$result = mysqli_query($connection, "CALL StoreProcName");
//loop the result set
while ($row = mysqli_fetch_array($result)){
echo $row[0] . " - " . + $row[1];
}
I found that many people seem to have a problem with using mysql_connect, mysql_query and mysql_fetch_array.
You can call a stored procedure using the following syntax:
$result = mysql_query('CALL getNodeChildren(2)');
This is my solution with prepared statements and stored procedure is returning several rows not only one value.
<?php
require 'config.php';
header('Content-type:application/json');
$connection->set_charset('utf8');
$mIds = $_GET['ids'];
$stmt = $connection->prepare("CALL sp_takes_string_returns_table(?)");
$stmt->bind_param("s", $mIds);
$stmt->execute();
$result = $stmt->get_result();
$response = $result->fetch_all(MYSQLI_ASSOC);
echo json_encode($response);
$stmt->close();
$connection->close();
<?php
$res = mysql_query('SELECT getTreeNodeName(1) AS result');
if ($res === false) {
echo mysql_errno().': '.mysql_error();
}
while ($obj = mysql_fetch_object($res)) {
echo $obj->result;
}
I'm trying to do a simple operation on a MySQL database: my contacts have their complete names on a column called first_name while the column last_name is empty.
So I want to take what's on the first_name column and split it on the first occurrence of a white space and put the first part on the first_name column and the second part on the last_name column.
I use the following code but it's not working:
$connection = new mysqli(DATABASE_SERVER, DATABASE_USERNAME, DATABASE_PASSWORD, DATABASE_NAME, DATABASE_PORT);
$statement = $connection->prepare("SELECT id, first_name FROM contacts");
$statement->execute();
$statement->bind_result($row->id, $row->firstName);
while ($statement->fetch()) {
$names = separateNames($row->firstName);
$connection->query('UPDATE contacts SET first_name="'.$names[0].'", last_name="'.$names[1].'" WHERE id='.$row->id);
}
$statement->free_result();
$statement->close();
$connection->close();
Can I use the $connection->query while having the statement open?
Best regards.
UPDATE
The $connection->query(...) returns FALSE and I get the following error:
PHP Fatal error: Uncaught exception 'Exception' with message 'MySQL Error - 2014 : Commands out of sync; you can't run this command now'
I changed the code to the following and worked:
$connection = new mysqli(DATABASE_SERVER, DATABASE_USERNAME, DATABASE_PASSWORD, DATABASE_NAME, DATABASE_PORT);
$result = $connection->query("SELECT id, first_name FROM contacts");
while ($row = $result->fetch_row()) {
$names = separateNames($row[1]);
$connection->query('UPDATE contacts SET first_name="'.$names[0].'", last_name="'.$names[1].'" WHERE id='.$row[0]);
}
$connection->close();
Can I use the $connection->query while having the statement open?
Yes. It will return a new result object or just a boolean depending on the SQL query, see http://php.net/mysqli_query - In your case of running an UPDATE query it will always return a boolean, FALSE if it failed, TRUE if it worked.
BTW, the Mysqli connection object is not the Mysqli statement object, so they normally do not interfere with each other (disconnecting might destroy/break some statements under circumstances, but I would consider this an edge-case for your question you can ignore for the moment).
I wonder why you ask actually. Maybe you should improve the way you do trouble-shooting?
I can only have one active statement at a given time, so I had to make one of the queries via the $connection->query() method.
As #hakre mentioned:
I still keep my suggestion that you should (must!) do prepared statements instead of query() to properly encode the update values
I opted to use the statement method for the update query, so the final working code is the following:
$connection = new mysqli(DATABASE_SERVER, DATABASE_USERNAME, DATABASE_PASSWORD, DATABASE_NAME, DATABASE_PORT);
$result = $connection->query("SELECT id, first_name FROM contacts");
$statement = $connection->prepare("UPDATE contacts SET first_name=?, last_name=? WHERE id=?");
while ($row = $result->fetch_row()) {
$names = separateNames($row[1]);
$statement->bind_param('ssi', $names[0], $names[1], $row[0]);
throwExceptionOnMySQLStatementError($statement, "Could not bind parameters", $logger);
$statement->execute();
throwExceptionOnMySQLStatementError($statement, "Could not execute", $logger);
}
$statement->free_result();
$statement->close();
$connection->close();
Thanks to all that gave their inputs, specially to #hakre that helped me to reach this final solution.
As an example, suppose I want to execute the following query:
SELECT * FROM posts;
Therefore, I write the following:
CREATE DEFINER=`root`#`localhost` PROCEDURE `get_posts`(IN `zip` INT)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
SELECT * FROM posts WHERE posts.zip = zip;
END
Is the following change the only one I have to make:
mysql_query("SELECT * FROM posts");
// to
mysql_query("CALL get_posts");
...and then I can fetch rows, etc.?
you also need to supply the parameter
mysql_query("CALL get_posts(11)");
another suggestion is by using PDO extension on this.
Example of using PDO,
<?php
$zipCode = 123;
$stmt = $dbh->prepare("CALL get_posts(?)");
$stmt->bindParam(1, $zipCode);
if ($stmt->execute(array($_GET['columnName'])))
{
while ($row = $stmt->fetch())
{
print_r($row);
}
}
?>
this will protect you from SQL Injection.
Your procedure expects an input parameter, so call it with one:
$result = mysql_query("CALL get_posts(12345)");
This will supply a result resource on a successful call, then you can run a fetch loop as you would a normal query.
if ($result) {
// fetch in a while loop like you would any normal SELECT query...
}
In an effort to make my scripts more secure, I have started using prepared statements to prevent mysql injection. This script inserts the data just fine, but getting the last inserted id (based on auto incrementation in the database) now returns 0 when it should return the correct id number.
This part inserts just fine.
$stmt = $conn->prepare("INSERT INTO users (userName) VALUES (?)");
$stmt->bind_param("s", $_SESSION['username']);
$stmt->execute();
This is where I am having problems. I am trying to get the last inserted ID of the user and it is returning 0.
// Get the last inserted ID for the users ID
$query = "SELECT LAST_INSERT_ID()";
$result = mysql_query($query);
if ($result) {
$nrows = mysql_num_rows($result);
$row = mysql_fetch_row($result);
$userId = $row[0];
}
This was working when I had my script before starting on Prepared Statements. The only thing I changed was adding the Prepared Statement to insert the data and my db connection is as follows:
$conn = new mysqli($server, $user, $password, $database) or die('Could not connect: ' . mysql_error());
I am a noob with php so any help would be greatly appreciated.
You may have a fundamental misunderstanding: When you switch to mysqli, your mysql_* functions will no longer use the same connection.
LAST_INSERT_ID() works on a per-connection basis.
You will have to make that query using the same library/connection as the main query, or as #zerkms points out, use $conn->insert_id.
mysqli_insert_id().
I have stored procedure that I created in MySQL and want PHP to call that stored procedure. What is the best way to do this?
-MySQL client version: 4.1.11
-MySQL Server version: 5.0.45
Here is my stored procedure:
DELIMITER $$
DROP FUNCTION IF EXISTS `getNodeName` $$
CREATE FUNCTION `getTreeNodeName`(`nid` int) RETURNS varchar(25) CHARSET utf8
BEGIN
DECLARE nodeName varchar(25);
SELECT name into nodeName FROM tree
WHERE id = nid;
RETURN nodeName;
END $$
DELIMITER ;
What is the PHP code to invoke the procedure getTreeNodeName?
I now found solution by using mysqli instead of mysql.
<?php
// enable error reporting
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
//connect to database
$connection = mysqli_connect("hostname", "user", "password", "db", "port");
//run the store proc
$result = mysqli_query($connection, "CALL StoreProcName");
//loop the result set
while ($row = mysqli_fetch_array($result)){
echo $row[0] . " - " . + $row[1];
}
I found that many people seem to have a problem with using mysql_connect, mysql_query and mysql_fetch_array.
You can call a stored procedure using the following syntax:
$result = mysql_query('CALL getNodeChildren(2)');
This is my solution with prepared statements and stored procedure is returning several rows not only one value.
<?php
require 'config.php';
header('Content-type:application/json');
$connection->set_charset('utf8');
$mIds = $_GET['ids'];
$stmt = $connection->prepare("CALL sp_takes_string_returns_table(?)");
$stmt->bind_param("s", $mIds);
$stmt->execute();
$result = $stmt->get_result();
$response = $result->fetch_all(MYSQLI_ASSOC);
echo json_encode($response);
$stmt->close();
$connection->close();
<?php
$res = mysql_query('SELECT getTreeNodeName(1) AS result');
if ($res === false) {
echo mysql_errno().': '.mysql_error();
}
while ($obj = mysql_fetch_object($res)) {
echo $obj->result;
}