Stored procedure that accepts multiple parameters - php

It's my first time working with stored procedures.
The previous developer already had a stored procedure in place that works, but it only accepts 1 parameter.
I am using PHP to pass the parameters:
<?php
$containers = $_POST['cntnum'];
$shortened = array();
foreach($containers as $short)
{
$shortened[] = substr($short, 0, 10);
}
$sans_check = preg_replace('/\n$/','',preg_replace('/^\n/','',preg_replace('/[\r\n]+/',"\n",$shortened)));
$sans = "'" . implode("', '", $sans_check) ."'";
// At this point, $sans looks like this: 'value1', 'value2', 'value3'...
// now I send $sans to the stored procedure
$thecall = mysqli_query($dbc, "CALL SP_ContSearch_TEST($sans)");
?>
I can send 1 value with no problem. I get back the data. But when there are more than 1, I get the following error:
Incorrect number of arguments for PROCEDURE table.storeprocedure; expected 1, got 3
Here is what the stored procedure looks like (shortened for time):
Begin
DECLARE sans_check varchar(100); // adjusted from 10, but same error message
SET sans_check = SUBSTR(cont,1,10);
SELECT
`inventory`
,delivery_date
,pool
FROM
inventory
WHERE
CONTAINER_CHECK IN (cont);
END
The parameter cont is varchar(11) // not sure if that means anything
This is my first attempting a stored procedure call, and I can return data for one value. I need to return data for multiple values.

The error message is absolutely right. You are sending 3 parameters to a stores procedure which takes only one.
What you've done is you have modified the stored proc which takes a single string such that it still expects a single string.
You should modify the definition of the stored procedure to take 3 parameters (that part is missing in your question)
Here is an example of a stored proc declaration with 3 parameters:
CREATE PROCEDURE SP_ContSearch_TEST
(IN sans1 CHAR(10),
IN sans2 CHAR(10),
IN sans3 CHAR(10)
-- add as many other parameters here as you need
)
BEGIN
-- your stored proc logic here.. can use sans1, sans2, and sans3
END
You should also change your code to use parameterized queries instead of the way you're doing right now. See: http://php.net/manual/en/pdo.prepared-statements.php or http://php.net/manual/en/mysqli.prepare.php

Related

Using PDO to retrieve an output parameter from a stored procedure in mysql

