I have no idea what to do. I wrote a function, compiled it with no errors but then when I run the code I got:
ORA-0650: line 3, column 14:
PLS-00103: Encountered the symbol "/" when expecting one of the following:
:= . ( # % ; not null range default character
ORA-06512: at line 58
Vendor code 6550
This is the function:
create or replace
FUNCTION "GET_MUSICIAN_FUN"
(
i_mus_id IN musicians.id%type
)
RETURN musicians%ROWTYPE
AS
o_mus_rec musicians%ROWTYPE;
BEGIN
SELECT m.id, m.first_name, m.last_name, m.born, m.died , m.picture_path, m.bio
INTO o_mus_rec
FROM musicians m
WHERE id = i_mus_id;
RETURN o_mus_rec;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20005, 'Found nothing.');
WHEN TOO_MANY_ROWS THEN
RAISE_APPLICATION_ERROR(-20006, 'Found too many.');
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20007, 'Cannot get musician.');
END GET_MUSICIAN_FUN;
EDIT:
When I call it with:
declare
result musicians%rowtype;
begin
result := get_musician_fun(53);
end;
/
I get : "anonymous block completed"
But when calling it from PHP:
$con = oci_connect("yoni", "yoni", "//localhost/xe");
$s = oci_parse($con, "begin :rc := GET_MUSICIAN_FUN(53); end;");
$rc = oci_new_cursor($con);
oci_bind_by_name($s, ":rc", $rc, -1, OCI_B_CURSOR);
oci_execute($s); // line 41
oci_execute($rc, OCI_DEFAULT);
oci_fetch_all($rc, $res, null, -1, OCI_FETCHSTATEMENT_BY_ROW); // line 43
return $res;
I get:
Warning
: oci_execute(): ORA-06550: line 1, column 14:
PLS-00382: expression is of wrong type
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored in... on line 41
Warning
: oci_fetch_all(): ORA-24338: statement handle not executed in... on line 43
I'm no php expert but your trying to fetch an oracle row object into php.
rowtype are used only inside oracle pl/sql code.
try this approach
create or replace function get_musician_fun( i_mus_id in musicians.id%type)
return varchar2
as
musician_row varchar2(32000);
begin
select m.id||','|| m.first_name||','|| m.last_name||','|| m.born||','|| m.died ||','|| m.picture_path||','|| m.bio
into o_mus_rec
from musicians m
where id = i_mus_id;
return musician_row;
exception
when no_data_found then
raise_application_error(-20005,'found nothing.');
when too_many_rows then
raise_application_error(-20006,'found too many.');
when others then
raise_application_error(-20007,'cannot get musician.');
end get_musician_fun;
and split the result on your php like a csv.
look at the revised raise_application_error bit the code above.
you might be better of querying the database and fetching the row
without a stored procedure.
Related
I have a oracle cursor which I have created to facilitate concurrency. This is my cursor.
create or replace FUNCTION get_unlocked_records RETURN table_to_test%ROWTYPE IS
CURSOR c IS SELECT * FROM table_to_test where status_code = 5 FOR UPDATE SKIP LOCKED;
record_to_get table_to_test%ROWTYPE;
BEGIN
OPEN c;
FETCH c INTO record_to_get;
CLOSE c;
RETURN record_to_get;
END;
When I do the testing in 2 separate sql sessions using these commands,it gives the following errors.
declare
record_to_gets table_to_test%ROWTYPE;
begin
exec :record_to_gets := get_unlocked_records;
dbms_output.put_line(record_to_gets);
end;
Error
Error starting at line : 32 in command -
declare
record_to_gets table_to_test%ROWTYPE;
begin
exec :record_to_gets := get_unlocked_records;
dbms_output.put_line(record_to_gets);
end;
Error report -
ORA-06550: line 4, column 7:
PLS-00103: Encountered the symbol "" when expecting one of the following:
:= . ( # % ;
The symbol ";" was substituted for "" to continue.
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
What is the error that I am doing here ?
Since my ultimate goal is to call the function and get the result in java, how to call this function to get the first record in java ?
Thanks in advance.
EXEC[UTE] is a SQL*Plus command and prepending variable with a colon is done in SQL*Plus, but in PL/SQL EXECUTE IMMEDIATE might be used whereas that's not needed in your case, only using such an assignment without prepending the local variable is enough :
DECLARE
record_to_gets table_to_test%ROWTYPE;
BEGIN
record_to_gets := get_unlocked_records;
DBMS_OUTPUT.PUT_LINE(record_to_gets.col1);
DBMS_OUTPUT.PUT_LINE(record_to_gets.col2)
END;
/
Out of curiosity I'm attempting to use the COMMENT statement in a PL/SQL block. I'm using Oracle APEX 18.2 on an Oracle 11g database and in SQL Workshop I am able to execute the command by itself, but if I wrap it in a BEGIN ... END block then I get an error message like:
ORA-06550: line 4, column 18: PLS-00103: Encountered the symbol "ON" when expecting one of the following: : = . ( # % ;
Example of command that works:
COMMENT ON COLUMN employees.job_id IS 'comment';
Example of command that results in the error message:
BEGIN
COMMENT ON COLUMN employees.job_id IS 'comment';
END;
I assume that COMMENT isn't a permitted statement in a stored procedure but I haven't been able to find evidence to back this up. Am I correct and if so is this documented anywhere?
Thanks to #GMB for an answer with written example.
Consider:
create table employees(job_id int);
begin
comment on column employees.job_id is 'comment'
end;
/
ora-06550: line 2, column 13:
pls-00103: encountered the symbol "on" when expecting one of the following:
:= . ( # % ;
begin
execute immediate 'comment on column employees.job_id is ''comment''' ;
end;
/
1 rows affected
db<>fiddle here
I'm trying to execute a below SP and it throws be the below error:
CREATE OR REPLACE PROCEDURE denodo.CLEAR_INDEX
( INDEX_NAME1 IN VARCHAR2,
INDEX_NAME2 IN VARCHAR2,
IT_WORKED OUT BOOLEAN ) as
BEGIN
IT_WORKED := FALSE;
EXECUTE IMMEDIATE 'drop index ' || INDEX_NAME1;
EXECUTE IMMEDIATE 'drop index ' || INDEX_NAME2;
IT_WORKED := TRUE;
EXCEPTION
WHEN OTHERS THEN
IT_WORKED := FALSE;
END CLEAR_INDEX;
CLEAR_INDEX#0 [JDBC ROUTE] [ERROR] Received exception with message 'ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'CLEAR_INDEX'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
What is going on here? appreciate your help.
This error you generally face when you deal with BOOLEAN datatype as OUT parameter and you try to print it or do any operation with any other inbuilt Oracle packages. You cannot directly use BOOLEAN datatype in dbms_output.put_line or any other DBMS package. For instance,if you want to print the OUT parameter you need to use sys.diutil.bool_to_int.
See below example which demonstrate the error you faced when you try to execute as below:
DECLARE
inx VARCHAR2(100):='ABC';
var BOOLEAN;
BEGIN
CLEAR_INDEX(INDEX_NAME1=>inx ,IT_WORKED =>var);
dbms_output.put_line(var);
END;
You face the issue:
ORA-06550: line 6, column 3:
PLS-00306: wrong number or types of arguments in call to 'PUT_LINE'
ORA-06550: line 6, column 3:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action
To overcome such issue you must execute as below:
DECLARE
inx VARCHAR2(100):='ABC';
var BOOLEAN;
var1 varchar2(10);
BEGIN
CLEAR_INDEX(INDEX_NAME1=>inx ,IT_WORKED =>var);
var1:=CASE WHEN (sys.diutil.bool_to_int(var)) = 1 THEN 'TRUE'
WHEN (sys.diutil.bool_to_int(var)) = 0 THEN 'FALSE'
END;
dbms_output.put_line(var1);
END;
Output:
anonymous block completed
Mine is a similar case, however, a different call to a function, which has return type as Boolean and the input to the function is varchar2.
So, this is what I am doing:
Declare
v_ret1 varchar2(1000);
v_ret BOOLEAN;
Begin
v_ret := CASE WHEN SEI_PROCESS_MF_MNL_INVC_PKG.f_process_mf_mnl_invc(v_ret1) = 1 THEN 'TRUE'
WHEN SEI_PROCESS_MF_MNL_INVC_PKG.f_process_mf_mnl_invc(v_ret1) = 0 THEN 'FALSE'
END;
dbms_output.put_line(v_ret);
end;
I just wanted to see output of v_ret so that I can use that for further decision making. If v_ret is of type Boolean, the output should be either "TRUE" or "FALSE".
I'm currently trying to execute a stored procedure in Oracle PL SQL. I keep running into the same error for the below with execution.
I've tried both execution with the same error
SET SERVEROUTPUT ON;
EXEC get_phone(200.00,500.00);
OR
SET SERVEROUTPUT ON;
DECLARE
c_minprice products.price%type;
c_maxprice products.price%type;
BEGIN
c_minprice := get_phone(200);
c_maxprice := get_phone(500);
END;
ERROR from executing the above:
c_minprice := get_phone(200);
*
ERROR at line 5:
ORA-06550: line 5, column 15:
PLS-00306: wrong number or types of arguments in call to 'GET_PHONE'
ORA-06550: line 5, column 1:
PL/SQL: Statement ignored
ORA-06550: line 6, column 15:
PLS-00306: wrong number or types of arguments in call to 'GET_PHONE'
ORA-06550: line 6, column 1:
PL/SQL: Statement ignored
****Sample Snip-its form my code:
CREATE OR REPLACE PROCEDURE get_phone
(
c_minprice IN products.price%type,
c_maxprice IN products.price%type,
i_result OUT VARCHAR2
) AS
--Checking if starting price range is valid or not
IF c_minprice IS NULL THEN
i_result := 'Starting price range should be valid and cannot be empty';
RAISE V_MINPRICE; -- Raising exception if starting price is null
END IF;
--Checking if end price range is valid or not
IF c_maxprice IS NULL THEN
i_result := 'End price range should be valid and cannot be empty';
RAISE V_MAXPRICE; -- Raising exception if end price is null
END IF;
Your procedure requires three parameters so you have to pass in three parameters
DECLARE
l_result varchar2(100);
BEGIN
get_phone( 200, 500, l_result );
END;
/
should work. Of course, your procedure seems rather pointless. And if the goal is simply to return a result, you really ought to be using a function rather than a procedure with an out parameter.
get_phone expects 3 arguments, c_minprice, c_maxprice and i_result. You are only passing it one number. Pass it the rest of the arguments.
I want to test my pipelined function without creating a package. The following example is simplified:
DECLARE
FUNCTION testDC RETURN NCOL PIPELINED IS
BEGIN
PIPE ROW(5);
END;
BEGIN
FOR cur IN (select * from table (testDC())) LOOP
dbms_output.put_line('--> ');
END LOOP;
END;
But I get this error:
ORA-06550: line 7, column 7: pls-00231: function TESTDC may not be used in SQL
ORA-06550: line 7, column 7: PL/SQL: ORA-00904: : invalid identifier
ORA-06550: line 7, column 7: PL/SQL: SQL Statement ignored
What is better way to test these function?
Create your pipelined function as a standalone procedure or package member. Then you can call it from your script.
Also ensure that the NCOL parameter you refer to is declared in a schema that can be accessed by the calling script.
You can't access a table function direct in PL/SQL - see the test case below. So as other pointed out you must define the table function as standalone or packaged.
DECLARE
res NUMBER;
FUNCTION testDC RETURN NCOL PIPELINED IS
BEGIN
PIPE ROW(5);
END;
BEGIN
res := testDC();
dbms_output.put_line('--> '||res);
END;
/
ORA-06550: line 3, column 12:
PLS-00653: aggregate/table functions are not allowed in PL/SQL scope