Using stored procedure with an OUT parameter in Laravel - php

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);

Related

PHP - PL/SQL: How to read array (as OUT parameter from Oracle procedure) into PHP

I have a procedure in my Oracle DB with an array as output parameter. In this procedure I put all the teams with their points into an array.
create or replace package pck_tournament
as
type trranking is record (
position number
, team VARCHAR2(20)
, points number
);
type taranking is table of trranking;
procedure retrieve_ranking (oparray out taranking);
end pck_tournament;
But when I try to call this procedure with PHP I always get an error like this:
PLS-00306: wrong number or types of arguments in call to 'RETRIEVE_RANKING'
This is a part of my PHP code:
$out_arr = array();
$stmt = oci_parse($conn, "BEGIN pck_tournament.retrieve_ranking(:taranking); END;");
oci_bind_array_by_name($stmt,":taranking", $out_arr, 10000, 10000, SQLT_CHR );
oci_execute($stmt);
If I change the OUT parameter to a VARCHAR2 for testing, I'm able to read the result. But I can't manage to make it work if it is an array.
So the problem must be that I use a wrong type of argument to store my OUT parameter?
I've searched a lot of websites but still have no idea how to make this work.
What you have in oracle is not a just an array, it is a array of records.... So a standard array in PHP is not going to be able to handle it.
As per the below question here on Stack Overflow you need to tell PHP what the Type is going to look like
PHP: Binding variable to table type output parameter
So use the below (substituting your type and schema)
$table_output = oci_new_collection($conn,'some_table_type','schema');
The other question also has a link to a good resource for finding more information about this.
As pointed out by #MT0 you will have to change the way that you are defining the types as well. You can iether change it to object as suggested or leave it as record, but the major change will be moving the declaration outside of you package.
PHP will not be able to see them if they are only defined in the package.

Stored procedure that accepts multiple parameters

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

passing PHP array to Oracle Stored Proc (PLS-00306: wrong number or types of arguments)

Using PHP 5.3.2 and Oracle 11G, I'm trying to pass an array from PHP into an oracle stored proc. Here is my PL/SQL:
create or replace type NUM_ARRAY as table of number;
create or replace package txa as
procedure upsert_txa_compliance_slct( v_compl_id_array in num_array);
end txa;
create or replace package body txa as
procedure upsert_txa_compliance_slct(v_compl_id_array in num_array)
is
begin
.
. -- sql code removed for brevity. package and body compile no errors
.
end upsert_txa_compliance_slct;
end;
The Query:
$sql = "begin txa.upsert_txa_compliance_slct(:my_array); end;";
And the PHP Code I've tried to bind the array and execute :
First:
<?
$this->conn = ociplogon($dbuser, $dbpass, $dbname);
$this->commit_mode = OCI_COMMIT_ON_SUCCESS;
$this->sth = #ociparse($this->conn, $sql);
oci_bind_array_by_name($this->sth,
':my_array',
$my_array,
count($my_array),
-1,
SQLT_CHR);
$r = #ociexecute($this->sth, $this->commit_mode);
?>
Which generates this error:
PLS-00306: wrong number or types of arguments in call to 'UPSERT_TXA_COMPLIANCE_SLCT'
I'm clearly passing 1 arg. So, what's wrong with/how do I fix the type issue?
Additionally I found this
http://www.oracle.com/technetwork/articles/seliverstov-multirows-098120.html
And tried it the old way using oci collection like so:
$collection = oci_new_collection($this->conn,"NUM_ARRAY");
After I changed my oracle type to this:
create or replace type NUM_ARRAY as varray(100) of number;
I got this error:
oci_new_collection(): ORA-22318: input type is not an array type
Any help would be MUCH appreciated.
EDIT 7:08PM ET Aug 14, 2014
I changed my php oci_bind function call to use SQLT_NUM as the type. This had no impact. Then I changed my package to include:
type num_array is table of number index by binary_integer;
( i also dropped the original num_array from my schema )
This change made it possible to pass my array to the stored proc, but then I can't use the array as a nested table like so:
delete
from my_table
where id not in (select column_value from table(v_compl_id_array));
I get this error when i try to compile the package body with that statement in it:
PL/SQL: ORA-22905: cannot access rows from a non-nested table item
And all the documentation tells me to return to the schema level type? But when I do I get that other error. I know I can find another way to do this using a loop over my pl/sql array, but I would really love to be able to use that schema level type.
The answer is this. You can't use a globally created or schema level type as a parameter to a stored procedure. PHP's oci_bind_array_by_name just doesn't seem to work with globally created types, but you need the globally created type to be able to use your array as a nested table in subselects. So.... here is how I got this to work. I'm MORE THAN HAPPY TO HEAR OTHER SOLUTIONS!! but for now, here's what I did.
-- globally create a type table of number
create or replace type num_array is table of number;
-- in my package i created an internal type table of number
type i_num_array is table of number index by binary_integer;
-- i then used i_num_array (internal type) as the type for my IN parameter to the procedure
upsert_TXA_compliance_slct( v_compl_id_array in i_num_array)
-- in my procedure i also created a variable that is the type of my globally created type
v_num_array num_array := num_array();
-- then i populated that variable in a loop inside my procedure with the values in my IN param
for i in 1 .. v_compl_id_array.count
loop
v_num_array.extend(1);
v_num_array(i) := v_compl_id_array(i);
end loop;
-- then i used v_num_array as my nested table so this now works:
delete from my_table where id in (select * from table(v_num_array));

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