Before this is closed as a duplicate out of hand, let me say that there are a few questions that ask this on Stack Overflow, but none of them have marked answers, and the unmarked ones didn't work for me.
In my MySql database, I have a simple procedure:
DELIMITER //
CREATE PROCEDURE foo (
IN a INT,
OUT b INT
) BEGIN
SELECT a INTO b;
END //
DELIMITER ;
If I call this in phpMyAdmin, I get what I expect:
SELECT 2 INTO #b;
CALL foo(1, #b);
SELECT #b;
| #b |
+----+
| 1 |
When I try to call this from my php code, however, stmt->execute() returns false.
$a = 1;
$pdoLink = get_pdo_connection($db);
$stmt = $pdoLink->prepare('CALL `mydb`.`foo`(:a, :b)');
$stmt->bindParam(':a', $a);
$stmt->bindParam(':b', $b, PDO::PARAM_INT, 4);
// I've also tried length values of 1, 2, and 16
$stmt->execute(); // returns false
I thought maybe it had to do with calling a procedure in the first place, so I replaced my procedure with:
DELIMITER //
CREATE PROCEDURE foo (
IN a INT,
IN b INT
) BEGIN
SELECT a, b;
END //
DELIMITER ;
This, however, does work from php, so it must be something having to do with output parameters. I'm using code that's only slightly altered from the PDO Documentation, so I really have no idea what's wrong with it.
I am not looking for an answer that uses mysqli's multi_query to do something like
$sql = "CALL `mydb`.`foo`(1, #b);
SELECT #b;";
$link->multi_query($sql);
// ...
I'm looking for how to do this using PDO and a single query.
Someone tried to mark this as a duplicate of Calling stored procedure with Out parameter using PDO. The marked answer to this question uses multiple queries.
You say you used phpMyAdmin to test if your query works, but phpMyAdmin is built in PHP and uses mySQL Improved, so the problem is not on PHP.
Or better, to talk with MySQL you have to go through a driver that interprets the data between PHP and a system library; usually the libmysql, this interfaces with the MySQL server. It's all too complicated!
Many information on the web, say to set the PDO :: ATTR_EMULATE_PREPARES to false, to prevent the PHP emulates the preparation of the parameters passed to the query.
Other information, always taken from the web, they say to do it only if the PHP is compiled through the php5-mysqlnd module.
In practice I noticed that the best way for me was to cast the variables that carry non-string values.
So your code could become
...
$stmt->bindParam(':a', (int)$a);
$stmt->bindParam(':b', (int)$b, PDO::PARAM_INT, 4);
...
My two cents

Using stored procedure with an OUT parameter in Laravel

I'm having a problem calling a stored procedure that has two OUT parameters. I cannot access them.
Here is my procedure's first line:
PROCEDURE `validate_reservation`(IN people INT, IN r_date DATETIME,IN place_id INT,IN max_people INT,IN more_people TINYINT(1),OUT r_status CHAR(20),OUT message CHAR(100))
And here is how I call it from Laravel 5:
DB::statement("call validate_reservation(4,'2016-04-26 20:30',1,10,1,$status,$message)");
I don't know if I have to pass two empty variables and they will turn the values of the output or if that is the return of the statement.
If I pass two empty variables Laravel tells me they are not defined. If I don't pass them, Laravel tells me the procedure is waiting for 7 parameters instead of 5.
With OUT parameters, you're dealing with MySQL variables - these are prefixed with #.
So, use #status, #message instead of $status, $message. Also, you may want to use binding to pass the other values.
These won't populate PHP variables in any case. If you want to get them in PHP, you'll need to SELECT them, e.g. SELECT #status, #message using DB::select.
This way work for me:
DB::select("call validate_reservation(4,'2016-04-26 20:30',1,10,1,#status,#message)");
$results = DB::select('select #status as status, #message as message ');
return dd($results[0]->message);

jTable jQuery plugin why is my MySQL stored procedure failing?

I am trying to implement a filter in jTable. Here is the jTable Filtering Demo.
I used the jQuery code supplied by the demo to sucessfully send POST data to the listAction php script. I access this data and assign it to the $filter variable. I also add two wildcards before and after the string to tell MySQL to perform a comprehensive search rather then an index search.
$filter = '%';
$filter .= $_POST['name'];
$filter .= '%';
$startIndex = $_GET['jtStartIndex'];
$pageSize = $_GET['jtPageSize'];
$sorting = $_GET['jtSorting'];
I then call the stored procedure and pass in each variable. I removed actual database and procedure name, but I verified they are correct.
$mysqli->query("USE data;");
$res = $mysqli->query("CALL proced($startIndex, $pageSize, $filter);");
$res returns false here.
Calling Stored Procedures DEFINITELY works as I have other functionalities working this way. I have other Stored Procedures working that simply return 0 to 9 records correctly. Here is the current Stored Procedure code:
CREATE DEFINER=`root`#`localhost` PROCEDURE `proced`(startIndex INTEGER, pageSize INTEGER, filter VARCHAR(255))
BEGIN
SELECT * FROM reports
WHERE `new`=0 AND ReportingName LIKE filter
ORDER BY idReports ASC
LIMIT startIndex, pageSize;
END
Passing in values in MySQL workbench works and the query returns the correct rows:
call proced(
0,
10,
'Art%'
);
But jTable fails with "An error occured while communicating to the server."
Can anyone point me in the right direction?
Got this working by getting an error back from MySQL:
if(!$res){
ChromePhp::log($mysqli->error);
die('error ['. $mysqli->error . ']');
}
Error:
Unknown column 'Art' in 'field list'
Solution(copied from link):
Try using different quotes for "Art" as the identifier quote character is the backtick (“`”). Otherwise MySQL "thinks" that you point to a column named "Art".
See also MySQL 5 Documentation
So simply by adding single quotes to the passed in String parameter works:
CALL procedure('$filter');

Could you please assist me with PHP 5.3 and MySQL 5.5 stored procedures and mysqli library + persistent connection

Helo,
I have a stored procedure that has 7 IN parameters and 3 OUT parameters.
I need to pass 7 parameters IN from PHP, execute the query with procedure, and retrieve the 3 OUT parameters.
I am using mysqli with persistent connection mode enabled. (For load considerations)
What is the most efficient way to execute the query and get results?
I need something that doesn't affect other concurrently running PHP scripts, and that cleans the result itself, and that is straightforward.
This is what my application is (simplified) (not a working example, just how i wish it was)
$inParam1 = 'wer';
$inParam2 = 'fewf';
$inParam3 = 'dsf';
$inParam4 = 'vccv';
$inParam5 = '34t3';
$inParam6 = 'ter';
$inParam7 = 'ert';
$query = "CALL my_procedure('$inParam1', '$inParam2', '$inParam3', '$inParam4', '$inParam5', '$inParam6', '$inParam7', #outParam8, #outParam9, #outParam10); SELECT #outParam8, #outParam9, #outParam10;";
$result = $mysql_query($query);
list($outParam1, $outParam2, $outParam3) = mysql_fetch_array($result);
echo $outParam1; // String param #1 that my procedure returned as an OUT variable
echo $outParam2; // String param #2 that my procedure returned as an OUT variable
echo $outParam3; // String param #3 that my procedure returned as an OUT variable
If somebody could show how this code could look in reality, please please would be great!
I am obviously using mysqli with proper connection, and such, but the examples I have found in internet are really confusing and seem to be inefficient, I am also worried if it will conflict with other clients, because it works like "nextResult" and other some strange functions.
Many thanks!
PHP 5.3, MySQL 5.5
Try looking here. As im not overly familiar with this. :)
http://www.mysqltutorial.org/stored-procedures-parameters.aspx
You need to create a query first. This query will then be stored in the database as a callable procedure. Then later using whatever language you can call the procedure.
DELIMITER //
CREATE PROCEDURE GetUserByCountry(IN countryName VARCHAR(255))
BEGIN
SELECT name, email
FROM users
WHERE country = countryName;
END //
DELIMITER ;
Then calling it.
CALL GetUserByCountry('mexico')
Returns all users names and emails who live in mexico.
I believe if you want to create a dynamic query string such as yours, you need to put {} around your variables in the string.
$query = "CALL my_procedure('{$inParam1}', '{$inParam2'}, '{$inParam3}', '{$inParam4}', '{$inParam5}', '{$inParam6}', '{$inParam7}', #outParam8, #outParam9, #outParam10); SELECT #outParam8, #outParam9, #outParam10;";

PHP: calling Oracle stored proc that returns a table

I have an Oracle stored proc that takes 2 parameters. userid as an input parameter and an Oracle table with 2 columns as second out parameter. How can I invoke the procedure from PHP? I think that the problem stands in the oci_bind_* for the second parameter. I've tried oci_bind_array_by_name but I always get PLS-00306: wrong number or types of arguments in call to GET_VALUES.
Can anyone help me, please?
Here is my code:
$tab=array();
$query = "begin GET_VALUES(:P_CUSTOMERCODE,:P_TAB); end;";
$stmt = oci_parse($ora_conn, $query) or die(oci_error());
oci_bind_by_name($stmt,":P_CUSTOMERCODE",$codUtente,255);
oci_bind_array_by_name($stmt,":P_TAB",$tab,100,100,SQLT_CHR);
oci_execute($stmt) or die(oci_error());
This might answer your problem: How to call package from php having procedure in oracle using oci drivers?
Not sure a multi-column table will work with oci_bind_array_by_name. Looking at the php manual, you can use this to bind a simple varray, assoc array or nested table, basically as simply 1 column list of values. You'd specify the type of array in the "type" param, using SQLT_CHR for varchar2 for example (if you defined an array like : type t_array is table of varchar2(100) index by pls_integer).
Seems you created a custom table of a custom record type(?), something like:
type t_rec is record (
col1 number,
col2 varchar2(100)
);
type t_tab is table of t_rec;
I don't see where you can bind to t_tab as an out param using php's oci8 calls, but I may be mistaken.

Categories