Dynamic query in Cursor for loop - sql

I am facing one issue with Dynamic query.I am trying to update one update statement by using dynamic SQL in cursor for loop.
Can you please help me how to execute this...
declare
statement varchar2(1000);
begin
for c1 in(select tenant_id from tenant where tenant_id!=0)
loop
for c2 in ( select alignment_id from customer_alignment where affiliation_id is null and tenant_id=c1.tenant_id)
loop
insert into t3 select 1 from dual;
for c3 in ( select *
from ca_primary_address ca,customer_alignemnt ca where ca.affiliation_id is null
and ca.alignment_id=c2.alignment_id
and ca.customer_id=vw.customer_id
and ca.alignment_id=vw.alignment_id
)
loop
statement :='update customer_alignment set affiliation_id='||vw.affiliation_id||' where customer_alignment_id='||customer_alignment_id||';'
execute immediate('begin '||STATEMENT||' end;');
end loop;
end loop;
dbms_output.put_line('Tenant_id '||c1.tenant_id);
end loop;
end;
Am getting below error msg while executing
ORA-06550: line 8, column 10:
PLS-00402: alias required in SELECT list of cursor to avoid duplicate column names
Please help me on this issue.
Many Many thanks for your help.
Sunitha..

Try the following:
...
statement :='update customer_alignment set affiliation_id='||c3.affiliation_id||' where customer_alignment_id='||c3.customer_alignment_id;
execute immediate(statement);
...
You have to qualify your variables used in the update query string with the cursor variable.

Related

How to create a Procedure with a specific WITH clause in Oracle?

I have a problem by creating a Procdure with a specific WITH clause. I use an Oracle database. I need a temp table for mapping specific values during time of execution.
In addition I have the following Oracle procedure. This Procedure will be created and executed by bringing into database:
How can I create this kind of Oracle SQL Procedure? Many thanks for helping me!
Use your WITH clause in a cursor FOR loop in your procedure:
DECLARE
PROCEDURE myProcedure(pinSchema IN VARCHAR2) AS
BEGIN
FOR aRow IN (WITH t AS (SELECT 'myFirstOldSchema' AS OLD_SCHEMA,
'myFirstNewSchema' AS NEW_SCHEMA
FROM DUAL UNION ALL
SELECT 'mySecondOldSchema' AS OLD_SCHEMA,
'mySecondNewSchema' AS NEW_SCHEMA
FROM DUAL UNION ALL
SELECT 'myThirdOldSchema' AS OLD_SCHEMA,
'myThirdNewSchema' AS NEW_SCHEMA
FROM DUAL)
SELECT t.*
FROM t
WHERE t.OLD_SCHEMA = pinSchema)
LOOP
-- Here a specific value from column "OLD_SCHEMA" must be inserted
EXECUTE IMMEDIATE 'INSERT INTO ' || aRow.OLD_SCHEMA ||
'.myTable(column_1, column_2, column_3)
(SELECT extern_column_1,
extern_column_2,
extern_column_3
FROM ' || aRow.NEW_SCHEMA || '.myExternTable)';
END LOOP;
END myProcedure;
BEGIN
FOR S IN (SELECT * FROM ROOT_SCHEMA.myTableWithSchema)
LOOP
-- First loop S.mySchemata represent the value 'myFirstOldSchema'
-- Second loop S.mySchemata represent the value 'mySecondOldSchema'
-- Third loop S.mySchemata represent the value 'myThirdOldSchema'
myProcedure(S.mySchemata);
END LOOP
COMMIT;
END;
Not tested on animals - you'll be first!

How to check that a value is NOT IN a %ROWTYPE from an SQL statement

Im writing a PLSQL stored procedure. Note that the below is only a part of it and the actual SP is complex than this. All I want to know is that in my nested query below, how i can check a certain value is not in the ROWTYPE that i named as 'l_05_data' ? Is there a way to do it without running thourgh a loop. Currently i have no idea on how to make this check in my nested query because im getting the below error when compiling. Someone please provide a solution for this.
**
Error(52,7): PL/SQL: SQL Statement ignored
Error(66,41): PL/SQL: ORA-00904: "l_05_data"."A2_ID_FK": invalid identifier
Error(66,51): PLS-00302: component 'A2_ID_FK' must be declared
**
stored procedure
create or replace PROCEDURE TEST_SP()
AS
TYPE r05_array IS TABLE OF A2_TBL%ROWTYPE;
l_05_data r05_array;
CURSOR r5_cur
IS
SELECT a2.*
FROM A2_TBL a2;
BEGIN
OPEN r5_cur;
LOOP
BEGIN
FETCH r5_cur BULK COLLECT INTO l_05_data LIMIT batch_limit;
EXIT WHEN l_05_data.count() = 0;
FOR indx IN l_05_data.FIRST ..l_05_data.LAST
LOOP
--some logic
END LOOP;
SELECT A1 BULK COLLECT
INTO l_01_id_data
FROM
( SELECT distinct column_value AS A1 FROM TABLE(l_01_id_data)
MINUS
(
SELECT distinct a1.A1_ID
FROM A1_TBL a1
INNER JOIN A2_TBL a2
ON a1.A1_ID = a2.A2_A1_ID_FK
WHERE a2.A2_STATUS !='X'
OR (a2.A2_A1_ID_FK NOT IN (l_05_data.A2_A1_ID_FK) AND a2.A2_STATUS = 'X')
)
);
COMMIT;
EXCEPTION
--exception is handled here
END;
END LOOP;
CLOSE r5_cur;
END TEST_SP;
below is the two table schema used in the SP

