Getting error while forming Dynamic PLSQL - oracle

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.

Related

Get the first value from Oracle cursor - Calling From Java Code

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

Use string concatenation in UPDATEXML()

I want to write an update script for my oracle db. I want to replace old XML node values with new ones. But I need to do this for many values so I wanna outsource the logic in a procedure.
This is what I've come up with.
CREATE OR REPLACE PROCEDURE MY_PROCEDURE(
old_name IN NVARCHAR2,
new_name IN NVARCHAR2
)
AS
BEGIN
UPDATE
MY_TABLE
SET
ENTITY = UPDATEXML(ENTITY, '/*/Section', '<Section>' || new_name || '</Section>', 'xmlns="http://foo.bar.com/baz"')
WHERE
EXTRACTVALUE(ENTITY, '/*/Section', 'xmlns="http://foo.bar.com/baz"') = old_name;
END;
This is actually working really well - when I don't use string concatenation in UPDATEXML(). When I start using concatenation the execution of the procedure stops working / starts to throw exceptions.
I've also tried CONCAT(CONCAT('<Section>', new_name), '</Section>') instead of the ||-Operator. Didn't work out either.
The exception I get running the procedure in Oracle SQL Developer
ORA-06550: line 2, column 5:
PLS-00905: object MY_DB.MY_PROCEDURE is invalid
ORA-06550: line 2, column 5:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:

Parameters wrong assignment (PL/SQL, ORACLE)

I'm trying to run below pl/sql block but I'm getting error:
set serveroutput on
declare
rowBefore VARCHAR2(32000);
myschema VARCHAR2(32000) := 'abc';
mytable VARCHAR2(32000) := 'table1';
param1 VARCHAR2(32000) := 'Tom';
begin
select count(*) into rowBefore from myschema.mytable where colA = param1;
--select count(*) into rowBefore from abc.table1 where colA = 'Tom';
DBMS_OUTPUT.PUT_LINE(rowBefore);
End;
How to correctly use my all parameters into select statement?
Update error:
Error report -
ORA-06550: linia 7, kolumna 50:
PL/SQL: ORA-00942: tabela lub perspektywa nie istnieje
ORA-06550: linia 7, kolumna 5:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
You can't use a variable as an identifier in a SQL statement. It is looking for a table that is actually called mytable - not one with the value of the variable with that name as you expect. And the same for the schema.
From the documentation:
If the statement is a SELECT statement, the PL/SQL compiler removes the INTO clause.
The PL/SQL compiler sends the statement to the SQL subsystem.
The SQL subsystem checks the syntax of the statement.
If the syntax is incorrect, the compilation of the PL/SQL unit fails. If the syntax is correct, the SQL subsystem determines the names of the tables and tries to resolve the other names in the scope of the SQL statement.
...
It tries to resolve other names, e.g. functions; but table names (and schema names, and column names) have to be valid to the SQL parser.
You have to use dynamic SQL to create a string that contains the statement, concatenating in the identifiers:
execute immediate 'select count(*) from ' || myschema ||'.'|| mytable
|| ' where colA = :value'
into rowBefore using param1;
If you print out that generated statement with dbms_output you should see it matching the commented-out version, except for the use of a bind variable for the columns value. That would also help highlight any errors - like not including whitespace between the concatenated parts of the statement, which is a common and easy mistake.
It's often a good idea to build the statement as a string variable to make such debugging easier:
declare
...
v_stmt varchar2(4000):
begin
v_stmt := 'select count(*) from ' || myschema ||'.'|| mytable
|| ' where colA = :value';
-- for debugging
dbms_output.put_line(v_stmt);
-- and run it
execute immediate vStmt into rowBefore using param1;
...
If you are really getting the identifiers passed in by a user or client you should validate them to avoid unexpected errors and SQL injection attacks. Also, if the identifiers might be case sensitive (i.e. schemas/tables created with quoted identifiers) then you may need to add double-quotes to the generated statement, and make sure the variables are the correct case.
error is ORA-942: table or view does not exists. run first below query and see if error still occurs.
-- should you use abc.table1, instead of myschema.mytable?
select count(*) rowBefore from myschema.mytable where colA = 'a';
if there is still error, then fix the SELECT statement first before you use it in the PL/SQL block.

Execute Immediate not working,need help in syntax

When I am executing the below query, it is working:
CREATE TABLE MySchema.AAA ( INFOLINKPODID NVARCHAR2(50));
But when I am trying to execute the same using execute immediate:
EXECUTE IMMEDIATE 'CREATE TABLE '|| MySchema||'.AAA ( INFOLINKPODID NVARCHAR2(50));';
Getting below compilation error:
Error report -
ORA-06550: line 1, column 17:
PLS-00103: Encountered the symbol "CREATE TABLE " when expecting one of the following:
:= . ( # % ;
The symbol ":=" was substituted for "CREATE TABLE " to continue.
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Thanks in advance.
as per the comments, you need a framing block, but also the semi-colon at the end of the execute immediate string needs to be removed (or you will get an ORA-00911 invalid character error), like this:
begin
execute immediate 'CREATE TABLE TEST (X NUMBER)';
end;
/
should work.

"EXECUTE IMMEDIATE" command issue in 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.

Resources