Oracle Dynamic Cursor - ORA-00936 missing expression - oracle

I need to use a dynamic cursor in my procedure which receive values from another cursor.
When I run this procedure I got ORA-00936 missing expression.
I put this select from cursor into dbms_output to see it is correct and it was.
This is the code :
BEGIN
OPEN dsa_tables;
LOOP
FETCH dsa_tables INTO
v_owner,
v_table_name,
v_column_name,
v_comments,
v_tech_date;
EXIT WHEN dsa_tables%notfound;
v_table_all := dbms_assert.sql_object_name(v_owner
|| '.'
|| v_table_name);
-- with this cursor is the problem
OPEN count_date FOR ' SELECT '
|| v_column_name
|| ','
|| ' COUNT('
|| v_column_name
|| ') FROM '
||v_table_all
|| ' GROUP BY '
|| v_column_name;
LOOP
FETCH count_date INTO
v_date,
v_count;
EXIT WHEN count_date%notfound;
END LOOP;
CLOSE count_date;
END LOOP;
CLOSE dsa_tables;
END;
/

You likely have v_column_name set to NULL.

I've already checked it and there is no NULL im this column.

Related

Oracle : Delete rows with "execute immediate" and rowcount

I want to delete rows with an "Execute immediate" because the table name is in a variable.
How can I count the number of lines deleted?
I tried this, but it does not work with the INTO v_LINE_REMOVE;
v_sql := '
DELETE /*+parallel(t,4)*/
FROM "' || v_owner || '"."' || v_table_name ||'" t
where t."'|| v_column_name ||'" in (
select /*+parallel(rem,4)*/
rem.' || v_type_data || '
from ' || v_table_listeremove || ' rem
WHERE rem.dt_vact = '''|| v_dt_vact ||'''
)
';EXECUTE IMMEDIATE v_sql;--INTO v_LINE_REMOVE;
Thanks a lot
You should be able to use SQL%ROWCOUNT after running your DML statement
EXECUTE IMMEDIATE v_sql;
v_line_remove := SQL%ROWCOUNT;

Oracle SQL Function selecting output

I am not so used to pipelined functions in Oracle. I worked a lot with Sybase, and MS SQL Server, but Oracle is more or less new to me.
I am using a function from a colleague who left a while ago.
This function return something, if I am not totally wrong:
return ty_CouponTypes_tab pipelined is
V_CT varchar(3);
V_PST varchar(5);
I created a view and iterate over this view with a cursor and pass all the columns to the function, but how can I get the result of this function?
This is what I do not understand.
This is my cursor
set serveroutput on format wrapped;
declare
cursor cCur is select * from VW_PRE_WHITELIST;
begin
for vCurData in cCur
loop
dbms_output.put_line(vCurData.MAT_NAME || ' ' || vCurData.DST_SKONTRO || ' ' || vCurData.DST_ZINSART || ' ' || vCurData.UND_TYP || ' ' || vCurData.DZU_RZ_ERWARTET || ' ' || vCurData.DST_ERSTZINS || ' ' || vCurData.CNT);
select a.* FROM FN_COUPONTYPES(vCurData.MAT_NAME, vCurData.DST_SKONTRO, vCurData.DST_ZINSART, vCurData.UND_TYP, vCurData.DZU_RZ_ERWARTET, vCurData.DST_ERSTZINS, vCurData.CNT) a;
end loop;
end;
Thanks for helping me in advance!

PL/SQL Procedure error ORA-00900: invalid SQL statement