looping and executing dynamic query in Oracle

I'm having some trouble truncating some tables that get generated in my base.
The table names get saved and I can do it manually, but I wanted to see if it could be automated until its fixed.
What I've done so far is get all the table names and a id/number into my own help table. My errors begin around the loop/Execute immediate where im not sure how to use the data I've gotten in the syntax and i cant find any similar examples.
create table HlpTruncTable as SELECT SUBSTR(argument, 3) as tblName, rownum as Nr
FROM tblLogHlp
WHERE status = 'E' and argument like '0,awfh%' and LAST_UPDATE <= ADD_MONTHS(sysdate,-1);
for i in 1..(select max(nr) from HlpTruncTable) LOOP
execute immediate TRUNCATE TABLE (select tblName from HlpTruncTable where nr = (i));
END LOOP;
drop table hlpTruncTable;
I would do it like this:
declare
cursor HlpTruncTable is
SELECT SUBSTR(argument, 3) as tblName
FROM tblLogHlp
WHERE status = 'E' and argument like '0,awfh%' and LAST_UPDATE <= ADD_MONTHS(sysdate,-1);
BEGIN
FOR aTable IN HlpTruncTable LOOP
execute immediate 'TRUNCATE TABLE '||aTable.tblName;
END LOOP;
END;

PL/SQL block and LOOP exercise

I have to create a PL/SQL block to insert 10 to 100 multiples of 10 in a table called TEN_MULTIPLES that I have to create... (SCHEMA -> TEN_MULTIPLES(numbervalue)). I will have to insert inside the table only 10,20,30,...,100 but exluding 50 and 90. So far I have done this... is it correct?
DECLARE
CREATE TABLE ten_multiples
(numbervalue NUMBER (3));
BEGIN
FOR i IN 9..101 LOOP
IF (i = 50 OR i = 90) THEN
ELSIF (i%10 = 0) THEN
INSERT INTO ten_multiples
VALUE (i);
END IF;
END LOOP;
END;
When I use 10..100 are 10 and 100 included and evaluated as 'i' in the loop?
I need also to find the MAXIMUM number from that table using a cursor, so in this case 100, store it in a variable 'num' declared in the DECLARE part and print it out...
DECLAR
CURSOR my_cursor IS
SELECT MAX(v_number) FROM ten_multiples;
num NUMBER;
BEGIN
OPEN my_cursor;
FETCH my_cursor INTO (num);
DBMS_OUTPUT.PUT_LINE(‘Maximum number is ‘ | num);
CLOSE my_cursor;
END;
Is this right?
I really thank you in advance :)
Why is so much PL/SQL coursework consists of exercises in how not to use PL/SQL?
insert into ten_multiples
with data as ( select level*10 as mult
from dual
connect by level <=10)
select * from data
where mult not in (50,90)
/
First part:
You cannot execute the CREATE TABLE statement directly in a PL/SQL
context. You must use the DBMS_DDL package or dynamic SQL via the
EXECUTE IMMEDIATE command, if you must execute within PL/SQL context.
Yes number literals in the for loop are included.
Second part:
Use DECLARE not DECLAR.
Your SELECT member must be a column of the table, not v_number.
Your single quote character is incorrect, use ', not ‘.
Use double pipe for concatenation, not single.
Finally:
Actually run these commands through SQL*Plus and listen to the tool.
Trying is your friend.

SQL Query Using Cursor and table variable for output table

can you please suggest using loops (IF else) ...like reading the data using conditions i.e. <=5, and by insert statement storing it in a temporary table variable and by using final select statement we are getting the output... plz help
Input table is having data and result table should read all the data from the input table and check the length of the Name column and should print the length which is <=5 in the result table
DECLARE
CURSOR c_input
IS
SELECT * FROM table_a;
BEGIN
FOR x IN c_input
LOOP
IF LEN(x.name) <= 5 THEN
dbms_output.put_line(x.name) ;
--Insert statement if you wish to insert this in result table
END IF;
END LOOP;
END;
Thanks,
Jayati