PL/SQL: Procedures Successful with compilation error - oracle

I am trying to create a procedure to dump out specific data from few tables:
CREATE OR REPLACE PROCEDURE Lab9_View IS
--declare the variable
o_Id orders.OrderID%type;
o_date orders.orderdate%type;
s_date orders.shippeddate%type;
c_name customers.companyname%type;
s_country orders.shippeddate%type;
--define CURSOR for select
CURSOR Lab9_View IS
SELECT OrderId, OrderDate, ShippedDate, CompanyName, ShipCountry
FROM Orders JOIN Customers ON
customers.customerid = orders.CustomerId WHERE ORDERDATE BETWEEN '2019-08-14' AND '2019-08-23';
--exceution begin here
BEGIN
--heading line
dbms_output.put_line(' Harry''s Lab9 - Orders by COuntry Aug. 14th-23rd ');
dbms_output.put_line(' Order #' || ' '|| ' Order Date' || ' ' || 'Shipped Date' || " " || 'Company Name' || ' ' || 'Ship Country');
--execute the select
OPEN Lab9_View;
--retrieve each row from result in loop
LOOP
FETCH Lab9_View into o_id, o_date, s_date, c_name, s_country;
--end of result reach
EXIT WHEN Lab9_View%notfound;
--dump out data
dbms_output.put_line(o_id || ' '|| o_date || ' ' || s_date || " " || c_name || ' ' || s_country);
END LOOP;
--close cursor
CLOSE Lab9_View;
END;
I keep on getting this error:
ORA-24344: success with compilation error
ORA-06512: at "SYS.WWV_DBMS_SQL_APEX_200100", line 581
ORA-06512: at "SYS.DBMS_SYS_SQL", line 1658
ORA-06512: at "SYS.WWV_DBMS_SQL_APEX_200100", line 567
ORA-06512: at "APEX_200100.WWV_FLOW_DYNAMIC_EXEC", line 2127
3. o_Id orders.OrderID%type;
4. o_date orders.orderdate%type;
5. s_date orders.shippeddate%type;
6. c_name customers.companyname%type;
7. s_country orders.shippeddate%type;
I can't spot anything different from my professor's lab notes. Can anyone see anything wrong with my code?
Thank you

You have double quotes instead of single quotes between two of the columns in your put_line commands.

Related

What is wrong with my procedure sql