I am new to PL/SQL and I am trying to make a procedure with 2 cursors and I have no ideea why am I having this error:
ORA-00900: invalid SQL statement
PROCEDURE filme_pret IS
CURSOR planificari_pret_redus (pret_propus NUMBER) IS
SELECT * FROM planificare WHERE pret < pret_propus ;
obiect planificari_pret_redus%rowtype;
CURSOR planificari_pret_normal IS
SELECT * FROM planificare;
obiect2 planificari_pret_normal%rowtype;
BEGIN
dbms_output.put_line('Filme cu pret redus');
for obiect in planificari_pret_redus(100)
LOOP
dbms_output.put_line(obiect.idplanificare || ' ' || obiect.idfilm || ' ' || obiect.pret);
END LOOP;
for obiect2 in planificari_pret_normal
LOOP
dbms_output.put_line(obiect2.idplanificare || ' ' || obiect2.idfilm || ' ' || obiect2.pret);
END LOOP;
END;
Thank you.
The main part of your code is ok, you simply have to decide how to use it; if you want to create a procedure without storing it, you need a complete DECLARE...BEGIN...END block:
DECLARE
/* declare your procedure */
PROCEDURE filme_pret IS
CURSOR planificari_pret_redus(pret_propus NUMBER) IS
SELECT *
FROM planificare
WHERE pret < pret_propus;
obiect planificari_pret_redus%ROWTYPE;
CURSOR planificari_pret_normal IS
SELECT * FROM planificare;
obiect2 planificari_pret_normal%ROWTYPE;
BEGIN
DBMS_OUTPUT.put_line('Filme cu pret redus');
FOR obiect IN planificari_pret_redus(100) LOOP
DBMS_OUTPUT.put_line(obiect.idplanificare || ' ' || obiect.idfilm || ' ' || obiect.pret);
END LOOP;
FOR obiect2 IN planificari_pret_normal LOOP
DBMS_OUTPUT.put_line(obiect2.idplanificare || ' ' || obiect2.idfilm || ' ' || obiect2.pret);
END LOOP;
END;
BEGIN
/* CALL YOU PROCEDURE */
filme_pret;
END;
/
This way your procedure is not stored in DB, and you always need to use the entire block; if you want to create a stored procedure, you need this syntax:
CREATE OR REPLACE PROCEDURE filme_pret IS
CURSOR planificari_pret_redus(pret_propus NUMBER) IS
SELECT *
FROM planificare
WHERE pret < pret_propus;
obiect planificari_pret_redus%ROWTYPE;
CURSOR planificari_pret_normal IS
SELECT * FROM planificare;
obiect2 planificari_pret_normal%ROWTYPE;
BEGIN
DBMS_OUTPUT.put_line('Filme cu pret redus');
FOR obiect IN planificari_pret_redus(100) LOOP
DBMS_OUTPUT.put_line(obiect.idplanificare || ' ' || obiect.idfilm || ' ' || obiect.pret);
END LOOP;
FOR obiect2 IN planificari_pret_normal LOOP
DBMS_OUTPUT.put_line(obiect2.idplanificare || ' ' || obiect2.idfilm || ' ' || obiect2.pret);
END LOOP;
END;
/
After this, you can simply call your procedure in a PL/SQL block:
begin
filme_pret;
end;
/
is that a typo ?
obiect planificari%rowtype;
it seems that planificari doesn't exists.

Procedure failed due to ORA-00920: invalid relational operator

