SQL loop
Hi Gurus
Question :
Using only SQL not PL/SQL* can we do loop ?
for example :
SELECT COUNT (*)
FROM (SELECT object_name
FROM all_objects
WHERE object_type = 'TABLE')
Now i am aware we have a static table which can give count but idea here is avoid the PL/SQL and not to use static information.
Objective : to be able to loop using only SQL ...
with the above mentioned query what i want to achieve is :
1. be able to take all tables then do count on all tables one by one.
please help provide comment
855161 wrote:
Again question is to challenge the intellectuals persons who can think outside the box and are creative..... thanksWhy don't you think outside the box yourself and use google or the documentation or a correct forum instead of challenge the intellectuals persons with a question that can be easily solved by taking a look at the documentation.
take a look at the num_rows column of all_tables:
http://docs.oracle.com/cd/E11882_01/server.112/e25513/statviews_2117.htm#i1592091
it will be refreshed every time you gather statistics on your tables. How outside the box and creative is that for you?
cheers
Similar Messages
-
Can we assign value to a variable in PL/SQL Loop
Hi
Can we assign value to a variable in PL/SQL Loops?
DECLARE
V_Num NUMBER;
BEGIN
LOOP
V_Num := 10;
DBMS_OUTPUT.put_line(V_num);
V_Num := V_Num - 1;
EXIT WHEN V_Num = 0;
END LOOP;
END;
In the above program, Can we assign V_num with a value 10????????
Thanks & Regards,
Hari Babu
Edited by: 1004977 on Jun 5, 2013 2:40 AMHi,
1004977 wrote:
Hi
Can we assign value to a variable in PL/SQL Loops?
DECLARE
V_Num NUMBER;
BEGIN
LOOP
V_Num := 10;
DBMS_OUTPUT.put_line(V_num);
V_Num := V_Num - 1;
EXIT WHEN V_Num = 0;
END LOOP;
END;
In the above program, Can we assign V_num with a value 10????????Yes; the example you posted does that.
When the loop starts, the value 10 is assigned to v_num. You should see that value displayed by the put_line statement.
After that, v_num is set to 10 - 1 = 9.
Next, the EXIT condition is evaluated. At this point, v_num is 9, not 0, so the loop runs again. V_num is set to 10 again, and the loop continues forever (or, in some versions, until the dbms_output buffer is filled and an error occurs.) -
PL/SQL LOOP or INSERT MONTH
I have a table below that has START_DATE and END_DATE for each record but not individual row for each month. So, a record can have 6 months payment with start date - '20100101' to end_date 20100630.
I need to find out payment for each month for recon.
I want to add that month field and keep everything else exactly the same as what's in table.
For above example it should add
01-JAN-2010 ................................................ <--- everything else same
01-FEB-2010 ........................
|
|
|
01-JUN-2010 ..........................................................
The helpful fields are START_DATE, END_DATE, NO_OF_MONTHS1 and NO_MONTHS_2. Somethimes, NO_MONTH1 and NO_MONTHS_2 differ. Normally whe they differ, one is 00.
--oracle 10g
--DROP TABLE PAYMENTS;
CREATE TABLE PAYMENTS
CMPNY VARCHAR2,
S_ID VARCHAR2,
NO_MONTHS_1 VARCHAR2,
NO_MONTHS_2 VARCHAR2,
ADJ_CODE VARCHAR2,
START_DATE VARCHAR2,
END_DATE VARCHAR2,
AMOUNT NUMBER
INSERT INTO PAYMENTS (CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('C001','S001','06','06','20','20100101','20100630','30');
INSERT INTO PAYMENTS (CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('C001','S001','04','04','12','20090101','20090430','50');
INSERT INTO PAYMENTS (CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('C002','S001','02','02','20','20090801','20100930','100');
INSERT INTO PAYMENTS (CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('C002','S002','02','02','20','20090801','20100930','100');
INSERT INTO PAYMENTS (CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('C001','S002','01','01','12','20090101','20090131','50');
INSERT INTO PAYMENTS (CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('C001','S001','00','04','18','20090101','20090430','50');
INSERT INTO PAYMENTS (CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('C001','S003','00','02','12','20090501','20090731','50');
INSERT INTO PAYMENTS (CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('C001','S004','01','01','12','20090101','20090131','50');
commit;
RESULTS should be something like
CREATE TABLE PAYMENTS1
ELIGIBLE_MONTH DATE,
CMPNY VARCHAR2,
S_ID VARCHAR2,
NO_MONTHS_1 VARCHAR2,
NO_MONTHS_2 VARCHAR2,
ADJ_CODE VARCHAR2,
START_DATE VARCHAR2,
END_DATE VARCHAR2,
AMOUNT NUMBER
commit;
--BELOW IS AN EXAMPLE OF HOW THE SOLUTION SHOULD COMEOUT FOR FIRST 3 RECORD IN ABOVE TABLE
---for first record in above table, it should create 6 rows, and apply eligible_month to it
INSERT INTO PAYMENTS (ELIGIBLE_MONTH, CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('01-JAN-2010','C001','S001','06','06','20','20100101','20100630','30');
INSERT INTO PAYMENTS (ELIGIBLE_MONTH, CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('01-FEB-2010','C001','S001','06','06','20','20100101','20100630','30');
INSERT INTO PAYMENTS (ELIGIBLE_MONTH, CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('01-MAR-2010','C001','S001','06','06','20','20100101','20100630','30');
INSERT INTO PAYMENTS (ELIGIBLE_MONTH, CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('01-APR-2010','C001','S001','06','06','20','20100101','20100630','30');
INSERT INTO PAYMENTS (ELIGIBLE_MONTH, CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('01-MAY-2010','C001','S001','06','06','20','20100101','20100630','30');
INSERT INTO PAYMENTS (ELIGIBLE_MONTH, CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('01-JUN-2010','C001','S001','06','06','20','20100101','20100630','30');
---IT SHOULD CREATE 4 ROWS
INSERT INTO PAYMENTS (ELIGIBLE_MONTH, CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('01-JAN-2009','C001','S001','04','04','12','20090101','20090430','50');
INSERT INTO PAYMENTS (ELIGIBLE_MONTH, CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('01-FEB-2009','C001','S001','04','04','12','20090101','20090430','50');
INSERT INTO PAYMENTS (ELIGIBLE_MONTH, CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('01-MAR-2009','C001','S001','04','04','12','20090101','20090430','50');
INSERT INTO PAYMENTS (ELIGIBLE_MONTH, CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('01-APR-2009','C001','S001','04','04','12','20090101','20090430','50');
INSERT INTO PAYMENTS (ELIGIBLE_MONTH, CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('01-AUG-2010','C002','S001','02','02','20','20100801','20100930','100');
INSERT INTO PAYMENTS (ELIGIBLE_MONTH, CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('01-SEP-2010','C002','S001','02','02','20','20100801','20100930','100');Hi,
788729 wrote:
I have a table below that has START_DATE and END_DATE for each record but not individual row for each month. So, a record can have 6 months payment with start date - '20100101' to end_date 20100630.
I need to find out payment for each month for recon.
I want to add that month field and keep everything else exactly the same as what's in table.
For above example it should add
01-JAN-2010 ................................................ <--- everything else same
01-FEB-2010 ........................
|
|
|
01-JUN-2010 ..........................................................This seems to be an easier variation of your last question:
Re: PL/SQL LOOP MONTH
You should have some idea about how to do it by now. Post your best attempt.
The helpful fields are START_DATE, END_DATE, NO_OF_MONTHS1 and NO_MONTHS_2. Somethimes, NO_MONTH1 and NO_MONTHS_2 differ. Normally whe they differ, one is 00.What is the role each of those columns plays in this problem? Which one(s) tell how many rows need to be inserted? Why are the others helpful?
>
>
--oracle 10g
--DROP TABLE PAYMENTS;
CREATE TABLE PAYMENTS
CMPNY VARCHAR2,
S_ID VARCHAR2,
NO_MONTHS_1 VARCHAR2,
NO_MONTHS_2 VARCHAR2,
ADJ_CODE VARCHAR2,
START_DATE VARCHAR2,
END_DATE VARCHAR2,
AMOUNT NUMBER
);Don't use VARCHAR2 columns to store dates; alwyas use DATE (or TIMESTAMP) columns.
INSERT INTO PAYMENTS (CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('C001','S001','06','06','20','20100101','20100630','30');
INSERT INTO PAYMENTS (CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('C001','S001','04','04','12','20090101','20090430','50');
INSERT INTO PAYMENTS (CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('C002','S001','02','02','20','20090801','20100930','100');
INSERT INTO PAYMENTS (CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('C002','S002','02','02','20','20090801','20100930','100');
INSERT INTO PAYMENTS (CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('C001','S002','01','01','12','20090101','20090131','50');
INSERT INTO PAYMENTS (CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('C001','S001','00','04','18','20090101','20090430','50');
INSERT INTO PAYMENTS (CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('C001','S003','00','02','12','20090501','20090731','50');
INSERT INTO PAYMENTS (CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('C001','S004','01','01','12','20090101','20090131','50');
commit;Thanks for posting the CREATE TABLE and INSERT statemnets.
RESULTS should be something like
CREATE TABLE PAYMENTS1
ELIGIBLE_MONTH DATE,
CMPNY VARCHAR2,
S_ID VARCHAR2,
NO_MONTHS_1 VARCHAR2,
NO_MONTHS_2 VARCHAR2,
ADJ_CODE VARCHAR2,
START_DATE VARCHAR2,
END_DATE VARCHAR2,
AMOUNT NUMBER
commit;
--BELOW IS AN EXAMPLE OF HOW THE SOLUTION SHOULD COMEOUT FOR FIRST 3 RECORD IN ABOVE TABLEWhy only 3? Post the results that you want from the sample data. If 3 rows is enough to show what the problem is, why did you post 8 rows above? If 8 rows give a better picture of the problem, why not show the results from 8 rows?
>
---for first record in above table, it should create 6 rows, and apply eligible_month to it
INSERT INTO PAYMENTS (ELIGIBLE_MONTH, CMPNY,S_ID,NO_MONTHS_1,NO_MONTHS_2, START_DATE, END_DATE,AMOUNT) VALUES ('01-JAN-2010','C001','S001','06','06','20','20100101','20100630','30');There are 8 columns listed before the VALUES keyword, but 9 values given after it.
There is no eligible_month column in paymemts. Did you mean payments<b>1</b>?
Do you want a query that produces these INSERT statements as strings, or do you actually want to populate payments1 (or payments)?
If you just want to populate a table, show the contents of the populated table in a form people can read and understand, for example:
ELIGIBLE_MONTH CMPNY S_ID NO_MONTHS_1 NO_MONTHS_2 START_DATE END_DATE AMOUNT
01-JAN-2010 C001 S001 06 06 20100101 20100630 30
01-FEB-2010 C001 S001 06 06 20100101 20100630 30
...When you post formatted text on this site, type these 6 characters:
\(small letters only, inside curly brackets) before and after each section of formatted text, to preserve spacing. -
PL/SQL Looping a table and copying some values to another one...
hi all!!!
i'm totally new to pl/sql, and i need to create an interaction to do the following..
my scenario is:
i have a table called "references" that contains 2 columns (new_id, old_id).
then i have another table called "ref" which also contains 2 columns (old_id, other_id).
ok the point is this:
in the table references i have stored the references between 2 products (the old one and the new one) by storing their ids.
now what i have to do by knowing this, is to insert in the table "ref" a new entry for every old_id that is already stored there, but changing it with the new_id that i can get from the other table (references).
let's see an example:
table references:
new_id - old_id
11 - 3
12 - 7
13 - 5
table ref:
old_id - other_id
3 - tu7r
7 - asduih
7 - anotherone
7 - 44444
5 - 6754f
so the result that i want is that the new ids (11,12,13) has to be copied to the table "ref" with the same "other_id" as their correspondants in "references" table.. the result would be:
table ref:
old_id - other_id
3 - tu7r
7 - asduih
7 - anotherone
7 - 44444
5 - 6754f
11 - tu7r
12 - asduih
12 - anotherone
12 - 44444
13 - 6754f
i don't know how to build up a loop or something to reach this aim!!
thanks for your time guys!!!
Edited by: ElMazzaX on Nov 17, 2011 3:15 PMYou do not need pl/sql to do this.
If I understand your datamodel correctly, this join will get you those records you need to insert:
select
references.new_id, ref.other_id
from references
join ref
on ref.old_id = references.old_id;Try that select - it it works, then you can simply do:
insert into ref (old_id, other_id)
select
references.new_id, ref.other_id
from references
join ref
on ref.old_id = references.old_id;SQL is quite enough - no PL/SQL loop necessary ;-) -
Hi,
Here is what I am trying to do. The SQL query retrurns only one record but the loop is execuitng twice. The count returns 2. What could be the problem? Thanks for your help.
type t_name is record(id number, c_name varchar2(100));
type t_names is ref cursor return t_name
Procedure returnVal()
v_t_names t_names;
count number;
BEGIN
count : = 0;
OPEN v_t_names for select user_id, u_name from tableA WHERE dept_id = 100;
LOOP
FETCH v_t_names into t_name;
Exit when v_t_names%not found;
count := count + 1
END LOOP
END returnVal;
---------------------------------------------------------------------After fixing the million and one errors with your example code, I turned it into the following similar so I could run it:
declare
type t_name is record(id number, c_name varchar2(100));
type t_names is ref cursor return t_name;
v_t_names t_names;
v_t_name_rec t_name;
l_count number;
BEGIN
l_count := 0;
OPEN v_t_names for select 1, 'Fred' from dual;
LOOP
FETCH v_t_names into v_t_name_rec;
Exit when v_t_names%notfound;
l_count := l_count + 1;
END LOOP;
dbms_output.put_line(l_count);
END;
/the output was: 1.
The loop does get executed twice - the first time through it does a fetch, finds a record, so doesn't satisfy the EXIT criteria, and updates l_count, and finishes the first loop through. It must then go back to the top of the loop, and fetch another record. However, because there was only 1 record, the exit criteria is now met, so the procedure now jumps out of the loop without updating l_count. So, the loop has been entered twice.
Does that explain things?
Message was edited by:
Boneist
One thought: Since your code was so obviously an example you made up to illustrate your problem, can you guarentee that the "increment the counter" step was AFTER the "exit when cursor%notfound" step in the original?
My guess is that it's before it, so that the count goes up regardless of the cursor having fetched a row or not. -
PL/SQL loop counter for Xpath
I have an XML file that looks like this...
<COL-COMPET_LNG>
<COMPET_LNG>
<LNG_CODE>3</LNG_CODE>
<READ>O</READ>
<WRITE>O</WRITE>
<SPEAK>O</SPEAK>
<UNDERSTAND>O</UNDERSTAND>
</COMPET_LNG>
<COMPET_LNG>
<LNG_CODE>4</LNG_CODE>
<READ>O</READ>
<WRITE>N</WRITE>
<SPEAK>O</SPEAK>
<UNDERSTAND>O</UNDERSTAND>
</COMPET_LNG>
<COMPET_LNG>
<LNG_CODE>1</LNG_CODE>
<READ>O</READ>
<WRITE>N</WRITE>
<SPEAK>O</SPEAK>
<UNDERSTAND>O</UNDERSTAND>
</COMPET_LNG>
<COMPET_LNG>
<LNG_CODE>5</LNG_CODE>
<READ>O</READ>
<WRITE>N</WRITE>
<SPEAK>O</SPEAK>
<UNDERSTAND>O</UNDERSTAND>
</COMPET_LNG>
</COL-COMPET_LNG>
Using PLSQL I would like to loop though each node and process the /LNG_CODE value. I know how to set up the loop and how to access the /LNG_CODE values for each node. I am not sure how to count the number of occurrences of each <COMPET_LNG> node so that I can use it for my max count on the loop. Can anyone help?
Is there a good reference book I can use for this type of PL/SQL programming with XPath? I am using the Oracle manuals but I find the examples a little sparse and would love to read something with some good example code.
Thanks
KarenChris,
Thanks for the help. I now have a loop that works but I am not sure how to extract my data. I have tried...
declare
xml xmltype;
v_other_language VARCHAR2(40);
BEGIN
SELECT ccv_xml INTO xml FROM ccv_xml;
FOR i IN (SELECT value(x) FROM TABLE(XMLSEQUENCE(EXTRACT(xml,'/CV/COL-COMPET_LNG/COMPET_LNG'))) x)
LOOP
SELECT EXTRACTVALUE(xml,'/CV/COL-COMPET_LNG/COMPET_LNG/LNG_CODE')
INTO v_other_language
FROM dual
WHERE EXTRACTVALUE(xml,'/CV/COL-COMPET_LNG/COMPET_LNG/LNG_CODE[i]') > 2;
dbms_output.put_line('Looping'||v_other_language);
END LOOP;
dbms_output.put_line('END');
END;
But my counter 'i' does not seem to be an integer. I get the error message ORA-01403: no data found with this option. I thought I might have access to value(x) in the loop but I don't have that either. How can I access the data that I have now isolated for my loop? I am lost and I can't find an example in the Oracle XML manual.
Thanks for your help
Karen -
Whenever a bogus item_no is in the input record the program exists the loop and doesn't process next record. I have two examples shown one with all valid item_no and processes to completion. The other with the bogus item_no and doesn't complete. I want to complete the records in the file even if the item_no doesn't exist in the mif_stg table. Your assistance is most appreciated.
FOR no_stock_rec IN no_stock_cur
LOOP
DBMS_OUTPUT.PUT_LINE(no_stock_rec.item_no);
UPDATE MIF_STG SET BALANCE_ON_HAND = 0
WHERE MIF_STG.item_no = no_stock_rec.item_no ;
dbms_output.put_line ('before mif status_code');
select mif_stg.status_code into v_mif_status_code
from mif_stg where mif_stg.item_no = no_stock_rec.item_no;
dbms_output.put_line ('mif status_code ' || v_mif_status_code);
END LOOP;
R2043 481689 100327 00004
M0675 388856 100327 00002
F2036 481689 100327 00005
R0698 125034 100403 00002
M2805 481697 100406 00001
SQL> @C:\dataformats\sql\no-stock1.sql
Directory created.
Directory created.
NO-STOCK.txt
NO-STOCK.txt file Exists
481689
before mif status_code
mif status_code 3
388856
before mif status_code
mif status_code 0
481689
before mif status_code
mif status_code 3
125034
before mif status_code
mif status_code 7
481697
before mif status_code
mif status_code
before mif status_code
SQLERRM: ORA-01403: no data found
PL/SQL procedure successfully completed.
SQL> @C:\STARPUBS\STARPUBS\dataformats\sql\no-stock1.sql
Directory created.
R2043 481689 100327 00004
M0675 388856 100327 00002
XXXXX 111111 100327 00001 bogus record ( item_no doesn't exist)
F2036 481689 100327 00005
R0698 125034 100403 00002
M2805 481697 100406 00001
Directory created.
NO-STOCK.txt
NO-STOCK.txt file Exists
481689
before mif status_code
mif status_code 3
388856
before mif status_code
mif status_code 0
111111
before mif status_code
SQLERRM: ORA-01403: no data found
PL/SQL procedure successfully completed.Thanks. I'm a newbie and trying to put this together. I"m working on a process called no_stock. Here is the pseudo code thus far:
Input NOSTOCK file: <this might not be accurate perhaps subaccount field exists>
Accoun ITEM_ID Date QTY
D1324 480579 100409 1
L1277 354448 100409 1
1. Use the ITEM_ID in the NOSTOCK file and in the MIF table assign 0 in the BALANCE_ON_HAND field for that particular ITEM_ID.
2. IF the MIF.STATUS_CODE = 3 for NOSTOCK FILE ITEM_ID then INSERT RECORD to CRAM with CRAM.SUPPLYACTIONCode = ‘UR’. –UR UNDER REVISON
3. ELSE IF MIF.STATUS_CODE = 4 for NOSTOCK FILE ITEM_ID then INSERT RECORD to CRAM with CRAM.SUPPLYACTIONCode = ‘NR’. -- NOT REPRINT
4. ELSE IF MIF.STATUS_CODE = 8 for NOSTOCK.ITEM_ID then
<program stub> POD processing………. To be continued at a later time.
--Not status code 3, 4 or 8
5. ELSE NOSTOCK.ITEM_ID = MIF.ITEM_ID then UPDATE MIF
MIF.BACKORDER + NOSTOCK.QTY -- add qty to backorder qty
INSERT NOSTOCK RECORD to DUE_OUT
UPDATE CRAM.SUPPLYACTIONCODE = ‘DO’ for NOSTOCK.ITEM_ID.
Resources involve:
Input NOSTOCK file
MIF Table
CRAM table
DUE_OUT Table.
Here is my current program:
set serveroutput on
create or replace directory user_dir as 'c:\dataformats\incoming\';
create or replace directory history_dir as 'c:\dataformats\history\';
DECLARE
v_filename VARCHAR2(100); -- Data filename
v_file_exists boolean;
v_file_length number;
v_block_size number;
f utl_file.file_type;
no_stock_rec ext_no_stock_table%rowtype;
v_mif_status_code mif_stg.status_code%TYPE;
CURSOR no_stock_cur IS
SELECT * from ext_no_stock_table;
BEGIN
v_filename := 'NO-STOCK.txt';
DBMS_OUTPUT.PUT_LINE(v_filename); --shows filename
utl_file.fgetattr('USER_DIR', v_filename, v_file_exists, v_file_length ,v_block_size );
IF v_file_exists THEN
dbms_output.put_line( 'NO-STOCK.txt file Exists');
FOR no_stock_rec IN no_stock_cur
LOOP
DBMS_OUTPUT.PUT_LINE(no_stock_rec.item_no);
UPDATE MIF_STG SET BALANCE_ON_HAND = 0
WHERE MIF_STG.item_no = no_stock_rec.item_no ;
dbms_output.put_line ('before mif status_code');
select mif_stg.status_code into v_mif_status_code
from mif_stg where mif_stg.item_no = no_stock_rec.item_no;
dbms_output.put_line ('mif status_code ' || v_mif_status_code);
END LOOP;
commit;
/* utl_file.frename('USER_DIR', v_filename, 'HISTORY_DIR', v_filename || '_' || to_char(SYSDATE,'ddMonth'),
TRUE);
ELSE
dbms_output.put_line('File Does Not Exist');
END IF; -- file exists
EXCEPTION
WHEN UTL_FILE.ACCESS_DENIED THEN
DBMS_OUTPUT.PUT_LINE('No Access!!!');
WHEN UTL_FILE.INVALID_PATH THEN
DBMS_OUTPUT.PUT_LINE('PATH DOES NOT EXIST');
WHEN others THEN
DBMS_OUTPUT.PUT_LINE('SQLERRM: ' || SQLERRM);
END;
/ -
Hi Guys,
Need help here as I'm not good with PL\SQL.
Coming out with a script to purge recycle_bin objects that is older than 14 days.
Basically the syntax will be : purge table owner.object_name.
Please see below:
Can help to correct? I think shouldn't be
--Purge table
sql_stmt := 'PURGE TABLE i.owner."i.object_name"';
EXECUTE IMMEDIATE sql_stmt;
thanks!
create or replace
PROCEDURE PURGE_RECYCLEBIN
AS
sql_stmt VARCHAR2(200);
CURSOR LIST_TO_DELETE IS
Select owner,OBJECT_NAME,TYPE, droptime
from dba_recyclebin
Where to_char(to_date(droptime, 'rrrr-mm-dd hh24:mi:ss'), 'dd-mm-rrrr') < to_char(Sysdate, 'dd-mm-rrrr')
and type='TABLE'
order by droptime;
BEGIN
--Loop through list of tables to purge
FOR i in LIST_TO_DELETE LOOP
BEGIN
--Purge table
sql_stmt := 'PURGE TABLE i.owner."i.object_name"';
EXECUTE IMMEDIATE sql_stmt;
--Rollback all if got any errors.
EXCEPTION WHEN OTHERS THEN
ROLLBACK;
END;
END LOOP;
COMMIT;
END PURGE_RECYCLEBIN;
/dbaing wrote:
Need help here as I'm not good with PL\SQL.The main thing is being "good" at programming - i.e. understanding concepts like structured programming, exception management, modularisation and so on. This is true in all programming languages. And if you get these basics right, you will be able to right good code in any programming language.
When executing that SQL statement - what do you when it fails? For example, the purge command can fail for some or other reason. Do you continue with the loop? Do you halt processing?
You can modularise that and create a procedure whose sole task is to execute a dynamic SQL statement and deal with exceptions that may occur.
E.g. the procedure can be instructed to ignore dynamic SQL exceptions - if that is a requirement.
create or replace procedure ExecSQL( dynamicSQL varchar2, ignoreError boolean default false ) is
begin
execute immediate dynamicSQL;
exception when OTHERS then
if not ignoreError then
raise;
end if;
end;Instead of stringing literals and variables together to make up a dynamic SQL statement, it is far easier to maintain a "template". And then simply substitute tokens/variables in this template with values. E.g.
create or replace procedure PurgeRecyclebin is
PURGE_TEMPLATE constant varchar2(1000) := 'purge table "$OWNER"."$TABLE"';
purgeSQL varchar2(1000);
begin
for c in (select ... ) loop
purgeSQL := replace( PURGE_TEMPLATE, '$OWNER', c.owner );
purgeSQL := replace( purgeSQL, '$TABLE', c.table_name );
ExecSQL( dynamicSQL => purgeSQL, ignoreError => true );
end loop;
end;Instrumentation is another basic concept for good programming. These examples are not instrumented - but should be. For example, recording the actual dynamic SQL statement executed and the SQL%Code response for that execution. Or the duration of the dynamic SQL execution. Etc.
The bottom line is that good programming starts with getting the fundamentals of software engineering right - it is not only about how good your knowledge of that particular programming language is. -
PL/SQL Loop is too slow??
Hi all,
I have a basic loop (LOOP..END LOOP) for reading a very large varchar2 variable. In this Loop i always read 1 caracter for header (size in bytes) and the amount of data. Why this loop processing is too slow??? Can i boost it with something?
Thanx.Function to read data on a socket
Always read 1 byte for length, and with this length,
body of message.
FUNCTION PEGA_MESG (io_Conex_Env IN OUT Utl_Tcp.connection)
RETURN LONG RAW
IS
v_Buffer LONG RAW;
v_Mesg LONG RAW;
v_intResp INTEGER;
v_intBytes INTEGER;
v_qtde_bytes integer;
BEGIN
v_Mesg := NULL;
LOOP
v_intResp := utl_tcp.read_raw(io_Conex_Env, v_Buffer, 1);
v_qtde_bytes := ascii(utl_raw.cast_to_varchar2(v_Buffer));
v_intResp := utl_tcp.read_raw(io_Conex_Env, v_Mesg, v_qtde_bytes);
EXIT WHEN v_Mesg is not null;
END LOOP;
RETURN(v_Mesg);
END;
This is a little peace of my prog. If i send a lot of data, my prog get too slow.
loop
v_Mesg := Pega_Mesg(io_conexao);
if ( v_Mesg = utl_raw.cast_to_raw('sum')) then
v_Mesg := Pega_Mesg(io_conexao);
l_Dados.DELETE;
while v_Mesg <> utl_raw.cast_to_raw('fimsum') loop
for sumario in 1..4 loop -- Loop para quantidade de campos na tabela saida_sumario
l_Dados(sumario) :=Long postings are being truncated to ~1 kB at this time. -
PL/SQL Loop without stopping
Hi, I have a list of procedure name in PROCLIST table. I am planning to fetch it and interate using loop. Inside loop I have to execute the same name procedure.
Problem : The procedure I have to execute without stopping means in the 1st iteration execute 1st procedure, before completion of the 1st procedure it should iterate for next and execute the 2nd procedure. so my task is to execute this all the procedures parallely. Any type of help is appreciated.Hi,
Thanks for reply. I have tried with the same package. but my all the procedure's name in table which I am fetching using cursor loop.
My task is to fetch procedure name from the loop and executed it but the loop shouldn't wait for the 1st procedure to complete. Without waiting for 1st procedure to complete, it should interate for the next & fetch the 2nd procedure's name and execute 2nd procedure parallely. -
One more favor, PLEASe...
CREATE TABLE USR_FAC
FACILITY_ID VARCHAR2(16),
FACILITY_NAME VARCHAR2(30),
DOCTOR_ID VARCHAR2(16),
EFFECTIVE_DATE DATE,
STATUS VARCHAR2(1)
INSERT INTO usr_fac (FACILITY_ID, FACILITY_NAME,doctor_id, effective_date, STATUS) VALUES ('F1001','UNC_HOSPITAL','D1001', '01-JAN-2009','1');
INSERT INTO usr_fac (FACILITY_ID, FACILITY_NAME,doctor_id, effective_date, STATUS) VALUES ('F1001','UNC_HOSPITAL','D1001', '01-OCT-2009','0');
INSERT INTO usr_fac (FACILITY_ID, FACILITY_NAME,doctor_id, effective_date, STATUS) VALUES ('F1002','UNC_HOSPITAL_2','D1001', '01-OCT-2009','1');
INSERT INTO usr_fac (FACILITY_ID, FACILITY_NAME,doctor_id, effective_date, STATUS) VALUES ('F1003','UNC_HOSPITAL_3','D1002', '01-JAN-2010','1');
INSERT INTO usr_fac (FACILITY_ID, FACILITY_NAME,doctor_id, effective_date, STATUS) VALUES ('F1003','UNC_HOSPITAL_3','D1003', '01-FEB-2010','1');
COMMIT;
Here status: 1 - ACTIVE and 0 - TERMINATED.
Similarly, I want to have monthly rows when the docotor is active.
So D1001 should have 1 row each of the month- from 01-jan-2009 to 01-oct-2009 with same facility_id and name.
When he gets terminated, one row is fine.
When he becomes active again, it should restart monthly rows up to sysdate.
THIS WILL BE GREAT HELP.
THANKSHi,
788729 wrote:
People are mess. Alright, I think I know what's going on now.
One issue I am having not because of our IS dep't but our iffy Config dep't.
So for few record like 78 to be exact, either the effective date of status = 1 or effective date of status = 0 is not consistent meaning date is not always '01' in 'DD-MON-YYYY' = '01-JAN-2010'. This is a big issue which I have addressed to config but, meanwhile is there a quick fix to this?
In above case, our first sub-query calculated incorrect MONTHS_NEEDED. For example, IF Config has term doctor on 5/5/2010, then that (DATE - 1) function will keep that provider active in May but infact, he should not be active 4/1/2010.Did you mean "he should not be active <b>5</b>/1/2010"?
That is, if a Termination row is dated May, 1, then you want to insert an Active row for April 1, don't you? If the Termination date is a little later (that is May 5), wouldn't you still want an Active row for April 1?
The query I posted yesterday added
new rows for the 1st of each month up to, but not including, the day of the termination. I think what you're saying now is that you want
new rows for the 1st of each month up to, but not including, the month of the termination.
If that's correct, then just change the place where months_needed is calculated. Instead of subtracting 1 day from the termination date, subtract 1 month .
INSERT INTO usr_fac
( facility_id, facility_name, doctor_id
, effective_date
, status -- If needed
WITH got_months_needed AS
SELECT a.facility_id, a.facility_name, a.doctor_id, a.effective_date
-- , MONTHS_BETWEEN ( TRUNC ( NVL ( MIN (t.effective_date) - 1 -- Old way, August 16
, MONTHS_BETWEEN ( TRUNC ( NVL ( ADD_MONTHS ( MIN (t.effective_date) -- New way, August 17
, -1 -- New way
) -- New way
, SYSDATE
, 'MONTH'
, a.effective_date
) AS months_needed
FROM usr_fac a
LEFT OUTER JOIN usr_fac t ON a.facility_id = t.facility_id
AND a.facility_name = t.facility_name -- If needed
AND a.doctor_id = t.doctor_id
AND a.effective_date < t.effective_date
AND 0 = t.status
WHERE a.status = 1
GROUP BY a.facility_id, a.facility_name, a.doctor_id, a.effective_date
, cntr AS
SELECT LEVEL AS n
FROM (
SELECT MAX (months_needed) AS max_months_needed
FROM got_months_needed
CONNECT BY LEVEL <= max_months_needed
SELECT m.facility_id, m.facility_name, m.doctor_id
, ADD_MONTHS ( m.effective_date
, c.n
) AS effective_date
, '1' -- If needed
FROM got_months_needed m
JOIN cntr c ON c.n <= m.months_needed
;Of course, you don't need the commented-out line that says "Old way", or the comments that say "New way"; I just added them so that you could see where I changed the statement. Except for the computation of months_needed, the statement is the same. (Actually, I got rid of the ORDER BY clause; that was just a relic of the testing process. It only wastes time in an acutal INSERT.)
Given your new sample data, the staement above leaves the usr_fac table looking like this:
FACILITY_ID FACILITY_NAME DOCTOR_ID EFFECTIVE_D STATUS
F1001 UNC_HOSPITAL D1001 01-Jan-2009 1
F1001 UNC_HOSPITAL D1001 01-Feb-2009 1
F1001 UNC_HOSPITAL D1001 01-Mar-2009 1
F1001 UNC_HOSPITAL D1001 01-Apr-2009 1
F1001 UNC_HOSPITAL D1001 01-May-2009 1
F1001 UNC_HOSPITAL D1001 01-Jun-2009 1
F1001 UNC_HOSPITAL D1001 01-Jul-2009 1
F1001 UNC_HOSPITAL D1001 01-Aug-2009 1
F1001 UNC_HOSPITAL D1001 01-Sep-2009 1
F1001 UNC_HOSPITAL D1001 01-Oct-2009 0
F1002 UNC_HOSPITAL_2 D1001 01-Oct-2009 1
F1002 UNC_HOSPITAL_2 D1001 01-Nov-2009 1
F1002 UNC_HOSPITAL_2 D1001 01-Dec-2009 1
F1002 UNC_HOSPITAL_2 D1001 01-Jan-2010 1
F1002 UNC_HOSPITAL_2 D1001 01-Feb-2010 1
F1002 UNC_HOSPITAL_2 D1001 01-Mar-2010 1
F1002 UNC_HOSPITAL_2 D1001 01-Apr-2010 1
F1002 UNC_HOSPITAL_2 D1001 05-May-2010 0
F1003 UNC_HOSPITAL_3 D1002 01-Jan-2010 1
F1003 UNC_HOSPITAL_3 D1002 01-Feb-2010 1
F1003 UNC_HOSPITAL_3 D1002 01-Mar-2010 1
F1003 UNC_HOSPITAL_3 D1002 01-Apr-2010 1
F1003 UNC_HOSPITAL_3 D1002 01-May-2010 1
F1003 UNC_HOSPITAL_3 D1002 01-Jun-2010 1
F1003 UNC_HOSPITAL_3 D1002 01-Jul-2010 1
F1003 UNC_HOSPITAL_3 D1002 01-Aug-2010 1
F1003 UNC_HOSPITAL_3 D1003 01-Feb-2010 1
F1003 UNC_HOSPITAL_3 D1003 01-Mar-2010 1
F1003 UNC_HOSPITAL_3 D1003 01-Apr-2010 1
F1003 UNC_HOSPITAL_3 D1003 01-May-2010 1
F1003 UNC_HOSPITAL_3 D1003 01-Jun-2010 1
F1003 UNC_HOSPITAL_3 D1003 01-Jul-2010 1
F1003 UNC_HOSPITAL_3 D1003 01-Aug-2010 1That seems to be what you want, but "Esse non videre", as the Tar Heels say. Correct me if you need different results. -
How to run a SQL query which is stored in a column using PL/SQL?
Hello
I have a table A and one of the column values is select * from emp where empno :=xyz;
Now I would like to call this SQL query using a cursor in PL/SQL and run this for all the empno's and insert them into a temp table.
Can anybody help me in writing this PL/SQL query?
With Regards,
Mohanuser525114 wrote:
The primary reason for doing this is we are calculating percentiles on an entity sales for different range periods, and there are several sql queries stored in a cloumn, so we would like to know whether we can run these queries by calling them in a pl/sql query, Its not necessary that we need to use a cursor, but once fetching the result set of the query we would like to insert them in a table.Vamsi,
As said in response to Satya, executing dynamic SQL, looping over the result set and inserting the results one by one in a temporary table, is a horribly bad idea. Especially in terms of performance, but also regarding the maintainability of your code. It's just way more complex than necessary.
If you want to calculate percentages, then use analytic or aggregate functions in SQL to do so. If you want to store them, use a single INSERT SELECT statement.
If you want to continue on the same path, use Satya's code and use it inside a loop.
Regards,
Rob. -
Taking user input in a PL/SQL block
Can someone tell me if it is possible to to take user input from within a PL/SQL loop? I mean I want that for each iteration in the loop, the program first take user input, and then based on that input, it perform specific operations. Then it repeats this process for each subsequent iteration of loop.
If it is not possible in PL/SQL, is there any other alternative?
Thanks.> I'm afraid I have no idea how to get the server to ask questions of the user,
especially when it essentially operates in a kind of batch mode.
Yep. To expand a tad on what Hans mentioned here.
To accept input, the process needs to be able to read from this input device. Let's make it a keyboard. The PL/SQL process needs to read keyboard input.
The keyboard is attached to a PC 1000km away in a branch office. The Oracle server process, running on a server in the data centre, executes this PL/SQL code.
So now this PL/SQL process has to automagically hack its way across the network. It needs to remove the keyboard plug from that client PC. It somehow must get that keyboard rewired, across that 1000km, into the server platform at the data centre. And only then can the Oracle server process running that PL/SQL code read from that keyboard input device and accept user input.
It is important, when developing in Oracle, to grasp just what client-server is and how it works. And not to confuse something like a SQL*Plus Client Process (submitting PL/SQL code) with the Oracle Server Process (parsing and executing that submitted PL/SQL code). -
In general, how do I put code into a loop?
I have access to a procedure that takes a parameter and spits out a single result. I need to figure out how to use that procedure and spit out many results. This example should clear things up.
VARIABLE enum NUMBER;
EXEC :enum := 7566;
-- my procedure. Cannot change code here.
-- Prints out a formatted name and job, given an empno stored in :enum
SELECT ename || ' (' || job || ')' AS "myrow"
FROM scott.emp
WHERE empno = :enum;
-- end of my procedureHere, I can't change anything from the SELECT to the semi-colon. Now I would like to put this into a PL/SQL LOOP, but I can't figure it out. Let's say I want to print out all of the employees with a job of manager. Somehow I will need enum to take the value of the current iteration from within the loop.
something like this:
BEGIN
-- first get the list of employees
CURSOR e_cur IS
SELECT empno
FROM scott.emp
WHERE job="MANAGER';
END;
BEGIN
FOR r_cur IN e_cur LOOP
:enum = r_cur.empno
-- my procedure. Cannot change code here.
-- Prints out a formatted name and job, given an empno stored in :enum
SELECT ename || ' (' || job || ')' AS "myrow"
FROM scott.emp
WHERE empno = :enum;
-- end of my procedure
END LOOP;
END;
{code}
of course, this code does not work, and I don't know what else to try.
Thanks in advance for any help!
SkipOh boy, do I owe you guys an apology. Absolutely no excuse, but I screwed up big time yesterday. I am working on a couple of projects and got some wires crossed. I would like to start over. Forget everything I asked yesterday. I wouldn't be surprised if no one answered, but I could still use some help. I am embarrassed because I am usually pretty good at these things, and again, I humbly apologize.
Still with me? Here we go:
I have a SQL script that is quite long. It has 25 select statements, 4 unions, 7 minus'es, lots of joins, sub-queries, etc. The script expects two bind variables to be set before running. The code was written to execute once (like a report). But the code does exactly what I need, but I need to run it on a much larger set. So I would like to wrap it in a loop. Now, I am pretty good at other programming languages (I know, hard to believe given yesterday's exchange). If I have some java code that I want to wrap in a FOR-NEXT loop, often all I need to do is put one line at the top of the code and one line at the bottom. Then I make sure the variables that need t be updated through each iteration are properly updated. Bada-bing, bada-boom, it's done.
It doesn't seem as easy here. I know that I will have to convert my SQL script to PL/SQL. But I am wrestling with the DECLAREs, BEGINs and LOOPs, and changes to the existing code to ensure the bind variables are updated each iteration. I have tried all of what I thought would be the simple solutions as I described with my java example above, but it has not worked. So, as my subject line indicates, I was wondering if there was a general methodology to LOOP-ifying existing code. I know this is a pretty nebulous question, and I probably blew it yesterday, but I really do need some help. Even if it is "read this and that website/book/etc". That's really it. sigh All that stuff yesterday about "unmodifiable code"--forget about that. I should never have said that. Anything goes.
Maybe there isn't a simple solution here. SQL isn't Java. And that's OK. At least then I will know I will need to look for a different solution or I will have to get a LOT smarter with SQL and PL/SQL. I thought my super-simple example yesterday was a good enough substitute for what I am faced with, but maybe that isn't a good assumption. -
Hi,
I need help or suggestions in writing a pl/sql loop query against the data in Table A in order to get the output of Table B.
Table A
id type valu
1 a x
1 a y
1 a x
1 b 3
1 c 33
2 a x
2 b 55
2 c 33
The output should be inserted in a new table.The expected output
Table B output
id list_a List_B List_C
1 x,y,x 3 33
2 x 55 33
ThanksTry this
SQL> with t
2 as
3 (
4 select 1 id, 'a' type, 'x' value from dual union all
5 select 1 id, 'a' type, 'y' value from dual union all
6 select 1 id, 'a' type, 'x' value from dual union all
7 select 1 id, 'b' type, '3' value from dual union all
8 select 1 id, 'c' type, '33' value from dual union all
9 select 2 id, 'a' type, 'x' value from dual union all
10 select 2 id, 'b' type, '55' value from dual union all
11 select 2 id, 'c' type, '33' value from dual
12 )
13 select id, max(decode(type, 'a', value)) list_a, max(decode(type, 'b', value)) list_b, max(decode(type, 'c', value)) list_c
14 from (
15 select id, type, max(value) value
16 from (
17 select id, type, ltrim(sys_connect_by_path(value, ','),' ,') value
18 from (
19 select t.*, row_number() over(partition by id, type order by 1) rno
20 from t
21 )
22 start with rno = 1
23 connect by rno = prior rno + 1
24 and id = prior id
25 and type = prior type
26 )
27 group by id, type
28 )
29 group by id
30 /
ID LIST_A LIST_B LIST_C
1 x,y,x 3 33
2 x 55 33
SQL>
Maybe you are looking for
-
I have writing on a photo how can i get rid of it
i have writing on a photo how can i get rid of it
-
Different currency during invoice entering
Dear expertise, Is it possible to enter a PO invoice with T. Code - MIRO with different currency that maintained in the PO currency. Suppose a po is in USD. Is it possible to enter invoice against the PO with INR? Can you please guide me how to enter
-
How can I establish many to many unidirectional relationship?
Hi, EJB Fans! I am an ejb fan too. This time I am learn ejb2.0 and find very funny in cmr. I think it is a good idea and can do manythings we cann't do or difficult with ejb1.1. But in many to many relationship, I don't know how to give my tables to
-
I was downloading a game on my iPad and then it stop and kept saying waiting when I click it nothing happens and I try to delete it and it won't what should I do
-
Hi All using of TRANSLATE text to UPPER|LOWER CASE When i run extended check it is giving this error message "Dangerous use of TRANSLATE in a multilingual system" what it mean please