my procedure is like below;
CREATE OR REPLACE PROCEDURE updateWEEK_SALES_REPORTS
( p_start IN WEEK_SALES_REPORT.StartDate%TYPE,
p_end IN weekly_sales_report.EndDate%TYPE)
IS
BEGIN
UPDATE WEEK_SALES_REPORT SET ComAmount = SaleAmount*ComRate WHERE (StartDate-EndDate) = (p_start-p_end);
SELECT concat('The commission amount for report ',ReportID,' has been updated to ',ComAmount,' dollars,
which is',ComRate,'% of the total sale amount of ',SaleAmount,' dollars.')
COMMIT;
END;
/
but show errors is
7/3 PL/SQL: SQL Statement ignored
7/10 PL/SQL: ORA-00909: invalid number of arguments
I'm pretty sure you're trying to print your message to the console. For that, you want dbms_output.
CREATE OR REPLACE PROCEDURE updateWEEK_SALES_REPORTS
( p_start IN date,
p_end IN date)
IS
BEGIN
UPDATE WEEK_SALES_REPORT SET ComAmount = SaleAmount*ComRate WHERE (StartDate-EndDate) = (p_start-p_end);
dbms_output.put_line('The commission amount for report ' || ReportID || ' has been updated to ' || ComAmount || ' dollars,
which is' || ComRate || '% of the total sale amount of ' || SaleAmount || ' dollars.');
COMMIT;
END;
Yes, #Jacob H is right, CONCAT takes only 2 parameters. Use || instead, much uglier than your version, though:
SELECT 'The commission amount for report ' || ReportID ||
' has been updated to ' || ComAmount || ' dollars, which is' ||
ComRate || '% of the total sale amount of ' || SaleAmount ||
' dollars.' ...
Furthermore, you need to SELECT it INTO some variable like, f.i.
SELECT ... INTO myvar FROM DUAL;

Procedure which gives grants, Invalid table name error

I'm trying to create a procedure which gives grants to specific schema objects. Procedure seems to compile ok, but it gives an error when execution.
Something is wrong in this simple procedure but I cannot find the reason for this.
Procedure:
create or replace procedure ch.grants_to_schema_objects(
i_target_schema varchar2,
i_target_user varchar2) as
begin
for mt in (SELECT 'GRANT SELECT ON ' || chr(39)
|| i_target_schema || chr(39)
|| '.' || TABLE_NAME || ' TO ' || chr(39)
|| i_target_user || chr(39)
|| ' WITH GRANT OPTION' as grnt
FROM ALL_TABLES
WHERE OWNER = i_target_schema) loop
dbms_output.put_line(mt.grnt);
execute immediate mt.grnt;
end loop;
end;
call:
execute ch.grants_to_schema_objects('SR', 'CH');
Error:
ORA-06512: "CH.GRANTS_TO_SCHEMA_OBJECTS", line 5
ORA-06512: line 1
00903. 00000 - "invalid table name"
*Cause:
*Action:
The CHR(39) is breaking it. Replace it whit CHR(34): it is " you need to separate your username, not '.

Oracle: update table using dynamic column names

I am using Oracle 11g. My tables include columns like name and l_name (lowercase of name column). I am trying to iterate through all the columns in my table space to set the l_ columns to lowercase of their respective uppercase columns. Here is what I tried:
for i in (select table_name from user_tables) loop
SELECT SUBSTR(column_name,3) bulk collect into my_temp_storage FROM user_tab_columns WHERE table_name = i.table_name and column_name like 'L\_%' escape '\';
for j in (select column_name from user_tab_columns where table_name = i.table_name) loop
for k in 1..my_temp_storage.count
loop
if(j.column_name like 'L\_%' escape '\' and SUBSTR(j.column_name,3) = my_temp_storage(k)) then
DBMS_OUTPUT.PUT_LINE( 'update ' || i.table_name || ' set ' || j.column_name || ' = LOWER(' ||my_temp_storage(k)|| ') where ' || j.column_name || ' is not null');
execute immediate 'update ' || i.table_name || ' set ' || j.column_name || ' = LOWER(' ||my_temp_storage(k)|| ') where ' || j.column_name || ' is not null';
end if;
end loop;
end loop;
end loop;
I am storing all the names of columns in uppercase in my_temp_storage and updating the table with the LOWER value of the columns in my_temp_storage. This gave me an error saying:
Error report -
ORA-00900: invalid SQL statement
ORA-06512: at line 8
00900. 00000 - "invalid SQL statement"
*Cause:
*Action:
But the DBMS output seemed to be fine:
`update EMPLOYEE set L_NAME = LOWER(NAME) where L_NAME is not null`
Could you help me with the way I did or any other way it can be done?
The program could certainly be simplified:
begin
for i in (select table_name, column_name from user_tab_columns
where column_name like 'L\_%' escape '\')
loop
l_sql := 'update ' || i.table_name || ' set ' || i.column_name
|| ' = LOWER(' ||substr(i.columm_name,3)
|| ') where ' || i.column_name || ' is not null';
execute immediate l_sql;
end loop;
end;
It seems an odd database design though. Have you considered virtual columns, and/or function-based indexes, instead of manually maintained columns?

Gettig error PLS-00364

I'm trying to create a stored procedure where I'm passing select statement to for loop and i'm using dynamic table which is passing at runtime and getting below error:
LINE 23 PLS-00364: loop index variable 'I' use is invalid
LINE 19 PL/SQL: ORA-00942: table or view does not exist
CREATE OR REPLACE PROCEDURE CREATE_TEST(TBL_NM IN VARCHAR2)
IS
SRC_ID NUMBER(38);
SQL_Q VARCHAR2(250);
DEL_F VARCHAR2(250);
BEGIN
FOR I in (SELECT DEL_IND FROM TBL_NM)
LOOP
SRC_ID := SRC_FILE_ID_SEQ.NEXTVAL;
IF I.DEL_IND = 0
THEN
execute immediate 'INSERT INTO TEST_HIST ' || ' (a,b,c,d,e,DEL_IND) ' ||
' SELECT a,b,c,d,e, '|| 0 || ' || ' FROM ' || TBL_NM;
ELSIF I.DEL_IND = 1
THEN
execute immediate 'INSERT INTO JESTX_IGNR ' || ' (a,b,c,d,e,DEL_IND,SRC_ID_NO) ' ||
' SELECT a,b,c,d,e, '|| 2 ||' , '|| SRC_ID || ' FROM ' || TBL_NM;
END IF ;
END LOOP;
COMMIT;
END;
I call the procedure using:
EXEC CREATE_TEST('abc');
What you want is a REF CURSOR as you cannot use cursor for loop with dynamic sql.
I dont know the exact datatype for your column DEL_IND. Please declare accordingly.
Here is some more information on Oracle REF CURSORS.
Try below
CREATE OR REPLACE PROCEDURE CREATE_TEST(TBL_NM IN VARCHAR2)
IS
TYPE c1ref is REF CURSOR;
SRC_ID NUMBER(38);
SQL_Q VARCHAR2(250);
DEL_F VARCHAR2(250);
DEL_IND NUMBER(5);
BEGIN
vsql_text := 'select DEL_IND from ' || TBL_NM;
open c1ref for vsql_text;
LOOP
SRC_ID := SRC_FILE_ID_SEQ.NEXTVAL;
fetch c1ref into DEL_IND;
exit when c1ref%NOTFOUND;
IF (DEL_IND = 0)
THEN
execute immediate 'INSERT INTO TEST_HIST ' || ' (a,b,c,d,e,DEL_IND) ' ||
' SELECT a,b,c,d,e, '|| 0 || ' || FROM ' || TBL_NM;
ELSIF (DEL_IND = 1)
THEN
execute immediate 'INSERT INTO JESTX_IGNR ' || ' (a,b,c,d,e,DEL_IND) ' ||
' SELECT a,b,c,d,e, '|| 2 ||' , '|| SRC_ID || ' FROM ' || TBL_NM;
END IF ;
END LOOP;
CLOSE c1ref;
COMMIT;
END;

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.

Resources