"EXECUTE IMMEDIATE" command issue in Oracle - oracle

I'm trying to execute this block inside a procedure...
schema_nm := 'DEVL';
plsql_block:='BEGIN ' || schema_nm || '.LIC_PKG.REMOVE(:x, :y); END;';
BEGIN
EXECUTE IMMEDIATE plsql_block USING in_val1,in_val2;
END;
When I try to execute the above i see this error..
ORA-06550: line 1, column 7:
PLS-00201: identifier 'DEVL.LIC_PKG' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
Please let me know if you have come across this kind of error...
Thank you in advance for your help.

Related

PLS-00103 error when using COMMENT statement in BEGIN ... END block in PL/SQL

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

PLS-00306: wrong number or types of arguments in call to a Oracle SP

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".

PLS-00231: Function may not be used in SQL

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

trigger compiling error in sqldeveloper with oracle11g

I have been studying triggers from
[ http://www.tutorialspoint.com/plsql/plsql_triggers.htm][1]
with sqldeveloper and I connected Oracle 11g database. I created customers table successfully. But when I tried to create trigger as :
CREATE OR REPLACE TRIGGER display_salary_changes
BEFORE DELETE OR INSERT OR UPDATE ON customers
FOR EACH ROW
WHEN (NEW.ID > 0)
DECLARE
sal_diff number;
BEGIN
sal_diff := :NEW.salary - :OLD.salary;
dbms_output.put_line('Old salary: ' || :OLD.salary);
dbms_output.put_line('New salary: ' || :NEW.salary);
dbms_output.put_line('Salary difference: ' || sal_diff);
END;
I get these errors:
Error starting at line : 1 in command -
CREATE OR REPLACE TRIGGER display_salary_changes
BEFORE DELETE OR INSERT OR UPDATE ON customers
FOR EACH ROW
WHEN (NEW.ID > 0)
DECLARE
sal_diff number
Error report -
SQL Command: trıgger DISPLAY_SALARY_CHANGES
Failed: Warning: yürütme uyarı ile tamamlandı
Error starting at line : 7 in command -
BEGIN
sal_diff := :NEW.salary - :OLD.salary;
dbms_output.put_line('Old salary: ' || :OLD.salary);
dbms_output.put_line('New salary: ' || :NEW.salary);
dbms_output.put_line('Salary difference: ' || sal_diff);
END;
Error report -
ORA-06550: line 2, column 5:
PLS-00201: identifier 'SAL_DIFF' must be declared
ORA-06550: line 2, column 5:
PL/SQL: Statement ignored
ORA-06550: line 3, column 60:
PLS-00487: Invalid reference to variable 'SQLDEVBIND1Z_2'
ORA-06550: line 3, column 5:
PL/SQL: Statement ignored
ORA-06550: line 4, column 60:
PLS-00487: Invalid reference to variable 'SQLDEVBIND1Z_1'
ORA-06550: line 4, column 5:
PL/SQL: Statement ignored
ORA-06550: line 5, column 51:
PLS-00201: identifier 'SAL_DIFF' must be declared
ORA-06550: line 5, column 5:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
What is wrong with this create trigger block?
It seems to be the same "Securing Literals" feature as described here
http://krisrice.io/2015-09-11-sqlcl-more-secure-now-with-rest/

Getting error while forming Dynamic PLSQL

I am trying to form below SQL statement. but getting this weird error which I can't seem to figure out. I have executed each statement individually outside the loop and they are working fine. Please someone help me finding the error.
Error
ORA-06550: line 6, column 14:
PLS-00306: wrong number or types of arguments in call to '||'
ORA-06550: line 6, column 7:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
PLSQL Statement:
DECLARE
L_sql VARCHAR2(2000):=NULL;
BEGIN
FOR val IN (SELECT generation_qtr from test_1)
LOOP
L_sql:=L_sql ||' MAX(DECODE(generation_qtr, '||''''||val||''''||' cum_actual_gen)) AS ' || val ||','||chr(10);
END LOOP;
L_sql:='SELECT assetname, '|| L_sql;
L_sql:=substr(L_sql,1,LENGTH(L_sql)-1);
dbms_output.put_line(L_sql);
END;
Oracle Version -11.2
You're referring to val directly, but that's a cursor row type. You need to specify the column name, even if there is only one:
... ||val.generation_qtr|| ...
... in both places you use it in the concatenation. So it woudl become:
L_sql:=L_sql ||' MAX(DECODE(generation_qtr, '||''''
|| val.generation_qtr ||''''||' cum_actual_gen)) AS '
|| val.generation_qtr ||','||chr(10);
If you're going to execute this dynamically then the new line characters aren't going to be very useful, but I guess they help for debugging.

Resources