Getting below error while executing in 12c oracle,but it is working fine when it was in oracle 10.2.0.4 :
Procedure proc_up_dts_product_cat_dynsql failed due to ORA-00920: invalid
relational operator
Here is the procedure :
CREATE OR REPLACE PROCEDURE SEAPROB.proc_up_dts_product_cat_dynsql(tablename IN varchar)
AS
dynamicsql varchar(8000);
ID int;
DTS_Segment_op varchar2(10);
DTS_Segment varchar2(15);
DTS_Segment_where varchar2(255);
DateEntered_op varchar2(10);
DateEntered varchar2(30);
DateEntered_where varchar2(255);
Svc_Name_op varchar2(10);
Svc_Name varchar2(100);
Svc_Name_where varchar2(255);
Product_Category varchar2(75);
Priority int;
combined_status_where varchar2(255);
refdate date ;
CURSOR PrivCursor
IS
SELECT
ID,
DTS_Segment_op,
Nvl(upper(trim(DTS_Segment)),' '),
DateEntered_op,
CASE WHEN dateentered='%' THEN dateentered
WHEN dateentered LIKE '%/%/____' THEN To_Char(To_Date(dateentered,'MM/DD/YYYY'),'YYYY-MM-DD')
WHEN dateentered LIKE '%/%/__' THEN To_Char(To_Date(dateentered,'MM/DD/YY'),'YYYY-MM-DD')
WHEN dateentered LIKE '''%/%/%'' % ''%/%/%''' THEN ''''||To_Char(To_Date(SubStr(dateentered,InStr(dateentered,'''',1,1)+1,InStr(dateentered,'''',1,2)-InStr(dateentered,'''',1,1)-1),'MM/DD/YY'),'YYYY-MM-DD')||''' and '''||To_Char(To_Date(SubStr(dateentered,InStr(dateentered,'''',1,3)+1,InStr(dateentered,'''',1,4)-InStr(dateentered,'''',1,3)-1),'MM/DD/YY'),'YYYY-MM-DD')||''''
ELSE dateentered END AS dateentered,
Svc_Name_op,
Nvl(upper(trim(Svc_Name)),' '),
Product_Category,
Priority
FROM tbl_dts_pt_lookup order by priority desc;
BEGIN
refdate := ADD_MONTHS(to_date(SYSDATE,'dd-mon-yy'),-6) ;
OPEN PrivCursor;
-- Loop through all the rows in the tbl_dts_category_lookup table
FETCH PrivCursor
INTO
ID,
DTS_Segment_op,
DTS_Segment,
DateEntered_op,
DateEntered,
Svc_Name_op,
Svc_Name,
Product_Category,
Priority;
WHILE PrivCursor%found
LOOP
-- Create dynamic SQL
--define case statements for where clause components
combined_status_where := ' where (DTS_Cm_DisputeStatus <>'|| '''C''' || ' OR ( DTS_Cm_DisputeStatus='|| '''C''' || ' AND DTS_CM_CLOSEDATE >= '''||refdate||'''))' ;
dts_segment_where := case when dts_segment='%' then ' and 1=1' else ' and NVL(trim(Replace(Upper(segment),chr(0),''' || ''')),''' || ' '') ' || dts_segment_op || ' ''' || dts_segment || '''' end;
svc_name_where := case when svc_name='%' then ' and 1=1' else ' and NVL(trim(Replace(Upper(dts_cm_servicename),chr(0),''' || ''')),''' || ' '') ' || svc_name_op || ' ''' || svc_name || '''' end ;
dateentered_where := case when dateentered='%' then ' and 1=1'
when dateentered_op='between' then ' and TO_CHAR(dts_cm_dateentered,''YYYY-MM-DD'') between ' || dateentered
else ' and TO_CHAR(dts_cm_dateentered,''YYYY-MM-DD'') ' || dateentered_op || ' ''' || dateentered || '''' end ;
dynamicsql := 'update '||tablename||' set product_cat_id=' || cast(id as varchar) ||', product_category =''' || product_category || '''';
--add where clause
dynamicsql := dynamicsql || combined_status_where || dts_segment_where || dateentered_where || svc_name_where;
EXECUTE IMMEDIATE dynamicsql;
COMMIT;
FETCH PrivCursor
INTO
ID,
DTS_Segment_op,
DTS_Segment,
DateEntered_op,
DateEntered,
Svc_Name_op,
Svc_Name,
Product_Category,
Priority;
END LOOP;
CLOSE PrivCursor;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Procedure proc_up_dts_product_cat_dynsql failed due to '||SQLERRM);
END proc_up_dts_product_cat_dynsql;
/
The database hurls ORA-00920: invalid relational operator when we submit a SQL statement with a syntax error in a WHERE clause. Usually it's a typo. This is extremely easy to do in dynamic SQL, because we cannot see the whole statement except at run time.
You haven't posted the generated update statement. Well you can't, as your exception handling doesn't display it. Pro tip: when working with dynamic SQL always log or display the generated statement, in the exception block if nowhere else:
dbms_output.put_line('generated statement:'|| dynamicsql);
So this is just a guess but this line looks suspicious ...
when dateentered_op='between' then ' and TO_CHAR(dts_cm_dateentered,''YYYY-MM-DD'') between ' || dateentered
... because it appears to generate a BETWEEN statement with no AND clause. The BETWEEN operator requires two bounds.
But it could be many things. You may be running with an unusual combination of parameters which generates an invalid statement. You need better logging.

procedure issue(error in syntax)

I have the procedure block:
begin
for i in (select grantee
,table_name
,privilege
from user_tab_privs_made
where grantee='TEST')
loop
revoke i.privilege on i.table_name from i.grantee;
end loop;
end;
and the error occurs:
You need to issue the revoke as EXECUTE IMMEDIATE, building a dynamic string with the command you want to be executed:
execute immediate 'revoke ' || i.privilege || ' on ' || i.table_name
|| ' from ' || i.grantee;

Resources