I am trying to create an sql proceedure that will return the results back to the php page.
I want to be able to call the procedure as follows from the php
call procedure_name($var1)
which will run this script:
-- ---------------------------------------------------------------------------------
-- pUIGetCliStmtGenFlag
--
-- This procedure returns the status of the Trading Period:
--
-- ---------------------------------------------------------------------------------
drop procedure if exists pUIGetCliStmtGenFlag;
delimiter //
create procedure pUIGetCliStmtGenFlag(
IN pTradingPeriodMonth DATE
)
MODIFIES SQL DATA
COMMENT 'Checks if the TP has been closed'
begin
SELECT trading_period_month,
dt_end,
amt_traded_system_ccy
FROM ca_trading_period
WHERE trading_period_month=$var1
-- If amt_traded_system_ccy is NULL give the TP an open status otherwise mark as closed
IF amt_traded_system_ccy is NULL
$tpstatus='open'
ELSE
$tpstatus='closed'
end;
//
delimiter ;
I then want to be able to use $tpstatus in the rest of the php script.
I know this is simple but this is completely new to me and I cant find the correct method
You have to call the stored procedure from php and THEN get the values back, using OUT parameters of the procedure.
Please follow these instructions:
https://stackoverflow.com/a/48161/1291428
Related
I am working with pgsql and i need to convert my mysql trigger to pgsql trigger.Pgsql query has executed successfully,but i am not able to view output.Please help me.
The code of trigger looks well. I don't see any problem. When you design trigger, then the RAISE NOTICE statement is your best friend. The often error is human error - you can set trigger on wrong table, you can try to insert to wrong table - the notification shows so all is ok.
postgres=> \sf func_trg
CREATE OR REPLACE FUNCTION public.func_trg()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
BEGIN
RAISE NOTICE 'func_trg: %', new;
RETURN new;
END;
$function$
postgres=> CREATE TRIGGER xxx AFTER INSERT ON foo_table
FOR EACH ROW EXECUTE PROCEDURE func_trg();
CREATE TRIGGER
postgres=> set client_min_messages to notice;
SET
postgres=> INSERT INTO foo_table VALUES(10,20);
NOTICE: func_trg: (10,20)
INSERT 0 1
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));
my Store procedure having 4 In type parameters.i want to use only 3 parameters when i call stored procedure in php mysql .
My stored Procedure is
DELIMITER $$
CREATE PROCEDURE `usptregister`
(
IN ID bigint,
IN name varchar(100),
IN email varchar(100),
IN phoneno varchar(15)
)
BEGIN
Insert INTO register
(id,fname, emailid, phone) values
(id,name , email ,phone) ;
END
and my php code where i am calling stored procedure passing only 3 parameters.
$call = mysql_query("CALL usptregister('0','".$_POST[name ]."','".$_POST[email ]."') ");
This code is working when i am passing same no of arguments when i am calling stored procedure.
I am new in stored procedure .so please help me.
Optional parameters are not supported by MySQL
I suggest you to pass the fourth parameter as null. Then in the procedure you can check if is null or not.
BEGIN
IF param IS NULL THEN
-- statements ;
ELSE
-- statements ;
END IF;
END$$
EDIT:
http://bugs.mysql.com/bug.php?id=15975
Although the request is 9 years old it's still not done.
i am a php beginer. i want to call a mysql procedure and display the output rows returned by the procedure. the code is below
mysql
delimiter //
create procedure get_ques_list(in p_ques_ctgr varchar(10))
begin
select ques from question_list where ques_categorey=p_ques_ctgr
order by ques;
end //
delimiter ;
php code
$result=mysql_query("CALL GET_QUES_LIST('S_001')");
while($row=mysql_result($result,0,0))
{
echo $row['ques'];
}
but it is giving warning messgge
Warning: mysql_result(): supplied argument is not a valid MySQL result resource in
but the same code works fine and display 5 rows if i use query instead of calling procedure
$result=mysql_query("select ques from question_list where
ques_categorey='S_001' order by ques");
procedure is also working fine when executed in mysql
can anyone tell where m going wrong in that??
any help is appreciated
I am in a bit of a pickle. I have a stored procedure that accepts an argument and returns the results of a query. The query is using an IN statement.
Here's the structure of the SP:
CREATE OR REPLACE
PROCEDURE EXAMPLE_SP
(
arg VARCHAR2,
argRS1 OUT cursors.rs
)
AS
l_test VARCHAR2(255) := arg;
BEGIN
OPEN argRS1 FOR
SELECT * FROM TABLE1
WHERE LOCATION IN (l_test);
END EXAMPLE_SP;
The number of values within the IN statement can be variable. The options for IN are coming from selected form checkboxes on the UI side.
I am using PHP to retrieve the selected checkbox values. I have already tried imploding the values into a comma deliminated string.
My logic for that was that the query would then look like this:
l_test = 'val1, val2, val3';
SELECT * FROM TABLE1
WHERE LOCATION IN (val1, val2, val3);
But that didn't work. I am not sure how to proceed. Thanks in advance for any constructive comments or suggestions.
You can add this comma separated input parameter as a varchar() and use following where statement:
where (','||l_test||',' like '%,'||LOCATION||',%')
for example if l_test='2,3,4,5' and LOCATION=3 we get:
where (',2,3,4,5,' like '%,3,%')
and it's TRUE if LOCATION value is in this list.
I think the location that you have selected is VARCHAR,so for that you need to convert the list as shown below
l_test = '''val1''||','|| ''val2''||','||''val3''';
So that your final query look like
SELECT * FROM TABLE1
WHERE LOCATION IN ('val1', 'val2', 'val3');
You can do like this also
CREATE OR REPLACE
PROCEDURE EXAMPLE_SP
(
arg VARCHAR2,
argRS1 OUT cursors.rs
)
AS
l_test VARCHAR2(255) := arg;
BEGIN
l_test:=''''||replace(l_test,',',''',''')||'''';
OPEN argRS1 FOR
SELECT * FROM TABLE1
WHERE LOCATION IN (l_test);
END EXAMPLE_SP;
Note:I have not tested this ,but i think this way you will achieve what you want
I would do this without using string manipulation. Theoretically there may currently be little risk of SQL Injection because you're using checkboxes it's best to implement good practice at the beginning so if anything changes you don't put yourself at risk.
The second benefit is that you are still able to utilise any indexes on your column, which you wouldn't be able to do if you use like '%....
To do this you can utilise a table function and an external object to populate your "in" list.
As an example I'm going to return the OBJECT_NAME from USER_OBJECTS.
If I create two tables:
create table tmp_test ( a number );
create table tmp_test2 ( a number );
and an object to hold the list of tables, or in your case locations.
create type t_test_object is table of varchar2(30);
Next, here's the equivalent of your procedure. It's a function that returns a SYS_REFCURSOR. It accepts the T_TEST_OBJECT as a parameter, which means this first needs to be populated before being passed to the function.
create or replace function select_many (
Ptest_object in t_test_object
) return sys_refcursor is
l_curs sys_refcursor;
begin
open l_curs for
select object_name
from user_objects
where object_name in ( select *
from table(Ptest_object)
);
return l_curs;
end;
Lastly, here's an example of how to use this set-up. Notice how an instance of T_TEST_OBJECT gets populated with multiple values. This object then gets passed to the function to return your cursor. Lastly, to display the values I loop through the cursor. Obviously you may want to utilise the cursor and populate the TYPE differently.
SQL> declare
2
3 l_nested_table t_test_object := new t_test_object();
4 l_cursor sys_refcursor;
5 -- Used for display demonstration only.
6 l_object_name user_objects.object_name%type;
7
8 begin
9
10 l_nested_table.extend;
11 l_nested_table(l_nested_table.last) := 'TMP_TEST';
12 l_nested_table.extend;
13 l_nested_table(l_nested_table.last) := 'TMP_TEST2';
14
15 l_cursor := select_many(l_nested_table);
16
17 loop -- Display example, not really relevant
18 fetch l_cursor into l_object_name;
19 exit when l_cursor%notfound;
20 dbms_output.put_line(l_object_name);
21 end loop;
22
23 end;
24 /
TMP_TEST
TMP_TEST2
PL/SQL procedure successfully completed.
You can use Oracle examples from Oracle Documentation: http://docs.oracle.com/cd/B28359_01/win.111/b28378/basfeat.htm#sthref207
Look here - return a table:
Can an SQL procedure return a table?
And here's another example:
PACKAGE emp_actions IS
TYPE EnameTabTyp IS TABLE OF emp.ename%TYPE INDEX BY BINARY_INTEGER;
TYPE SalTabTyp IS TABLE OF emp.sal%TYPE INDEX BY BINARY_INTEGER;
...
PROCEDURE hire_batch (ename_tab IN EnameTabTyp, sal_tab IN SalTabTyp, ...);
PROCEDURE log_names (ename_tab IN EnameTabTyp);
END emp_actions;