From PHP I would like to call a stored procedure in MySQL. The procedure takes input and output parameters -- not "INOUT" parameters.
For a simple example, say I have the following stored procedure in MySQL:
DELIMITER $$
DROP PROCEDURE IF EXISTS `test_proc`$$
CREATE PROCEDURE `test_proc`(
in input_param_1 int,
in input_param_2 int,
in input_param_3 int,
out output_sum int,
out output_product int,
out output_average int
)
BEGIN
set output_sum = input_param_1 + input_param_2 + input_param_3;
set output_product = input_param_1 * input_param_2 * input_param_3;
set output_average = (input_param_1 + input_param_2 + input_param_3) / 3;
END$$
DELIMITER ;
Now, from the PHP script/page side, say I have the following variables (we'll call them "proc input variables") that I want to feed to the stored procedure as input parameters when I call it:
$procInput1 = "123";
$procInput2 = "456";
$procInput3 = "789";
Let's say that on the PHP script/page side I also have the following variables (we'll call them "proc output variables") that I want to feed to the stored procedure as output parameters to be set by the stored procedure when I call it:
$procOutput_sum;
$procOutput_product;
$procOutput_average;
So, in essence, on the PHP script/page side, what I want to be able to do, in essence (I realize the following code is not valid), is...
call test_proc($procInput1, $procInput2, $procInput3, $procOutput_sum, $procOutput_product, $procOutput_average);
...and, once called, the following PHP code...
echo "Sum: ".$procOutput_sum;
echo "Product: ".$procOutput_product;
echo "Average: ".$procOutput_average;
...should produce the following output:
Sum: 1368
Product: 44253432
Average: 456
One caveat is that, if at all possible, I would like to be able to do this using the MySQLi procedural functions/interface. If not possible, then however I can get it to work is what I'll use.
I have been programming for quite some time, but the PHP language is a relatively new endeavor for me. I have found tons of tutorials on calling MySQL stored procedures from PHP. Some are tutorials on calling stored procedures with input parameters, some are tutorials on calling stored procedures with output parameters, and some are tutorials on calling stored procedures with inout parameters. I have not found any tutorials or examples on calling stored procedures that take both input and output parameters at the same time, while specifically not using "inout" parameters. I'm having trouble figuring out how to code the parameter bindings (e.g.: mysqli_stmt_bind_param and mysqli_stmt_bind_result) and getting it all to work properly.
Any help will be greatly appreciated and I give thanks in advance!
Unfortunately, MySQLi does not have any native support for output sproc parameters; one must instead output into MySQL user variables and then fetch the values using a separate SELECT statement.
Using the procedural interface:
$procInput1 = 123;
$procInput2 = 456;
$procInput3 = 789;
$mysqli = mysqli_connect();
$call = mysqli_prepare($mysqli, 'CALL test_proc(?, ?, ?, #sum, #product, #average)');
mysqli_stmt_bind_param($call, 'iii', $procInput1, $procInput2, $procInput3);
mysqli_stmt_execute($call);
$select = mysqli_query($mysqli, 'SELECT #sum, #product, #average');
$result = mysqli_fetch_assoc($select);
$procOutput_sum = $result['#sum'];
$procOutput_product = $result['#product'];
$procOutput_average = $result['#average'];
Or, using the object-oriented interface:
$procInput1 = 123;
$procInput2 = 456;
$procInput3 = 789;
$mysqli = new mysqli();
$call = $mysqli->prepare('CALL test_proc(?, ?, ?, #sum, #product, #average)');
$call->bind_param('iii', $procInput1, $procInput2, $procInput3);
$call->execute();
$select = $mysqli->query('SELECT #sum, #product, #average');
$result = $select->fetch_assoc();
$procOutput_sum = $result['#sum'];
$procOutput_product = $result['#product'];
$procOutput_average = $result['#average'];
DB::select('call SP_fci_cb_emp_comp_salary_revision_add(?,?,?,#,#)',
[
$my_compensation['detail']['employee_master_id'],
Carbon::createFromFormat('d/m/Y', $salary_revised_result['detail']->effective_date)->format('Y-m-d'),
$request->user_id
]);
Related
From PHP I would like to call a stored procedure in MySQL. The procedure takes input and output parameters -- not "INOUT" parameters.
For a simple example, say I have the following stored procedure in MySQL:
DELIMITER $$
DROP PROCEDURE IF EXISTS `test_proc`$$
CREATE PROCEDURE `test_proc`(
in input_param_1 int,
in input_param_2 int,
in input_param_3 int,
out output_sum int,
out output_product int,
out output_average int
)
BEGIN
set output_sum = input_param_1 + input_param_2 + input_param_3;
set output_product = input_param_1 * input_param_2 * input_param_3;
set output_average = (input_param_1 + input_param_2 + input_param_3) / 3;
END$$
DELIMITER ;
Now, from the PHP script/page side, say I have the following variables (we'll call them "proc input variables") that I want to feed to the stored procedure as input parameters when I call it:
$procInput1 = "123";
$procInput2 = "456";
$procInput3 = "789";
Let's say that on the PHP script/page side I also have the following variables (we'll call them "proc output variables") that I want to feed to the stored procedure as output parameters to be set by the stored procedure when I call it:
$procOutput_sum;
$procOutput_product;
$procOutput_average;
So, in essence, on the PHP script/page side, what I want to be able to do, in essence (I realize the following code is not valid), is...
call test_proc($procInput1, $procInput2, $procInput3, $procOutput_sum, $procOutput_product, $procOutput_average);
...and, once called, the following PHP code...
echo "Sum: ".$procOutput_sum;
echo "Product: ".$procOutput_product;
echo "Average: ".$procOutput_average;
...should produce the following output:
Sum: 1368
Product: 44253432
Average: 456
One caveat is that, if at all possible, I would like to be able to do this using the MySQLi procedural functions/interface. If not possible, then however I can get it to work is what I'll use.
I have been programming for quite some time, but the PHP language is a relatively new endeavor for me. I have found tons of tutorials on calling MySQL stored procedures from PHP. Some are tutorials on calling stored procedures with input parameters, some are tutorials on calling stored procedures with output parameters, and some are tutorials on calling stored procedures with inout parameters. I have not found any tutorials or examples on calling stored procedures that take both input and output parameters at the same time, while specifically not using "inout" parameters. I'm having trouble figuring out how to code the parameter bindings (e.g.: mysqli_stmt_bind_param and mysqli_stmt_bind_result) and getting it all to work properly.
Any help will be greatly appreciated and I give thanks in advance!
Unfortunately, MySQLi does not have any native support for output sproc parameters; one must instead output into MySQL user variables and then fetch the values using a separate SELECT statement.
Using the procedural interface:
$procInput1 = 123;
$procInput2 = 456;
$procInput3 = 789;
$mysqli = mysqli_connect();
$call = mysqli_prepare($mysqli, 'CALL test_proc(?, ?, ?, #sum, #product, #average)');
mysqli_stmt_bind_param($call, 'iii', $procInput1, $procInput2, $procInput3);
mysqli_stmt_execute($call);
$select = mysqli_query($mysqli, 'SELECT #sum, #product, #average');
$result = mysqli_fetch_assoc($select);
$procOutput_sum = $result['#sum'];
$procOutput_product = $result['#product'];
$procOutput_average = $result['#average'];
Or, using the object-oriented interface:
$procInput1 = 123;
$procInput2 = 456;
$procInput3 = 789;
$mysqli = new mysqli();
$call = $mysqli->prepare('CALL test_proc(?, ?, ?, #sum, #product, #average)');
$call->bind_param('iii', $procInput1, $procInput2, $procInput3);
$call->execute();
$select = $mysqli->query('SELECT #sum, #product, #average');
$result = $select->fetch_assoc();
$procOutput_sum = $result['#sum'];
$procOutput_product = $result['#product'];
$procOutput_average = $result['#average'];
DB::select('call SP_fci_cb_emp_comp_salary_revision_add(?,?,?,#,#)',
[
$my_compensation['detail']['employee_master_id'],
Carbon::createFromFormat('d/m/Y', $salary_revised_result['detail']->effective_date)->format('Y-m-d'),
$request->user_id
]);
Here's my stored procedure:
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `testProc`(INOUT num INT(11), INOUT num2 INT(11))
BEGIN
set num2 = num+7;
END
Here's the code that calls it:
$newId = 1;
$type - 2;
if ($stmt = mysqli_prepare($con, 'call testProc(?,?)')) {
mysqli_stmt_bind_param($stmt, 'ii', $type,$newId);
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt, $type,$newId);
echo $newId;
exit;
}
I expected $newId to hold 9. It still holds 1.
mysqli_stmt_bind_result() seems redundant, as I don't actually have a result set (and I think its existence causes bugs later because I don't have a result set), but this code falls over without it (My actual code doesn't but I don't know why). That's may be moot though.
Please can anyone show me how to change this code to make it work?
The PHP manual states that you've got to use session variables (MySQL sessions, not PHP)
INOUT/OUT parameter
The values of INOUT/OUT parameters are accessed using session variables.
mysqli_stmt_bind_result() is to be used to bind values from a resultset like a SELECT statement. This could be a SELECT statement in a stored procedure, see the chapter Stored Routine Syntax of the MySQL manual:
MySQL supports a very useful extension that enables the use of regular
SELECT statements (that is, without using cursors or local variables)
inside a stored procedure. The result set of such a query is simply
sent directly to the client.
So you could do it with
// set your IN parameter using a prepared statement
if ($stmt = mysqli_prepare($con, 'SET #type := ?')) {
mysqli_stmt_bind_param($stmt, 'i', $type);
mysqli_stmt_execute($stmt);
}
// do the same for your second parameter
if ($stmt = mysqli_prepare($con, 'SET #newId := ?')) {
mysqli_stmt_bind_param($stmt, 'i', $newId);
mysqli_stmt_execute($stmt);
}
// No need to use a prepared statement for the procedure call anymore
$result = mysqli_query($con, 'call testProc(#type, #newId)');
// If the procedure would return something else than the INOUT or OUT parameter
// then you would get this result now
// getting the value of the INOUT parameter
$result = mysqli_query($con, 'SELECT #newId as newId');
$row = mysqli_fetch_assoc($result);
var_dump($row);
Output:
Connected to databasearray(1) {
["newId"]=>
string(1) "9"
}
Note:
Error handling left as an exercise to show only the main issue.
I am using procedure first time.How can I fetch data using procedure.I created this procedure in sql file.
CREATE PROCEDURE `GetUserProfile`(IN p_user_id INT, IN p_enabled BIT)
READS SQL DATA
BEGIN
# prepare init params
if p_user_id = 0 then
set p_user_id = null;
end if;
select parent_user_id
,user_id
,Last_name
,First_name
,email as Email_address
,mobile as Phone
from app_users
where app_user_id = IFNULL(p_user_id, user_id)
and enabled = IFNULL(p_enabled, enabled);
then How can I fetch the user detail through PHP like First_name,Last_name etc.
thanks
Do you can use sqlsrv_connect function to connect to SQL Server db, use sqlsrv_prepare function to call tsql function and $params args and, at last, use one of the sqlsrv_fetch_* function to retrieve data.
see instruction on this page:
http://technet.microsoft.com/en-us/library/cc793139(v=sql.90).aspx
You can use PDO to execute a mysql stored procedure and access the results.
See the examples on this page from the PHP Documentation. In particular example #4
<?php
$stmt = $dbh->prepare("CALL sp_returns_string(?)");
$stmt->bindParam(1, $return_value, PDO::PARAM_STR, 4000);
// call the stored procedure
$stmt->execute();
print "procedure returned $return_value\n";
?>
and example #5
<?php
$stmt = $dbh->prepare("CALL sp_takes_string_returns_string(?)");
$value = 'hello';
$stmt->bindParam(1, $value, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000);
// call the stored procedure
$stmt->execute();
print "procedure returned $value\n";
?>
If you haven't used PDO before I'd suggest browsing through the documentation, creating a new PDO object to manipulate a dabase is as simple as:
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass);
From PHP I would like to call a stored procedure in MySQL. The procedure takes input and output parameters -- not "INOUT" parameters.
For a simple example, say I have the following stored procedure in MySQL:
DELIMITER $$
DROP PROCEDURE IF EXISTS `test_proc`$$
CREATE PROCEDURE `test_proc`(
in input_param_1 int,
in input_param_2 int,
in input_param_3 int,
out output_sum int,
out output_product int,
out output_average int
)
BEGIN
set output_sum = input_param_1 + input_param_2 + input_param_3;
set output_product = input_param_1 * input_param_2 * input_param_3;
set output_average = (input_param_1 + input_param_2 + input_param_3) / 3;
END$$
DELIMITER ;
Now, from the PHP script/page side, say I have the following variables (we'll call them "proc input variables") that I want to feed to the stored procedure as input parameters when I call it:
$procInput1 = "123";
$procInput2 = "456";
$procInput3 = "789";
Let's say that on the PHP script/page side I also have the following variables (we'll call them "proc output variables") that I want to feed to the stored procedure as output parameters to be set by the stored procedure when I call it:
$procOutput_sum;
$procOutput_product;
$procOutput_average;
So, in essence, on the PHP script/page side, what I want to be able to do, in essence (I realize the following code is not valid), is...
call test_proc($procInput1, $procInput2, $procInput3, $procOutput_sum, $procOutput_product, $procOutput_average);
...and, once called, the following PHP code...
echo "Sum: ".$procOutput_sum;
echo "Product: ".$procOutput_product;
echo "Average: ".$procOutput_average;
...should produce the following output:
Sum: 1368
Product: 44253432
Average: 456
One caveat is that, if at all possible, I would like to be able to do this using the MySQLi procedural functions/interface. If not possible, then however I can get it to work is what I'll use.
I have been programming for quite some time, but the PHP language is a relatively new endeavor for me. I have found tons of tutorials on calling MySQL stored procedures from PHP. Some are tutorials on calling stored procedures with input parameters, some are tutorials on calling stored procedures with output parameters, and some are tutorials on calling stored procedures with inout parameters. I have not found any tutorials or examples on calling stored procedures that take both input and output parameters at the same time, while specifically not using "inout" parameters. I'm having trouble figuring out how to code the parameter bindings (e.g.: mysqli_stmt_bind_param and mysqli_stmt_bind_result) and getting it all to work properly.
Any help will be greatly appreciated and I give thanks in advance!
Unfortunately, MySQLi does not have any native support for output sproc parameters; one must instead output into MySQL user variables and then fetch the values using a separate SELECT statement.
Using the procedural interface:
$procInput1 = 123;
$procInput2 = 456;
$procInput3 = 789;
$mysqli = mysqli_connect();
$call = mysqli_prepare($mysqli, 'CALL test_proc(?, ?, ?, #sum, #product, #average)');
mysqli_stmt_bind_param($call, 'iii', $procInput1, $procInput2, $procInput3);
mysqli_stmt_execute($call);
$select = mysqli_query($mysqli, 'SELECT #sum, #product, #average');
$result = mysqli_fetch_assoc($select);
$procOutput_sum = $result['#sum'];
$procOutput_product = $result['#product'];
$procOutput_average = $result['#average'];
Or, using the object-oriented interface:
$procInput1 = 123;
$procInput2 = 456;
$procInput3 = 789;
$mysqli = new mysqli();
$call = $mysqli->prepare('CALL test_proc(?, ?, ?, #sum, #product, #average)');
$call->bind_param('iii', $procInput1, $procInput2, $procInput3);
$call->execute();
$select = $mysqli->query('SELECT #sum, #product, #average');
$result = $select->fetch_assoc();
$procOutput_sum = $result['#sum'];
$procOutput_product = $result['#product'];
$procOutput_average = $result['#average'];
DB::select('call SP_fci_cb_emp_comp_salary_revision_add(?,?,?,#,#)',
[
$my_compensation['detail']['employee_master_id'],
Carbon::createFromFormat('d/m/Y', $salary_revised_result['detail']->effective_date)->format('Y-m-d'),
$request->user_id
]);
I'm using PHP to process some XML that I'm getting from a web service and to insert the results into a database. I've created a stored procedure to insert the records and I'm using PDO to prepare a statement that I'd then like to execute multiple times, something like this:
$st = $this->db->prepare('CALL AddClient(:Name, :Id, :Priority, :Territory, :DateCreated, :Result)');
$st->bindParam(':Name', $Name, PDO::PARAM_STR);
$st->bindParam(':Id', $Id, PDO::PARAM_INT);
$st->bindParam(':Priority', $Priority, PDO::PARAM_STR);
$st->bindParam(':Territory', $Territory, PDO::PARAM_STR);
$st->bindParam(':DateCreated', $dateFormat, PDO::PARAM_STR);
$st->bindParam(':Result', $result, PDO::PARAM_STR);
foreach ($this->xml->AccountsDataSet->MainRecord as $Account) {
$Name = (string) $Account->AcctDesc;
$Id = (int) $Account->AcctID;
if ($num = (int)$Account->CDF309607) {
$Priority = self::$priorityFields[$num];
} else {
$Priority = '';
}
if (! $Territory = (string) $Account->AcctState) {
$Territory = '';
}
$date = new DateTime($Account->AcctCreationDate, new DateTimeZone('UTC'));
$dateFormat = $date->format('Y-m-d H:i:s');
$st->execute();
echo $result . '<br />';
}
In this example ':Result' would be a output value from the procedure. I cannot make this work at all though. If I omit the out put parameter both in the procedure code and PHP then one row gets inserted but subsequent calls in the loop fail. To make this work I have to prepare the statement fresh each time in the loop, then binding the parameters to the statement again. I still cannot make this work with an output parameter in the procedure and have to Select a value in the procedure to get some return value to PHP to process.
Does anyone know where I'm going wrong with this? Ideally I'd like to prepare the statement once and then loop through the results, executing it each time with fresh data. Are there any tricks that I'm missing to make all of this work? I'm developing on Windows 7 with Apache 2.2.17, PHP 5.3.5 and MySQL 5.5.8.
EDIT:
Well, the answer to executing the statement multiple times in the loop seems to be to call the PDOStatement::closeCursor() method each time after calling PDOStatement::execute(). Still no idea on how to get the value of an output parameter returned to PHP though.
EDIT
Here's the code for the procedure:
CREATE
PROCEDURE foo.AddClient(IN ClientName VARCHAR(255), IN Client_Id INT UNSIGNED, IN Priority VARCHAR(255), IN Territory VARCHAR(100), IN DateCreated DATETIME, OUT Result VARCHAR(100))
COMMENT 'Procedure to add a new client to the database'
BEGIN
#Declare variables.
DECLARE Priority_Id, Territory_Id TINYINT UNSIGNED DEFAULT NULL;
# Check if a Priority is defined. If so get the id, if not add it and get the id
IF LENGTH(Priority) > 0 THEN
SELECT
PriorityId
INTO
Priority_Id
FROM
client_priority
WHERE
Name = Priority;
IF Priority_Id IS NULL THEN
INSERT INTO client_priority (Name) VALUES (Priority);
SET Priority_Id = LAST_INSERT_ID();
END IF;
END IF;
#Check if a Territory is defined. If so get the id, if not add it and get the id.
IF LENGTH(Territory) > 0 THEN
SELECT
TerritoryId
INTO
Territory_Id
FROM
territories
WHERE
Name = Territory;
IF Territory_Id IS NULL THEN
INSERT INTO territories (Name) VALUES (Territory);
SET Territory_Id = LAST_INSERT_ID();
END IF;
END IF;
#Add the details of the client.
BEGIN
DECLARE EXIT HANDLER FOR SQLSTATE '23000'
SET Result = 'Client already exists'; # Error handler in case client with the same name already exists.
INSERT INTO clients
(ClientId, Name, PriorityId, TerritoryId, DateCreatedSalesNet) VALUES (Client_Id, ClientName, Priority_Id, Territory_Id, DateCreated);
SET Result = 'Client Inserted';
END;
END
The fact is you can't access you result like this, see these posts :
http://bugs.mysql.com/bug.php?id=25970
http://dev.mysql.com/doc/refman/5.0/en/call.html
So you will need to store the result into a MySQL var, then you can display it, like this :
<?php
// change
$st = $this->db->prepare('CALL AddClient(:Name, :Id, :Priority, :Territory, :DateCreated, :Result)');
// to
$st = $this->db->prepare('CALL AddClient(:Name, :Id, :Priority, :Territory, :DateCreated, #result)');
// remove this line
$st->bindParam(':Result', $result, PDO::PARAM_STR);
// change
$st->execute();
echo $result . '<br />';
// to
$st->execute();
echo $this->db->query('SELECT #result')->fetchColumn() . '<br />';
Try adding a string length to the output parameter:
$st->bindParam(':Result', $result, PDO::PARAM_STR, 4000);
Try to add PDO::PARAM_INPUT_OUTPUT:
$st->bindParam(':Result', $result, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000);