Learning... cursor and loop... suggestions?
Although I'm looking for non version specific information... Here is what I'm running on.
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
CORE 11.2.0.3.0 Production
TNS for Solaris: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production
I'm trying to figure out the whole relationship and execution of inserting data into a table, manipulating the table and anything else via a procedure using a cursor and a loop.
Sounds simple, but all the examples I find out there all deal with dbms_output.. obviously because it's 'safe'...
So I'm trying to use context that my mind makes quick sense of.
I built a simple table with vehicle makes, with the intention of using exercises to add models, trim levels, engines...pretty much all vehicle specifications.
CREATE TABLE VEH_COMP
MAKE VARCHAR2(20 BYTE),
MODEL VARCHAR2(50 BYTE),
TRIM VARCHAR2(50 BYTE),
ENGINE VARCHAR2(50 BYTE),
TRANSMISSION VARCHAR2(50 BYTE),
HORSEPOWER NUMBER,
TORQUE NUMBER
TABLESPACE USERS
RESULT_CACHE (MODE DEFAULT)
PCTUSED 0
PCTFREE 10
INITRANS 1
MAXTRANS 255
STORAGE (
INITIAL 80K
NEXT 1M
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
LOGGING
NOCOMPRESS
NOCACHE
NOPARALLEL
MONITORING;
Next I tried to build a simple sql block to insert a handful of Auto makes into the table... I know this is ugly, and here is where I'm looking for suggestions for improvement.
DECLARE
CURSOR m1
IS
SELECT 'Ford' as make FROM DUAL
UNION ALL
SELECT 'Chevy' FROM DUAL
UNION ALL
SELECT 'Dodge' FROM DUAL
UNION ALL
SELECT 'BMW' FROM DUAL
UNION ALL
SELECT 'Audi' FROM DUAL
UNION ALL
SELECT 'Mercedes' FROM DUAL;
BEGIN
FOR v_make IN m1
LOOP
dbms_output.put_line(v_make.make);
insert into veh_comp (make) values (v_make.make);
END LOOP;
END;
Now I'm looking to add models. Like Ford Mustang, Ford Lightning, Chevy Corvette, Chevy Camaro, Dodge Charger, Dodge Challenger, Dodge Viper, BMW M5, BMW M3, BMW M6...
Then I need to add engine sizes... I6, V8
Then I need to add transmission... M6, M5, A5, A6, A8
I'm a little confused as how I should execute this part. Or better yet, I'm sure there is a better way to include it all at once...
I've been looking on line on how to do this and again...only really finding dbms_output.put_line. And I did grasp how I could do something along this lines from using a spool file. But I really want to learn to be more efficient.
What's the best way to do this?
Thanks.
From what I can gather from the code, if I create some example data, you just want a query that does something like...
SQL> select * from vw_ta;
LID SID C0 C1 C2 C3
1 1 1 2 3 4
1 2 1 2 3 4
1 3 1 2 3 4
1 4 1 2 3 4
1 5 1 2 3 4
1 6 1 2 3 4
2 1 1 2 3 4
2 2 1 2 3 4
2 3 1 2 3 4
3 1 1 2 3 4
3 2 1 2 3 4
3 3 1 2 3 4
3 4 1 2 3 4
3 5 1 2 3 4
3 6 1 2 3 4
3 7 1 2 3 4
4 1 1 2 3 4
5 1 1 2 3 4
5 2 1 2 3 4
19 rows selected.
SQL> ed
Wrote file afiedt.buf
1 SELECT LID, SID, Cnt, Limits, dense_rank() over (order by lid) as grp, Iter
2 FROM (SELECT LID
3 ,SID
4 ,COUNT(*) OVER (PARTITION BY LID) Cnt
5 ,TRUNC(COUNT(*) OVER (PARTITION BY LID)/4)*4 Limits
6 ,row_number() over (partition by LID order by SID desc) iter
7 FROM VW_TA
8 WHERE C0 > 0 AND C1 > 0 AND C2 > 0 AND C3 > 0
9 ORDER BY LID, SID DESC
10 ) a
11* WHERE ITER <= LIMITS
SQL> /
LID SID CNT LIMITS GRP ITER
1 6 6 4 1 1
1 5 6 4 1 2
1 4 6 4 1 3
1 3 6 4 1 4
3 7 7 4 2 1
3 6 7 4 2 2
3 5 7 4 2 3
3 4 7 4 2 4
8 rows selected.
You already had the iteration part in your query, you just needed the Group number which is achieved using a dense_rank on the result.
Similar Messages
-
Hello.
I need help creating a cursor and loop that will update a column based on data from another column. I keep getting the following errors. Any suggestions? These identifiers are valid tables in columns in my data base.
SQL> DECLARE
2
3 CURSOR c1 IS
4 SELECT SectionID, Coursename, StudentID, FinalGrade from Registration, Section, Grade WHERE registration.sectionid = grade.sectionid and registrationid.studentid = grade.studentid;
5
6 v_SectionID number(10);
7 v_CourseName varchar(20);
8 v_StudentID number(10);
9 v_FinalGrade varchar2(5);
10
11 BEGIN
12
13 OPEN c1;
14
15 LOOP
16 FETCH c1
17 INTO v_SectionID, v_CourseName, v_StudentID, v_FinalGrade;
18 EXIT WHEN c1%NOTFOUND;
19
20 update grade
21
22 SET FinalGrade = translate(substr(v_CourseName,-1,1),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','AAAAAABBBBBCCCCCDDDDEEEEEE')
23
24 where Grade.StudentID = Registration.StudentID;
25
26 END LOOP;
27 CLOSE c1;
28 END;
29 /
SELECT SectionID, Coursename, StudentID, FinalGrade from Registration, Section, Grade WHERE registration.sectionid = grade.sectionid and registrationid.studentid = grade.studentid;
ERROR at line 4:
ORA-06550: line 4, column 140:
PL/SQL: ORA-00904: "REGISTRATIONID"."STUDENTID": invalid identifier
ORA-06550: line 4, column 3:
PL/SQL: SQL Statement ignored
ORA-06550: line 24, column 27:
PL/SQL: ORA-00904: "REGISTRATION"."STUDENTID": invalid identifier
ORA-06550: line 20, column 3:
PL/SQL: SQL Statement ignored863737 wrote:
I am taking a intro course online so I am trying to teach myself this. The most basic rule for designing and writing good Oracle code that will perform and will scale is to use SQL for what it is good at and using PL/SQL for what it is good at. And between the two, SQL is by far superior when it comes to crunching data in the database.
The simple maxim is Maximize SQL. Minimize PL/SQL.
What you want to do with that PL/SQL code can be done using SQL only. And since you are learning SQL and PL/SQL, it is very important that you learn the correct way to do this.
Have a look at Oracle® Database SQL Language Reference guide.
The update syntax supports:
UPDATE <dml_expression_clause>
Where this +<dml_expression_clause>+ is a SELECT statement (aka an in-line view) - that can contain joins.
Simple example. You join tables t1 and t2 to identify the rows in t1 to update. The +<dml_expression_clause>+ will define this join. The actual update part (using the SET clause) will update the relevant rows in t1.
This is also called an updatable view - though the +<dml_expression_clause>+ does not need to use an actual view.
Have a look at AskTom for a discussion on this. Also note that you can also create a view and define an "instead-of" trigger on the view - this particular feature enhances the ability to update DML expressions - but is not a prerequisite.
Note that there can be very significant performance degradation by NOT using an UPDATE on a +<dml_expression_clause>+ and instead coding that manually via PL/SQL.
So do yourself a favour and learn the CORRECT way to resolve the type of UPDATE problem you have. -
Hi,
can anybody suggest what kind of report and in what way I have to use if I want to write query using cursors within loops?
Thanks!
Karina.Hi,
I found the solution. I just rewrite all cursors within one SQL statement and it works.
Karina. -
How to create store procedure using cursor, and looping condition with exce
Hi,
I am new in pl/sql development , please help me for follwoing
1. I have select query by joining few tables which returns lets say 100 records.
2. I want to insert records into another table(lets say table name is tbl_sale).
3. If first record is inserted into tbl_sale,and for next record if value is same as first then update into tbl_sale else
insert new row
4. I want to achieve this using store procedure.
Please help me how to do looping,how to use cursor and all other necessary thing to achieve this.DECLARE
b NUMBER;
BEGIN
UPDATE tbl_sale
SET a = b
WHERE a = 1;
IF SQL%ROWCOUNT = 0
THEN
INSERT INTO tbl_sale
(a
VALUES (b
END IF;
END;note : handle exceptions where ever needed
Regards,
friend
Edited by: most wanted!!!! on Mar 18, 2013 12:06 AM -
Why use cursor and for loop?
Hi All
So in general why would we use a cursor and a for loop to do update in a stored procedure?
Why wouldnt we just use a single update statement ?
is there compelling reason for using a cursor and a for loop: I am reading some code from a co-worker that the business logic for the select (set need to be updated) is complex but the update logic is simple (just set a flag to (0 or 1 or 2 or 3 or 4).
But eventually the select come down to a key (row_id) so I re-write it using just a single sql statement.
The size of the main table is about 2.6 to 3million rows
Any thoughts on that??
The code below I just do a google for cursor for update example in case for something to play with
-Thanks for all your input
create table f (a number, b varchar2(10));
insert into f values (5,'five');
insert into f values (6,'six');
insert into f values (7,'seven');
insert into f values (8,'eight');
insert into f values (9,'nine');
commit;
create or replace procedure wco as
cursor c_f is
select a,b from f where length(b) = 5 for update;
v_a f.a%type;
v_b f.b%type;
begin
open c_f;
loop
fetch c_f into v_a, v_b;
exit when c_f%notfound;
update f set a=v_a*v_a where current of c_f;
end loop;
close c_f;
end;
exec wco;
select * from f;
drop table f;
drop procedure wco;
Joining multiple tables
create table numbers_en (
id_num number primary key,
txt_num varchar2(10)
insert into numbers_en values (1, 'one' );
insert into numbers_en values (2, 'two' );
insert into numbers_en values (3, 'three');
insert into numbers_en values (4, 'four' );
insert into numbers_en values (5, 'five' );
insert into numbers_en values (6, 'six' );
create table lang (
id_lang char(2) primary key,
txt_lang varchar2(10)
insert into lang values ('de', 'german');
insert into lang values ('fr', 'french');
insert into lang values ('it', 'italian');
create table translations (
id_num references numbers_en,
id_lang references lang,
txt_trans varchar2(10) not null
insert into translations values (1, 'de', 'eins' );
insert into translations values (1, 'fr', 'un' );
insert into translations values (2, 'it', 'duo' );
insert into translations values (3, 'de', 'drei' );
insert into translations values (3, 'it', 'tre' );
insert into translations values (4, 'it', 'quattro');
insert into translations values (6, 'de', 'sechs' );
insert into translations values (6, 'fr', 'six' );
declare
cursor cur is
select id_num,
txt_num,
id_lang,
txt_lang,
txt_trans
from numbers_en join translations using(id_num)
left join lang using(id_lang)
for update of translations.txt_trans;
rec cur%rowtype;
begin
for rec in cur loop
dbms_output.put (
to_char (rec.id_num , '999') || ' - ' ||
rpad (rec.txt_num , 10 ) || ' - ' ||
rpad(nvl(rec.txt_trans, ' '), 10 ) || ' - ' ||
rec.id_lang || ' - ' ||
rpad (rec.txt_lang , 10 )
if mod(rec.id_num,2) = 0 then
update translations set txt_trans = upper(txt_trans)
where current of cur;
dbms_output.put_line(' updated');
else
dbms_output.new_line;
end if;
end loop;
end;
/Edited by: xwo0owx on Apr 25, 2011 11:23 AMAdding my sixpence...
PL/SQL is not that different from a SQL perspective than any other SQL client language like Java or C# or C/C++. PL/SQL simply integrates the 2 languages a heck of a lot better and far more transparent than the others. But make no mistake in that PL/SQL is also a "client" language from a SQL perspective. The (internal) calls PL/SQL make to the SQL engine, are the same (driver) calls made to the SQL engine when using Java and C and the others.
So why a cursor and loops in PL/SQL? For the same reason you have cursors and loops in all these other SQL client languages. There are the occasion that you need to pull data from the SQL engine into the local language to perform some very funky and complex processing that is not possible using the SQL language.
The danger is using client cursor loop processing as the norm - always pulling rows into the client language and crunching it there. This is not very performant. And pretty much impossible to scale. Developers in this case views the SQL language as a mere I/O interface for reading and writing rows. As they would use the standard file I/O read() and write() interface calls.
Nothing could be further from the truth. SQL is a very advance and sophisticated data processing language. And it will always be faster than having to pull rows to a client language and process them there. However, SQL is not Turing complete. It is not the procedural type language that most other languages we use, are. For that reason there are things that we cannot do in SQL. And that should be the only reason for using the client language, like PL/SQL or the others, to perform row crunching using a client cursor loop. -
Help with if statement in cursor and for loop to get output
I have the following cursor and and want to use if else statement to get the output. The cursor is working fine. What i need help with is how to use and if else statement to only get the folderrsn that have not been updated in the last 30 days. If you look at the talbe below my select statement is showing folderrs 291631 was updated only 4 days ago and folderrsn 322160 was also updated 4 days ago.
I do not want these two to appear in my result set. So i need to use if else so that my result only shows all folderrsn that havenot been updated in the last 30 days.
Here is my cursor:
/*Cursor for Email procedure. It is working Shows userid and the string
You need to update these folders*/
DECLARE
a_user varchar2(200) := null;
v_assigneduser varchar2(20);
v_folderrsn varchar2(200);
v_emailaddress varchar2(60);
v_subject varchar2(200);
Cursor c IS
SELECT assigneduser, vu.emailaddress, f.folderrsn, trunc(f.indate) AS "IN DATE",
MAX (trunc(fpa.attemptdate)) AS "LAST UPDATE",
trunc(sysdate) - MAX (trunc(fpa.attemptdate)) AS "DAYS PAST"
--MAX (TRUNC (fpa.attemptdate)) - TRUNC (f.indate) AS "NUMBER OF DAYS"
FROM folder f, folderprocess fp, validuser vu, folderprocessattempt fpa
WHERE f.foldertype = 'HJ'
AND f.statuscode NOT IN (20, 40)
AND f.folderrsn = fp.folderrsn
AND fp.processrsn = fpa.processrsn
AND vu.userid = fp.assigneduser
AND vu.statuscode = 1
GROUP BY assigneduser, vu.emailaddress, f.folderrsn, f.indate
ORDER BY fp.assigneduser;
BEGIN
FOR c1 IN c LOOP
IF (c1.assigneduser = v_assigneduser) THEN
dbms_output.put_line(' ' || c1.folderrsn);
else
dbms_output.put(c1.assigneduser ||': ' || 'Overdue Folders:You need to update these folders: Folderrsn: '||c1.folderrsn);
END IF;
a_user := c1.assigneduser;
v_assigneduser := c1.assigneduser;
v_folderrsn := c1.folderrsn;
v_emailaddress := c1.emailaddress;
v_subject := 'Subject: Project for';
END LOOP;
END;
The reason I have included the folowing table is that I want you to see the output from the select statement. that way you can help me do the if statement in the above cursor so that the result will look like this:
emailaddress
Subject: 'Project for ' || V_email || 'not updated in the last 30 days'
v_folderrsn
v_folderrsn
etc
[email protected]......
Subject: 'Project for: ' Jim...'not updated in the last 30 days'
284087
292709
[email protected].....
Subject: 'Project for: ' Kim...'not updated in the last 30 days'
185083
190121
190132
190133
190159
190237
284109
286647
294631
322922
[email protected]....
Subject: 'Project for: Joe...'not updated in the last 30 days'
183332
183336
[email protected]......
Subject: 'Project for: Sam...'not updated in the last 30 days'
183876
183877
183879
183880
183881
183882
183883
183884
183886
183887
183888
This table is to shwo you the select statement output. I want to eliminnate the two days that that are less than 30 days since the last update in the last column.
Assigneduser....Email.........Folderrsn...........indate.............maxattemptdate...days past since last update
JIM......... jim@ aol.com.... 284087............. 9/28/2006.......10/5/2006...........690
JIM......... jim@ aol.com.... 292709............. 3/20/2007.......3/28/2007............516
KIM......... kim@ aol.com.... 185083............. 8/31/2004.......2/9/2006............. 928
KIM...........kim@ aol.com.... 190121............. 2/9/2006.........2/9/2006.............928
KIM...........kim@ aol.com.... 190132............. 2/9/2006.........2/9/2006.............928
KIM...........kim@ aol.com.... 190133............. 2/9/2006.........2/9/2006.............928
KIM...........kim@ aol.com.... 190159............. 2/13/2006.......2/14/2006............923
KIM...........kim@ aol.com.... 190237............. 2/23/2006.......2/23/2006............914
KIM...........kim@ aol.com.... 284109............. 9/28/2006.......9/28/2006............697
KIM...........kim@ aol.com.... 286647............. 11/7/2006.......12/5/2006............629
KIM...........kim@ aol.com.... 294631............. 4/2/2007.........3/4/2008.............174
KIM...........kim@ aol.com.... 322922............. 7/29/2008.......7/29/2008............27
JOE...........joe@ aol.com.... 183332............. 1/28/2004.......4/23/2004............1585
JOE...........joe@ aol.com.... 183336............. 1/28/2004.......3/9/2004.............1630
SAM...........sam@ aol.com....183876.............3/5/2004.........3/8/2004.............1631
SAM...........sam@ aol.com....183877.............3/5/2004.........3/8/2004.............1631
SAM...........sam@ aol.com....183879.............3/5/2004.........3/8/2004.............1631
SAM...........sam@ aol.com....183880.............3/5/2004.........3/8/2004.............1631
SAM...........sam@ aol.com....183881.............3/5/2004.........3/8/2004.............1631
SAM...........sam@ aol.com....183882.............3/5/2004.........3/8/2004.............1631
SAM...........sam@ aol.com....183883.............3/5/2004.........3/8/2004.............1631
SAM...........sam@ aol.com....183884.............3/5/2004.........3/8/2004............ 1631
SAM...........sam@ aol.com....183886.............3/5/2004.........3/8/2004............ 1631
SAM...........sam@ aol.com....183887.............3/5/2004.........3/8/2004............ 1631
SAM...........sam@ aol.com....183888.............3/5/2004.........3/8/2004............ 1631
PAT...........pat@ aol.com.....291630.............2/23/2007.......7/8/2008............ 48
PAT...........pat@ aol.com.....313990.............2/27/2008.......7/28/2008............28
NED...........ned@ aol.com.....190681.............4/4/2006........8/10/2006............746
NED...........ned@ aol.com......95467.............6/14/2006.......11/6/2006............658
NED...........ned@ aol.com......286688.............11/8/2006.......10/3/2007............327
NED...........ned@ aol.com.....291631.............2/23/2007.......8/21/2008............4
NED...........ned@ aol.com.....292111.............3/7/2007.........2/26/2008............181
NED...........ned@ aol.com.....292410.............3/15/2007.......7/22/2008............34
NED...........ned@ aol.com.....299410.............6/27/2007.......2/27/2008............180
NED...........ned@ aol.com.....303790.............9/19/2007.......9/19/2007............341
NED...........ned@ aol.com.....304268.............9/24/2007.......3/3/2008............ 175
NED...........ned@ aol.com.....308228.............12/6/2007.......12/6/2007............263
NED...........ned@ aol.com.....316689.............3/19/2008.......3/19/2008............159
NED...........ned@ aol.com.....316789.............3/20/2008.......3/20/2008............158
NED...........ned@ aol.com.....317528.............3/25/2008.......3/25/2008............153
NED...........ned@ aol.com.....321476.............6/4/2008.........6/17/2008............69
NED...........ned@ aol.com.....322160.............7/3/2008.........8/21/2008............4
MOE...........moe@ aol.com.....184169.............4/5/2004.......12/5/2006............629
[email protected]/27/2004.......3/8/2004............1631
How do I incorporate a if else statement in the above cursor so the two days less than 30 days since last update are not returned. I do not want to send email if the project have been updated within the last 30 days.
Edited by: user4653174 on Aug 25, 2008 2:40 PManalytical functions: http://download-west.oracle.com/docs/cd/B10501_01/server.920/a96540/functions2a.htm#81409
CASE
http://download.oracle.com/docs/cd/B10501_01/appdev.920/a96624/02_funds.htm#36899
http://download.oracle.com/docs/cd/B10501_01/appdev.920/a96624/04_struc.htm#5997
Incorporating either of these into your query should assist you in returning the desired results. -
The query below will return values in the form of
bu seq eligible
22 2345 Y
22 2345 N
22 1288 N
22 1458 Y
22 1458 N
22 1234 Y
22 1333 N
What I am trying to accomplish is to loop through the records returned.
for each seq if there is a 'N' in the eligible column return no record for that seq
eg seq 2345 has 'Y' and 'N' thus no record should be returned.
seq 1234 has only a 'Y' then return the record
seq 1333 has 'N' so return no record.
How would I accomplish this with a ref Cursor and pass the values to the front end application.
Procedure InvalidNOs(io_CURSOR OUT T_CURSOR)
IS
v_CURSOR T_CURSOR;
BEGIN
OPEN v_CURSOR FOR
' select bu, seq, eligible ' ||
' from (select bu, seq, po, tunit, tdollar,eligible,max(eligible) over () re ' ||
' from (select bu, seq, po, tunit, tdollar,eligible ' ||
' from ( ' ||
' select bu, seq, po, tunit, tdollar, eligible, sum(qty) qty, sum(price*qty) dollars ' ||
' from ' ||
' ( select /*+ use_nl(t,h,d,s) */ ' ||
' h.business_unit_id bu, h.edi_sequence_id seq, d.edi_det_sequ_id dseq, ' ||
' s.edi_size_sequ_id sseq, h.po_number po, h.total_unit tUnit, h.total_amount tDollar, ' ||
' s.quantity qty, s.unit_price price,' ||
' (select (case when count(*) = 0 then ''Y'' else ''N'' end) ' ||
' from sewn.NT_edii_po_det_error ' ||
' where edi_det_sequ_id = d.edi_det_sequ_id ' ||
' ) eligible ' ||
' from sewn.nt_edii_purchase_size s, sewn.nt_edii_purchase_det d, ' ||
' sewn.nt_edii_purchase_hdr h, sewn.nt_edii_param_temp t ' ||
' where h.business_unit_id = t.business_unit_id ' ||
' and h.edi_sequence_id = t.edi_sequence_id ' ||
' and h.business_unit_id = d.business_unit_id ' ||
' and h.edi_sequence_id = d.edi_sequence_id ' ||
' and d.business_unit_id = s.business_unit_id ' ||
' and d.edi_sequence_id = s.edi_sequence_id ' ||
' and d.edi_det_sequ_id = s.edi_det_sequ_id ' ||
' ) group by bu, seq, po, tunit, tdollar, eligible ' ||
' ) ' ||
' group by bu, seq, po, tunit, tdollar, eligible)) ';
io_CURSOR := v_CURSOR;
END InvalidNOs;One remark why you should not use the assignment between ref cursor
variables.
(I remembered I saw already such thing in your code).
Technically you can do it but it does not make sense and it can confuse your results.
In the opposite to usual variables, when your assignment copies value
from one variable to another, cursor variables are pointers to the memory.
Because of this when you assign one cursor variable to another you just
duplicate memory pointers. You don't copy result sets. What you do for
one pointer is that you do for another and vice versa. They are the same.
I think the below example is self-explained:
SQL> /* usual variables */
SQL> declare
2 a number;
3 b number;
4 begin
5 a := 1;
6 b := a;
7 a := a + 1;
8 dbms_output.put_line('a = ' || a);
9 dbms_output.put_line('b = ' || b);
10 end;
11 /
a = 2
b = 1
PL/SQL procedure successfully completed.
SQL> /* cursor variables */
SQL> declare
2 a sys_refcursor;
3 b sys_refcursor;
4 begin
5 open a for select empno from emp;
6 b := a;
7 close b;
8
9 /* next action is impossible - cursor already closed */
10 /* a and b are the same ! */
11 close a;
12 end;
13 /
declare
ERROR at line 1:
ORA-01001: invalid cursor
ORA-06512: at line 11
SQL> declare
2 a sys_refcursor;
3 b sys_refcursor;
4 vempno emp.empno%type;
5
6 begin
7 open a for select empno from emp;
8 b := a;
9
10 /* Fetch first row from a */
11 fetch a into vempno;
12 dbms_output.put_line(vempno);
13
14 /* Fetch from b gives us SECOND row, not first -
15 a and b are the SAME */
16
17 fetch b into vempno;
18 dbms_output.put_line(vempno);
19
20
21 end;
22 /
7369
7499
PL/SQL procedure successfully completed.Rgds.
Message was edited by:
dnikiforov -
How to add cursor and for loop
PROCEDURE "TEST" is
bala number;
ins1 number;
ins2 number;
BEGIN
select sum(bal) into bala from (select sum(acp.acp_totbal) bal,acp_instruid from cs_strmap_t map,cs_instru_strips strip,cs_acpos_bkp acp
where c_int_instruid=c_srm_prncplinsid
and c_srm_prncplinsid=acp_instruid
and acp_acntnum!='SG030001'
group by acp_instruid
union
select sum(acp.acp_totbal) bal,acp_instruid from cs_strmap_t map,cs_instru_strips strip,cs_acpos_bkp acp
where c_int_instruid=c_srm_prncplinsid
and acp_acntnum!='SG030001'
and acp_instruid=c_srm_prntinsid
group by acp_instruid)view1;
dbms_output.put_line(bala);
select acp_instruid into ins1 from cs_strmap_t map,cs_instru_strips strip,cs_acpos_bkp acp
where c_int_instruid=c_srm_prncplinsid
and c_srm_prncplinsid=acp_instruid
and acp_acntnum='SG030001';
dbms_output.put_line('principal'||ins1);
select acp_instruid into ins2 from cs_strmap_t map,cs_instru_strips strip,cs_acpos_bkp acp
where c_int_instruid=c_srm_prncplinsid
and acp_acntnum='SG030001'
and acp_instruid=c_srm_prntinsid;
dbms_output.put_line('parent'||ins2);
update cs_acpos_bkp
set acp_totbal=-bala
where acp_instruid=ins2
and acp_acntnum='SG030001';
END;
i have written this code,i need to use cursor and for loops to get more than one rows and update also.
if there are more than 1 rows in cs_strmap_t,then the procedure throws an error stating that it cannot take 2 rows.
Edited by: 850836 on Apr 7, 2011 11:43 PMPROCEDURE "TEST" is
bala number;
ins1 number;
ins2 number;
CURSOR cur_1 IS
select sum(bal) bala from (select sum(acp.acp_totbal) bal,acp_instruid from cs_strmap_t map,cs_instru_strips strip,cs_acpos_bkp acp
where c_int_instruid=c_srm_prncplinsid
and c_srm_prncplinsid=acp_instruid
and acp_acntnum='SG030001'
group by acp_instruid
union
select sum(acp.acp_totbal) bal,acp_instruid from cs_strmap_t map,cs_instru_strips strip,cs_acpos_bkp acp
where c_int_instruid=c_srm_prncplinsid
and acp_acntnum='SG030001'
and acp_instruid=c_srm_prntinsid
group by acp_instruid)view1;
BEGIN
select acp_instruid into ins1 from cs_strmap_t map,cs_instru_strips strip,cs_acpos_bkp acp
where c_int_instruid=c_srm_prncplinsid
and c_srm_prncplinsid=acp_instruid
and acp_acntnum='SG030001';
dbms_output.put_line('principal'||ins1);
select acp_instruid into ins2 from cs_strmap_t map,cs_instru_strips strip,cs_acpos_bkp acp
where c_int_instruid=c_srm_prncplinsid
and acp_acntnum='SG030001'
and acp_instruid=c_srm_prntinsid;
dbms_output.put_line('parent'||ins2);
for var_for in cur_1
loop
update cs_acpos_bkp
set acp_totbal=var_for.bala
where acp_instruid=ins2
and acp_acntnum='SG030001'
and abs(acp_totbal)>abs(bala);
dbms_output.put_line(bala);
end loop;
END;
i wrote the following procedure,but the balance is not getting updated.
Getting this errors when there are more than 1 row in cs_strmap_t table
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: line 22
ORA-06512: at line 2 -
How to optimize the select query that is executed in a cursor for loop?
Hi Friends,
I have executed the code below and clocked the times for every line of the code using DBMS_PROFILER.
CREATE OR REPLACE PROCEDURE TEST
AS
p_file_id NUMBER := 151;
v_shipper_ind ah_item.shipper_ind%TYPE;
v_sales_reserve_ind ah_item.special_sales_reserve_ind%TYPE;
v_location_indicator ah_item.exe_location_ind%TYPE;
CURSOR activity_c
IS
SELECT *
FROM ah_activity_internal
WHERE status_id = 30
AND file_id = p_file_id;
BEGIN
DBMS_PROFILER.start_profiler ('TEST');
FOR rec IN activity_c
LOOP
SELECT DISTINCT shipper_ind, special_sales_reserve_ind, exe_location_ind
INTO v_shipper_ind, v_sales_reserve_ind, v_location_indicator
FROM ah_item --464000 rows in this table
WHERE item_id_edw IN (
SELECT item_id_edw
FROM ah_item_xref --700000 rows in this table
WHERE item_code_cust = rec.item_code_cust
AND facility_num IN (
SELECT facility_code
FROM ah_chain_div_facility --17 rows in this table
WHERE chain_id = ah_internal_data_pkg.get_chain_id (p_file_id)
AND div_id = (SELECT div_id
FROM ah_div --8 rows in this table
WHERE division = rec.division)));
END LOOP;
DBMS_PROFILER.stop_profiler;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
NULL;
WHEN TOO_MANY_ROWS
THEN
NULL;
END TEST;The SELECT query inside the cursor FOR LOOP took 773 seconds.
I have tried using BULK COLLECT instead of cursor for loop but it did not help.
When I took out the select query separately and executed with a sample value then it gave the results in a flash of second.
All the tables have primary key indexes.
Any ideas what can be done to make this code perform better?
Thanks,
Raj.As suggested I'd try merging the queries into a single SQL. You could also rewrite your IN clauses as JOINs and see if that helps, e.g.
SELECT DISTINCT ai.shipper_ind, ai.special_sales_reserve_ind, ai.exe_location_ind
INTO v_shipper_ind, v_sales_reserve_ind, v_location_indicator
FROM ah_item ai, ah_item_xref aix, ah_chain_div_facility acdf, ah_div ad
WHERE ai.item_id_edw = aix.item_id_edw
AND aix.item_code_cust = rec.item_code_cust
AND aix.facility_num = acdf.facility_code
AND acdf.chain_id = ah_internal_data_pkg.get_chain_id (p_file_id)
AND acdf.div_id = ad.div_id
AND ad.division = rec.division;ALSO: You are calling ah_internal_data_pkg.get_chain_id (p_file_id) every time. Why not do it outside the loop and just use a variable in the inner query? That will prevent context switching and improve speed.
Edited by: Dave Hemming on Dec 3, 2008 9:34 AM -
Replace the following open/fetch/close statements with a cursor FOR loop
Hi anyone could you please help me,
I would like to replace the following open/fetch/close statements with a cursor FOR loop.
Codes are:
CREATE OR REPLACE PROCEDURE COMOES.orchid_shipment_interface IS
-- get the com shipment header records
CURSOR c_com_shphdr ( p_dwn_end_dt DATE ) IS
SELECT custno client_id
, plheadno plheadno
, DECODE(carr_no,'FEDX',lading_no,'UPS',lading_no,carrier_pro_no) tracking_no
, carr_no||'/'||carr_method carrier_id
, plantid plant_id
, carr_no
, lading_no
, del_custaddr ship_to_id
, ol_type cfm_order_type
, del_custno
, shipterm freight_terms
, del_custattn attn_line
, custaddr
FROM com_plhead@com_pricing.world
WHERE status = '9'
AND (mod_dat) > p_dwn_end_dt;
-- get the com shipment address records
CURSOR c_com_shpadr (p_custaddr VARCHAR2) IS
SELECT name1 addr_name
, street1 addr_line1
, street2 addr_line2
, city city
, state state_cd
, zip zip
, country country_cd
, phone work_phone
, email email1
FROM com_address@com_pricing.world
WHERE addr_id = p_custaddr;
-- get the com shipment detail records
CURSOR c_com_shpdtl ( p_plheadno NUMBER) IS
SELECT pll.plheadno pllheadno
, pll.pllineno ord_line_no
, pll.ol_no erp_line_no
, pll.ol_segno
, pll.fg_id sku
, pll.qty_shipped ship_qty
, pll.ordno erp_ord_no
FROM com_plline@com_pricing.world pll
WHERE pll.plheadno = p_plheadno
AND NOT EXISTS (SELECT '1'
FROM com_pkg_int_interface@com_pricing.world cpi
WHERE pll.ordno = cpi.ordno
AND pll.ol_no = cpi.ol_no);
-- type declaration
-- type declaration of com table.
TYPE t_com_shphdr IS TABLE OF c_com_shphdr%ROWTYPE INDEX BY BINARY_INTEGER;
TYPE t_orchid_shphdr IS TABLE OF orchid_shipment_hdr_intf%ROWTYPE INDEX BY BINARY_INTEGER;
TYPE t_com_shpadr IS TABLE OF c_com_shpadr%ROWTYPE INDEX BY BINARY_INTEGER;
TYPE t_orchid_shpadr IS TABLE OF orchid_shipment_address_intf%ROWTYPE INDEX BY BINARY_INTEGER;
TYPE t_com_shpdtl IS TABLE OF c_com_shpdtl%ROWTYPE INDEX BY BINARY_INTEGER;
TYPE t_orchid_shpdtl IS TABLE OF orchid_shipment_dtl_intf%ROWTYPE INDEX BY BINARY_INTEGER;
lv_company_code com_customer.business_unit%TYPE;
lv_erp_ord_no com_plline.ordno%TYPE;
lv_actual_ship_date com_plline.confirm_date%TYPE;
lv_po_no com_oline.po_no%TYPE;
lv_ord_date com_oline.entrydate%TYPE;
lv_hdr_batch_ctrl_no download_batch_info.batch_ctrl_no%TYPE;
lv_adr_batch_ctrl_no download_batch_info.batch_ctrl_no%TYPE;
lv_dtl_batch_ctrl_no download_batch_info.batch_ctrl_no%TYPE;
lv_sku_desc com_salesitem.title%TYPE;
lv_ord_qty com_oldelseg.qty%TYPE;
lr_com_shphdr t_com_shphdr;
lr_orchid_shphdr t_orchid_shphdr;
lr_com_shpadr t_com_shpadr;
lr_orchid_shpadr t_orchid_shpadr;
lr_com_shpdtl t_com_shpdtl;
lr_orchid_shpdtl t_orchid_shpdtl;
-- variable declaration
ln_shphdr_seq NUMBER(10):= 0;
ln_shpadr_seg NUMBER(10):= 0;
ln_shpdtl_seq NUMBER(10):= 0;
cnt NUMBER(10):= 0;
cnt1 NUMBER(10):= 0;
ld_hdr_dwn_end_dt download_batch_info.download_end_tstamp%TYPE;
lc_hdr_dwn_status download_batch_info.dwn_status%TYPE;
ld_hdr_download_end_tstamp DATE;
ln_hdr_running_seq NUMBER(10) := 0;
ld_adr_dwn_end_dt download_batch_info.download_end_tstamp%TYPE;
lc_adr_dwn_status download_batch_info.dwn_status%TYPE;
ld_adr_download_end_tstamp DATE;
ln_adr_running_seg NUMBER(10) := 0;
ld_dtl_dwn_end_dt download_batch_info.download_end_tstamp%TYPE;
lc_dtl_dwn_status download_batch_info.dwn_status%TYPE;
ld_dtl_download_end_tstamp DATE;
ln_dtl_running_seq NUMBER(10) := 0;
BEGIN
-- get the batch control number details from batch information table for shipment header
BEGIN
SELECT batch_ctrl_no
, NVL(download_end_tstamp,TO_DATE('01/01/1980','MM/DD/YYYY'))
, dwn_status
INTO lv_hdr_batch_ctrl_no
, ld_hdr_dwn_end_dt
, lc_hdr_dwn_status
FROM comoes.download_batch_info
WHERE download_id = 'ORCHID_SHIPMENT_HDR_INTF';
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE (' No Data Found for ORCHID_SHIPMENT_HDR_INTF in Download Batch Info table...!!!');
RAISE;
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE (' Too Many Rows found for ORCHID_SHIPMENT_HDR_INTF in Download Batch Info table...!!!');
RAISE;
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE (' Following error occured while getting batch control number for ORCHID_SHIPMENT_HDR_INTF in Download Batch Info table...!!!'||SQLERRM);
RAISE;
END;
-- get the batch control number details from batch information table for shipment address
BEGIN
SELECT batch_ctrl_no
, NVL(download_end_tstamp,TO_DATE('01/01/1980','MM/DD/YYYY'))
, dwn_status
INTO lv_adr_batch_ctrl_no
, ld_adr_dwn_end_dt
, lc_adr_dwn_status
FROM comoes.download_batch_info
WHERE download_id = 'ORCHID_SHIPMENT_ADDRESS_INTF';
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE (' No Data Found for ORCHID_SHIPMENT_ADDRESS_INTF in Download Batch Info table...!!!');
RAISE;
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE (' Too Many Rows found for ORCHID_SHIPMENT_ADDRESS_INTF in Download Batch Info table...!!!');
RAISE;
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE (' Following error occured while getting batch control number for ORCHID_SHIPMENT_ADDRESS_INTF in Download Batch Info table...!!!'||SQLERRM);
RAISE;
END;
-- get the batch control number details from batch information table for shipment details
BEGIN
SELECT batch_ctrl_no
, NVL(download_end_tstamp,TO_DATE('01/01/1980','MM/DD/YYYY'))
, dwn_status
INTO lv_dtl_batch_ctrl_no
, ld_dtl_dwn_end_dt
, lc_dtl_dwn_status
FROM download_batch_info
WHERE download_id = 'ORCHID_SHIPMENT_DTL_INTF';
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE (' No Data Found for ORCHID_SHIPMENT_DTL_INTF in Download Batch Info table...!!!');
RAISE;
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE (' Too Many Rows found for ORCHID_SHIPMENT_DTL_INTF in Download Batch Info table...!!!');
RAISE;
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE (' Following error occured while getting batch control number for ORCHID_SHIPMENT_DTL_INTF in Download Batch Info table...!!!'||SQLERRM);
RAISE;
END;
-- if previous run is not sucess then do nothing and return.
OPEN c_com_shphdr ( ld_hdr_dwn_end_dt ) ;
LOOP
-- delete the collection for every cycle
lr_com_shphdr.DELETE;
lr_orchid_shphdr.DELETE;
lr_com_shpadr.DELETE;
lr_orchid_shpadr.DELETE;
lr_com_shpdtl.DELETE;
lr_orchid_shpdtl.DELETE;
-- fetch the order header records to collection
FETCH c_com_shphdr BULK COLLECT INTO lr_com_shphdr LIMIT 500;
-- where there is no record in the collection the exit from the loop
EXIT WHEN lr_com_shphdr.COUNT = 0;
-- build your logic there to populate the data into order header collection.
FOR i IN 1..lr_com_shphdr.COUNT
LOOP
-- accumulate header running sequence number
ln_hdr_running_seq := ln_hdr_running_seq + 1;
ln_shphdr_seq := ln_hdr_running_seq;
-- Get the business unit for the customer from com_customer
BEGIN
SELECT business_unit
INTO lv_company_code
FROM com_customer@com_pricing.world
WHERE custno = lr_com_shphdr(i).del_custno;
EXCEPTION
WHEN OTHERS THEN
lv_company_code := NULL;
END;
-- Get the ordno, confirm_date from COM_PLLINE
BEGIN
SELECT ordno
, confirm_date
INTO lv_erp_ord_no
, lv_actual_ship_date
FROM com_plline@com_pricing.world cpl
WHERE cpl.plheadno = lr_com_shphdr(i).plheadno
AND ROWNUM = 1;
EXCEPTION
WHEN OTHERS THEN
lv_erp_ord_no := NULL;
lv_actual_ship_date := NULL;
END;
-- Get the po_no, Entry_date from COM_OLINE
BEGIN
SELECT po_no
, entrydate
INTO lv_po_no
, lv_ord_date
FROM com_oline@com_pricing.world col
WHERE col.ordno = lv_erp_ord_no
AND ROWNUM = 1;
EXCEPTION
WHEN OTHERS THEN
lv_po_no := NULL;
lv_ord_date := NULL;
END;
-- To assign the Bol Number from Lading Number
IF lr_com_shphdr(i).carr_no NOT IN ('FEDX','UPS') THEN
lr_orchid_shphdr(i).bol_no := lr_com_shphdr(i).lading_no;
ELSE
lr_orchid_shphdr(i).bol_no := NULL;
END IF;
-- For each order header get the Shipment Delivery Adderss
OPEN c_com_shpadr ( lr_com_shphdr(i).custaddr);
FETCH c_com_shpadr BULK COLLECT INTO lr_com_shpadr;
-- where there is no record in the collection the exit from the loop
EXIT WHEN lr_com_shpadr.COUNT = 0;
-- biuld your logic here to populate the del address collection.
FOR j IN 1..lr_com_shpadr.COUNT
LOOP
-- accumulate the loop count into temp variable, so that will through tell each set of order header.
cnt := cnt + 1;
-- accumolate the header running sequence number.
ln_adr_running_seg := ln_adr_running_seg + 1;
ln_shpadr_seg := ln_adr_running_seg;
-- move the order address data into collection.
lr_orchid_shpadr(cnt).client_id := lr_com_shphdr(i).del_custno;
lr_orchid_shpadr(cnt).ord_no := lr_com_shphdr(i).plheadno;
lr_orchid_shpadr(cnt).tracking_no := lr_com_shphdr(i).tracking_no;
lr_orchid_shpadr(cnt).addr_name := lr_com_shpadr(j).addr_name;
lr_orchid_shpadr(cnt).attn_line := lr_com_shphdr(i).attn_line;
lr_orchid_shpadr(cnt).addr_line1 := lr_com_shpadr(j).addr_line1;
lr_orchid_shpadr(cnt).addr_line2 := lr_com_shpadr(j).addr_line2;
lr_orchid_shpadr(cnt).addr_line3 := NULL;
lr_orchid_shpadr(cnt).addr_line4 := NULL;
lr_orchid_shpadr(cnt).addr_line5 := NULL;
lr_orchid_shpadr(cnt).city := lr_com_shpadr(j).city;
lr_orchid_shpadr(cnt).state_cd := lr_com_shpadr(j).state_cd;
lr_orchid_shpadr(cnt).zip := lr_com_shpadr(j).zip;
lr_orchid_shpadr(cnt).zip_ext := NULL;
lr_orchid_shpadr(cnt).country_cd := lr_com_shpadr(j).country_cd;
lr_orchid_shpadr(cnt).tax_geo_cd := NULL;
lr_orchid_shpadr(cnt).work_phone := lr_com_shpadr(j).work_phone;
lr_orchid_shpadr(cnt).email1 := lr_com_shpadr(j).email1;
lr_orchid_shpadr(cnt).cre_dat := SYSDATE;
lr_orchid_shpadr(cnt).cre_usr := USER;
lr_orchid_shpadr(cnt).batch_ctrl_no := lv_adr_batch_ctrl_no;
END LOOP;
CLOSE c_com_shpadr;
-- For each order header get the order detail/delivery segment data
OPEN c_com_shpdtl ( lr_com_shphdr(i).plheadno );
FETCH c_com_shpdtl BULK COLLECT INTO lr_com_shpdtl;
-- where there is no record in the collection the exit from the loop
EXIT WHEN lr_com_shpdtl.COUNT = 0;
-- build your logic here to populate the order detail collection
FOR k IN 1..lr_com_shpdtl.COUNT
LOOP
-- accumulate the loop count into a temp variable, so that will through till each set of Order Header.
cnt1 := cnt1 + 1;
-- accumulate header running sequence number
ln_dtl_running_seq := ln_dtl_running_seq + 1;
ln_shpdtl_seq := ln_dtl_running_seq;
-- Get Quantity for the delvery from delevery segment table.
BEGIN
SELECT NVL(Qty,0)
INTO lv_ord_qty
FROM com_oldelseg@com_pricing.world cds
WHERE cds.ordno = lr_com_shpdtl(k).erp_ord_no
AND cds.ol_no = lr_com_shpdtl(k).erp_line_no
AND cds.ol_segno = lr_com_shpdtl(k).ol_segno;
EXCEPTION
WHEN OTHERS THEN
lv_ord_qty := NULL;
END;
-- Get Title for the salesitem from the salesitem table.
BEGIN
SELECT Title
INTO lv_sku_desc
FROM com_salesitem@com_pricing.world cs
WHERE cs.fg_id = lr_com_shpdtl(k).sku;
EXCEPTION
WHEN OTHERS THEN
lv_sku_desc := NULL;
END;
-- move the Order detail data into collection
lr_orchid_shpdtl(cnt1).client_id := lr_com_shphdr(i).client_id;
lr_orchid_shpdtl(cnt1).ord_no := lr_com_shphdr(i).plheadno;
lr_orchid_shpdtl(cnt1).ord_line_no := lr_com_shpdtl(k).ord_line_no;
lr_orchid_shpdtl(cnt1).erp_line_no := lr_com_shpdtl(k).erp_line_no;
lr_orchid_shpdtl(cnt1).sku := lr_com_shpdtl(k).sku;
lr_orchid_shpdtl(cnt1).tracking_no := lr_com_shphdr(i).tracking_no;
lr_orchid_shpdtl(cnt1).container_no := NULL;
lr_orchid_shpdtl(cnt1).ord_qty := lv_ord_qty;
lr_orchid_shpdtl(cnt1).ship_qty := lr_com_shpdtl(k).ship_qty;
lr_orchid_shpdtl(cnt1).price_point := NULL;
lr_orchid_shpdtl(cnt1).pick_invoice_no := NULL;
lr_orchid_shpdtl(cnt1).cancel_qty := NULL;
lr_orchid_shpdtl(cnt1).bldg_id := NULL; --lr_com_shpdtl(k).bldg_id;
lr_orchid_shpdtl(cnt1).sku_company := NULL; --lr_com_shpdtl(k).sku_company;
lr_orchid_shpdtl(cnt1).sku_desc := lv_sku_desc;
lr_orchid_shpdtl(cnt1).icc_cd1 := NULL; --lr_com_shpdtl(k).icc_cd1;
lr_orchid_shpdtl(cnt1).erp_ord_no := lr_com_shpdtl(k).erp_ord_no;
lr_orchid_shpdtl(cnt1).cre_dat := SYSDATE;
lr_orchid_shpdtl(cnt1).cre_usr := USER;
lr_orchid_shpdtl(cnt1).batch_ctrl_no := lv_dtl_batch_ctrl_no;
END LOOP;
CLOSE c_com_shpdtl;
-- build the logic to populate Order Header
lr_orchid_shphdr(i).client_id := lr_com_shphdr(i).client_id;
lr_orchid_shphdr(i).ord_no := lr_com_shphdr(i).plheadno;
lr_orchid_shphdr(i).tracking_no := lr_com_shphdr(i).tracking_no;
lr_orchid_shphdr(i).container_no := NULL; -- container number is not maintained in COM
lr_orchid_shphdr(i).carrier_id := lr_com_shphdr(i).carrier_id;
lr_orchid_shphdr(i).plant_id := lr_com_shphdr(i).plant_id;
lr_orchid_shphdr(i).erp_ord_no := lv_erp_ord_no;
lr_orchid_shphdr(i).erp_ord_no2 := NULL;
lr_orchid_shphdr(i).po_no := lv_po_no;
lr_orchid_shphdr(i).ship_to_id := lr_com_shphdr(i).ship_to_id;
lr_orchid_shphdr(i).ship_to_addr_id := lr_com_shphdr(i).custaddr;
lr_orchid_shphdr(i).scac := NULL; --lr_com_shphdr(i).scac;
lr_orchid_shphdr(i).actual_ship_date := lv_actual_ship_date;
lr_orchid_shphdr(i).cfm_order_type := lr_com_shphdr(i).cfm_order_type;
lr_orchid_shphdr(i).company_code := lv_company_code;
lr_orchid_shphdr(i).no_of_order_lines := NULL; --lr_com_shphdr(i).no_of_order_lines;
lr_orchid_shphdr(i).pick_invoice_no := NULL;
lr_orchid_shphdr(i).ord_date := lv_ord_date;
lr_orchid_shphdr(i).orig_tender_date := NULL;
lr_orchid_shphdr(i).orig_delv_date := NULL;
lr_orchid_shphdr(i).delivery_flag := NULL;
lr_orchid_shphdr(i).delv_date_from := NULL;
lr_orchid_shphdr(i).delv_date_to := NULL;
lr_orchid_shphdr(i).orig_carr_cd := NULL;
lr_orchid_shphdr(i).routing_comment := NULL;
lr_orchid_shphdr(i).segment_type := NULL;
lr_orchid_shphdr(i).back_order_flag := NULL;
lr_orchid_shphdr(i).addr_override_flag := NULL;
lr_orchid_shphdr(i).fmx_assigned_carr := NULL;
lr_orchid_shphdr(i).fmx_assigned_ship_date := NULL;
lr_orchid_shphdr(i).fmx_assigned_delv_date := NULL;
lr_orchid_shphdr(i).freight_terms := lr_com_shphdr(i).freight_terms;
lr_orchid_shphdr(i).fmx_load_id := NULL;
lr_orchid_shphdr(i).asn_type := NULL;
lr_orchid_shphdr(i).icc_cd1 := NULL; --lr_com_shphdr(i).icc_cd1;
lr_orchid_shphdr(i).trans_type := NULL;
lr_orchid_shphdr(i).ref_no1 := NULL;
lr_orchid_shphdr(i).ref_no2 := NULL;
lr_orchid_shphdr(i).ref_no3 := NULL;
lr_orchid_shphdr(i).ref_no4 := NULL;
lr_orchid_shphdr(i).cre_dat := SYSDATE;
lr_orchid_shphdr(i).cre_usr := USER;
lr_orchid_shphdr(i).batch_ctrl_no := lv_hdr_batch_ctrl_no;
-- logic to get total boxes and weight.
BEGIN
SELECT SUM(no_cartons), SUM(weight)
INTO lr_orchid_shphdr(i).total_boxes
, lr_orchid_shphdr(i).weight
FROM com_plline@com_pricing.world pll
WHERE pll.plheadno = lr_com_shphdr(i).plheadno;
EXCEPTION
WHEN OTHERS THEN
lr_orchid_shphdr(i).total_boxes := NULL;
lr_orchid_shphdr(i).weight := NULL;
END;
END LOOP;
-- initialize the variables for next loop cycle.
cnt := 0;
cnt1 := 0;
-- populate the shipment header interface table.
FOR x IN 1..lr_orchid_shphdr.COUNT
LOOP
ld_hdr_download_end_tstamp := lr_orchid_shphdr(x).cre_dat;
INSERT INTO orchid_shipment_hdr_intf
(record_qualifier
,client_id
,ord_no
,tracking_no
,container_no
,bol_no
,carrier_id
,plant_id
,erp_ord_no
,erp_ord_no2
,po_no
,ship_to_id
,ship_to_addr_id
,scac
,actual_ship_date
,cfm_order_type
,company_code
,no_of_order_lines
,pick_invoice_no
,total_boxes
,weight
,ord_date
,orig_tender_date
,orig_delv_date
,delivery_flag
,delv_date_from
,delv_date_to
,orig_carr_cd
,routing_comment
,segment_type
,back_order_flag
,addr_override_flag
,fmx_assigned_carr
,fmx_assigned_ship_date
,fmx_assigned_delv_date
,freight_terms
,fmx_load_id
,asn_type
,upl_status
,icc_cd1
,trans_type
,ref_no1
,ref_no2
,ref_no3
,ref_no4
,cre_dat
,cre_usr
,batch_ctrl_no)
VALUES
( 10
,lr_orchid_shphdr(x).client_id
,lr_orchid_shphdr(x).ord_no
,lr_orchid_shphdr(x).tracking_no
,lr_orchid_shphdr(x).container_no
,lr_orchid_shphdr(x).bol_no
,lr_orchid_shphdr(x).carrier_id
,lr_orchid_shphdr(x).plant_id
,lr_orchid_shphdr(x).erp_ord_no
,lr_orchid_shphdr(x).erp_ord_no2
,lr_orchid_shphdr(x).po_no
,lr_orchid_shphdr(x).ship_to_id
,lr_orchid_shphdr(x).ship_to_addr_id
,lr_orchid_shphdr(x).scac
,lr_orchid_shphdr(x).actual_ship_date
,lr_orchid_shphdr(x).cfm_order_type
,lr_orchid_shphdr(x).company_code
,lr_orchid_shphdr(x).no_of_order_lines
,lr_orchid_shphdr(x).pick_invoice_no
,lr_orchid_shphdr(x).total_boxes
,lr_orchid_shphdr(x).weight
,lr_orchid_shphdr(x).ord_date
,lr_orchid_shphdr(x).orig_tender_date
,lr_orchid_shphdr(x).orig_delv_date
,lr_orchid_shphdr(x).delivery_flag
,lr_orchid_shphdr(x).delv_date_from
,lr_orchid_shphdr(x).delv_date_to
,lr_orchid_shphdr(x).orig_carr_cd
,lr_orchid_shphdr(x).routing_comment
,lr_orchid_shphdr(x).segment_type
,lr_orchid_shphdr(x).back_order_flag
,lr_orchid_shphdr(x).addr_override_flag
,lr_orchid_shphdr(x).fmx_assigned_carr
,lr_orchid_shphdr(x).fmx_assigned_ship_date
,lr_orchid_shphdr(x).fmx_assigned_delv_date
,lr_orchid_shphdr(x).freight_terms
,lr_orchid_shphdr(x).fmx_load_id
,lr_orchid_shphdr(x).asn_type
,00
,lr_orchid_shphdr(x).icc_cd1
,lr_orchid_shphdr(x).trans_type
,lr_orchid_shphdr(x).ref_no1
,lr_orchid_shphdr(x).ref_no2
,lr_orchid_shphdr(x).ref_no3
,lr_orchid_shphdr(x).ref_no4
,lr_orchid_shphdr(x).cre_dat
,lr_orchid_shphdr(x).cre_usr
,lr_orchid_shphdr(x).batch_ctrl_no);
END LOOP;
-- populate the shipment address interface table.
FOR y IN 1..lr_orchid_shpadr.COUNT
LOOP
ld_adr_download_end_tstamp := lr_orchid_shpadr(y).cre_dat;
INSERT INTO orchid_shipment_address_intf
( record_qualifier
, client_id
, ord_no
, tracking_no
, addr_name
, attn_line
, addr_line1
, addr_line2
, addr_line3
, addr_line4
, addr_line5
, city
, state_cd
, zip
, zip_ext
, country_cd
, tax_geo_cd
, work_phone
, email1
, cre_dat
, cre_usr
, batch_ctrl_no)
VALUES ( 14
, lr_orchid_shpadr(y).client_id
, lr_orchid_shpadr(y).ord_no
, lr_orchid_shpadr(y).tracking_no
, lr_orchid_shpadr(y).addr_name
, lr_orchid_shpadr(y).attn_line
, lr_orchid_shpadr(y).addr_line1
, lr_orchid_shpadr(y).addr_line2
, lr_orchid_shpadr(y).addr_line3
, lr_orchid_shpadr(y).addr_line4
, lr_orchid_shpadr(y).addr_line5
, lr_orchid_shpadr(y).city
, lr_orchid_shpadr(y).state_cd
, lr_orchid_shpadr(y).zip
, lr_orchid_shpadr(y).zip_ext
, lr_orchid_shpadr(y).country_cd
, lr_orchid_shpadr(y).tax_geo_cd
, lr_orchid_shpadr(y).work_phone
, lr_orchid_shpadr(y).email1
, lr_orchid_shpadr(y).cre_dat
, lr_orchid_shpadr(y).cre_usr
, lr_orchid_shpadr(y).batch_ctrl_no);
END LOOP;
-- populate the shipment detail interface table.
FOR z IN 1..lr_orchid_shpdtl.COUNT
LOOP
ld_dtl_download_end_tstamp := lr_orchid_shpdtl(z).cre_dat;
INSERT INTO orchid_shipment_dtl_intf
( record_qualifier
, client_id
, ord_no
, ord_line_no
, erp_line_no
, sku
, tracking_no
, container_no
, ord_qty
, ship_qty
, price_point
, pick_invoice_no
, cancel_qty
, bldg_id
, sku_company
, sku_desc
, icc_cd1
, erp_ord_no
, cre_dat
, cre_usr
, batch_ctrl_no)
VALUES ( 20
, lr_orchid_shpdtl(z).client_id
, lr_orchid_shpdtl(z).ord_no
, lr_orchid_shpdtl(z).ord_line_no
, lr_orchid_shpdtl(z).erp_line_no
, lr_orchid_shpdtl(z).sku
, lr_orchid_shpdtl(z).tracking_no
, lr_orchid_shpdtl(z).container_no
, lr_orchid_shpdtl(z).ord_qty
, lr_orchid_shpdtl(z).ship_qty
, lr_orchid_shpdtl(z).price_point
, lr_orchid_shpdtl(z).pick_invoice_no
, lr_orchid_shpdtl(z).cancel_qty
, lr_orchid_shpdtl(z).bldg_id
, lr_orchid_shpdtl(z).sku_company
, lr_orchid_shpdtl(z).sku_desc
, lr_orchid_shpdtl(z).icc_cd1
, lr_orchid_shpdtl(z).erp_ord_no
, lr_orchid_shpdtl(z).cre_dat
, lr_orchid_shpdtl(z).cre_usr
, lr_orchid_shpdtl(z).batch_ctrl_no);
END LOOP;
COMMIT;
END LOOP;
CLOSE c_com_shphdr;
-- set the status to success
UPDATE comoes.download_batch_info
SET batch_ctrl_no = orchid_plhead_btch_ctrl_seq.NEXTVAL
, dwn_status = '90'
, download_end_tstamp = NVL(ld_hdr_download_end_tstamp,SYSDATE)
WHERE download_id = 'ORCHID_SHIPMENT_HDR_INTF'
AND batch_ctrl_no = lv_hdr_batch_ctrl_no;
UPDATE comoes.download_batch_info
SET batch_ctrl_no = orchid_address_btch_ctrl_seq.NEXTVAL
, dwn_status = '90'
, download_end_tstamp = NVL(ld_hdr_download_end_tstamp,SYSDATE)
WHERE download_id = 'ORCHID_SHIPMENT_ADDRESS_INTF'
AND batch_ctrl_no = lv_adr_batch_ctrl_no;
UPDATE comoes.download_batch_info
SET batch_ctrl_no = orchid_plline_btch_ctrl_seq.NEXTVAL
, dwn_status = '90'
, download_end_tstamp = NVL(ld_dtl_download_end_tstamp,SYSDATE)
WHERE download_id = 'ORCHID_SHIPMENT_DTL_INTF'
AND batch_ctrl_no = lv_dtl_batch_ctrl_no;
-- Update the download status to success in the interface table.
-- Shipment Header
COMMIT;
EXCEPTION
WHEN OTHERS THEN
-- load is not sucess then set the status to fail
UPDATE comoes.download_batch_info
SET dwn_status = '99'
WHERE download_id = 'ORCHID_SHIPMENT_HDR_INTF'
AND batch_ctrl_no = lv_hdr_batch_ctrl_no;
UPDATE comoes.download_batch_info
SET dwn_status = '99'
WHERE download_id = 'ORCHID_SHIPMENT_ADDRESS_INTF'
AND batch_ctrl_no = lv_adr_batch_ctrl_no;
UPDATE comoes.download_batch_info
SET dwn_status = '99'
WHERE download_id = 'ORCHID_SHIPMENT_DTL_INTF'
AND batch_ctrl_no = lv_dtl_batch_ctrl_no;
COMMIT;
DBMS_OUTPUT.PUT_LINE('Following error occured while executing ORCHID_SHIPMENT_INTF procedure...!!!'||SQLERRM);
RAISE;
END orchid_shipment_interface;Edited by: BluShadow on 03-Aug-2011 13:28
added {noformat}{noformat} tags. Please read {message:id=9360002} to learn to do this yourself. &nbPlease read the Forum FAQ on how to ask a question, particularly how to format code
SQL and PL/SQL FAQ
SQL and PL/SQL FAQ
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE (' Following error occured while getting batch control number for ORCHID_SHIPMENT_HDR_INTF in Download Batch Info table...!!!'||SQLERRM);
RAISE;http://tkyte.blogspot.com/2008/01/why-do-people-do-this.html -
Cursor and Update rows based on value/date
SQL Server 2012
Microsoft SQL Server Management Studio
11.0.3128.0
Microsoft Analysis Services Client Tools
11.0.3128.0
Microsoft Data Access Components (MDAC)
6.1.7601.17514
Microsoft MSXML 3.0 4.0 5.0 6.0
Microsoft Internet Explorer
9.11.9600.16518
Microsoft .NET Framework
4.0.30319.18408
Operating System
6.1.7601
The objective of this is to test the Cursor and use it on a production environment after this is fixed. What I would like to do is update rows in a column i duplicated originally called 'HiredDate' from AdventureWorks2012 HumanResources.Employee table. I
made a duplicate column called 'DateToChange' and would like to change it based on a date I have picked, which returns normally 2 results (i.e. date is '04/07/2003'). The code runs but will not change both dates. It did run however with an error but changed
only 1 of the 2 rows because it said ['nothing available in next fetch'].
The code to add the columns and perform the query to get the results I am running this against:
-- ADD column 'DateToChange'
ALTER TABLE [HumanResources].[Employee] ADD DateToChange Date NOT NULL;
-- Copy 'HireDate' data to 'DateToChange'
UPDATE HumanResources.Employee SET DateToChange = HireDate;
-- Change 'DateToChange' to NOT NULL
ALTER TABLE [HumanResources].[Employee] ALTER COLUMN DateToChange Date NOT NULL;
SELECT BusinessEntityID,HireDate, CONVERT( char(10),[DateToChange],101) AS [Formatted Hire Date]
FROM HumanResources.Employee
WHERE [DateToChange] = '04/07/2003';
Code:
USE AdventureWorks2012;
GO
-- Holds output of the CURSOR
DECLARE @EmployeeID INT
DECLARE @HiredDate DATETIME
DECLARE @HiredModified DATETIME
DECLARE @ChangeDateTo DATETIME
--Declare cursor
-- SCROLL CURSOR ALLOWS "for extra options" to pul multiple records: i.e. PRIOR, ABSOLUTE ##, RELATIVE ##
DECLARE TestCursor CURSOR SCROLL FOR
-- SELECT statement of what records going to be used by CURSOR
-- Assign the query to the cursor.
SELECT /*HumanResources.Employee.BusinessEntityID, HumanResources.Employee.HireDate,*/ CONVERT( char(10),[DateToChange],101) AS [Formatted Hire Date]
FROM HumanResources.Employee
WHERE DateToChange = '01/01/1901'
/*ORDER BY HireDate DESC*/ FOR UPDATE OF [DateToChange];
-- Initiate CURSOR and load records
OPEN TestCursor
-- Get first row from query
FETCH NEXT FROM TestCursor
INTO @HiredModified
-- Logic to tell the Cursor while "@@FETCH_STATUS" 0 the cursor has successfully fetched the next record.
WHILE (@@FETCH_STATUS = 0 AND @@CURSOR_ROWS = -1)
BEGIN
FETCH NEXT FROM TestCursor
IF (@HiredModified = '04/07/2003')/*05/18/2006*/
-- Sets @HiredModifiedDate data to use for the change
SELECT @ChangeDateTo = '01/01/1901'
UPDATE HumanResources.Employee
SET [DateToChange] = @ChangeDateTo --'01/01/1901'
FROM HumanResources.Employee
WHERE CURRENT OF TestCursor;
END
-- CLOSE CURSOR
CLOSE TestCursor;
-- Remove any references held by cursor
DEALLOCATE TestCursor;
GO
This query is run successfully but it does not produce the desired results to change the dates
04/07/2003 to 01/01/1901.
I would like the query to essentially be able to run the initial select statement, and then update and iterate through the returned results while replacing the necessary column in each row.
I am also open to changes or a different design all together.
For this query I need:
1. To narrow the initial set of information
2. Check if the information returned, in particular a date, is before [i.e. this current month minus 12 months or
12 months before current month]
3. Next replace the dates with the needed date
[Haven't written this out yet but it will need to be done]
4. After all this is done I will then need to update a column on each row:
if the 'date' is within 12 months to 12 months from the date checked
NOTE: I am new to TSQL and have only been doing this for a few days, but I will understand or read up on what is explained if given enough information. Thank you in advance for anyone who may be able to help.The first thing you need to do is forget about cursors. Those are rarely needed. Instead you need to learn the basics of the tsql language and how to work with data in sets. For starters, your looping logic is incorrect. You open
the cursur and immediately fetch the first row. You enter the loop and the first thing in the loop does what? Fetches another row. That means you have "lost" the values from the first row fetched. You also do not test the success of
that fetch but immediately try to use the fetched value. In addition, your cursor includes the condition "DateToChange = '01/01/1901' " - by extension you only select rows where HireDate is Jan 1 1901. So the value fetched into @HiredModified will
never be anything different - it will always be Jan 1 1901. The IF logic inside your loop will always evaluate to FALSE.
But forget all that. In words, tell us what you are trying to do. It seems that you intend to add a new column to a table - one that is not null (ultimately) and is set to a particular value based on some criteria. Since you intend the
column to be not null, it is simpler to just add the column as not null with a default. Because you are adding the column, the assumption is that you need to set the appropriate value for EVERY row in the table so the actual default value can be anything.
Given the bogosity of the 1/1/1901 value, why not use this as your default and then set the column based on the Hiredate afterwards. Simply follow the alter table statement with an update statement. I don't really understand what your logic
or goal is, but perhaps that will come with a better description. In short:
alter table xxx add DateToChange date default '19010101'
update xxx set DateToChange = HireDate where [some unclear condition]
Lastly, you should consider wrapping everything you do in a transaction so that you recover from any errors. In a production system, you should consider making a backup immediately before you do anything - strongly consider and have a good reason not
to do so if that is your choice (and have a recovery plan just in case). -
Commit after every three UPDATEs in CURSOR FOR loop
DB Version: 11g
I know that experts in here despise the concept of COMMITing inside loop.
But most of the UPDATEs being fired by the code below are updating around 1 million records and it is breaking our UNDO tablespace.
begin
for rec in
(select owner,table_name,column_name
from dba_tab_cols where column_name like 'ABCD%' and owner = p_schema_name)
loop
begin
execute immediate 'update '||rec.owner||'.'||rec.table_name||' set '||rec.column_name|| ' = '''||rec.owner||'';
end;
end loop;
end;We are not expecting ORA-01555 error as these are just batch updates.
I was thinking of implementing something like
FOR i IN 1..myarray.count
LOOP
DBMS_OUTPUT.PUT_LINE('event_key at' || i || ' is: ' || myarray(i));
INSERT INTO emp
empid,
event_id,
dept,
event_key
VALUES
v_empid,
3423,
p_dept,
myarray(i)
if(MOD(i, p_CommitFreq) = 0) --- When the loop counter becomes fully divisible by p_commit_frequency, it COMMITs
then
commit;
end if;
END LOOP;(Found from an OTN thread)
But i don't know how to access the loop counter value in a CURSOR FOR loop.To be fair, what is really despised is code that takes an operation that could have been performed in a single SQL statement and steps through it in the slowest possible way, committing pointlessly as it goes along (exactly like the example you found). Your original version doesn't do that - it looks more like some sort of one-off migration where you have to set every value of every column that matches some naming standard pattern to a constant. If that's the case, and if there are huge volumes involved and you can't simply add a bit more undo, then I don't see much wrong with committing after each update, especially if you track how far you've got so you can restart cleanly if it fails.
If you really want an incrementing counter in an unnamed cursor, apart from the explicit variable others have suggested, you could add rownum to the cursor (alias it to something that isn't an Oracle keyword), although it could complicate the ORDER BY that you might be considering for the restart logic. You could have that instead of the redundant 'owner' column in your example which is always the same as the constant p_schema_name.
Another approach would be to keep track of SQL%ROWCOUNT after each update by adding it to a variable, and commit when the total number of rows updated so far reaches, say, a million.
Could the generated statement use a WHERE clause, or does it really have to update every row in every table it finds?
Could there be more than one column to update per table? If so it might be worth generating one multi-column update statement per table, although it'll complicate things a bit.
btw you don't need the inner 'begin' and 'end' keywords, and whoever supplied the MOD example you found should know that three or four spaces usually make a good indent and you don't need brackets around IF conditions. -
"FOR REC IN CURSOR(PARAMETERS) LOOP" command does not work. Why?
Hi to all.
It's a pleasure to receive your help.
In "FOR REC IN CURSOR(PARAMETERS) LOOP" command although the query return value does not enter the loop.
Sounds simple, but I'm not seeing the flaw...
Suggestions?
Version: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0
Thank in advance,
FilippeFilippe Soares Roza wrote:
Hi to all.
It's a pleasure to receive your help.
In "FOR REC IN CURSOR(PARAMETERS) LOOP" command although the query return value does not enter the loop.
Sounds simple, but I'm not seeing the flaw...
Suggestions?
Version: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0
Thank in advance,
Filippe
see a picture of my car that does not work.
Tell me how to make my car go.
How do I ask a question on the forums?
SQL and PL/SQL FAQ -
A strange error about cursor and dblink
My dbms:Oracle8i Enterprise Edition Release 8.1.7.4.0
I have a stored procedure, which inserts records from a remote database into a local table.
The 'insert' statement have similar pattern:
insert into table_a
select table_b.columns from table_b@dblink
where table_a.column in (select table_b.column from table_b@dblink);
commit;
There are about 100 'insert' statement in my procedure. But there is same error messages at the same
place when the procedure is run. The error messages:ora-01000:maximum open cursors exceeded,ora-02063:
preceding line from dblink. I have manually run the 'insert'statements before the error place and after the error place.
The before and after statements are both OK.
From google.com, I have learned that 'commit' will clear the implicit cursors from 'insert' statement. So I think
the problem is ora-02063. Again, keywords 'ora-01000 ora-02063'from google.com, I found 'alter session close
database link dblink' might solve the problem. I have add the 'alter session' statement after each 'commit' in
my procedure. Unfortunately, same error happened again at the same place.
I am puzzled. Would you like to give some advice? Thanks a lot!Hello
Well, the best place to lookup error messages is here....
http://www.oracle.com/pls/db92/db92.homepage
It's also where all the rest of the database documentation is. As for this error, too many open cursors, as it suggests, one session has too many open. From the statement you are using to select the data, it seems like you are forming the statements dynamically, is this the case? If so, you're using cursors, and so there's a good chance you aren't closing them.
HTH -
Cursor Fetch Loop to Move data from one table to another
Hi Gurus,
I need to write a cursor fetch loop PL/SQL procedure that moves all the data from the students table to student_history table. Can anyone tell me how to do this please?
Thanksand the instructions were specific:"Write a PL/SQL procedure that moves all the data from the students table to student_history table. You should use CURSOR FETCH LOOP to retrieve the data"
Who in the world have given you that instruction? This person[s] should take their ABC learning too. I might have come up with 1001 ineffective and owful ways to perform some task, but to teach others to do it in the same way would be a bit arrogant. To copy the content of a table into another one in CURSOR FETCH LOOP is one of the worst solutions I've heard of. See
http://asktom.oracle.com/pls/ask/f?p=4950:8:16840616406862738180::NO::F4950_P8_DISPLAYID,F4950_P8_CRITERIA:5008574230335
Maybe you are looking for
-
Colour Calibration / White Point setting - Is Imac Display really professional quality
I am trying to calibrate my imac 27" using i1 Display2 calibration software. I am trying to set a traget of 6500 using the software but it advises the current is only 5600 and suggests moving the RGB sliders to get this current white point up to my 6
-
SAP E COMMERCE FOR ERP : Maintaining catalog variants in multiple languages
Hi All, I have created a product catalog with 2 variants, one for english and other for russian, have maintained the texts in corresponding langiages in the layout area. I created a webshop and used the catalog variant for russian, but still when the
-
ITunes locked? Help!
Hey all, When I tried to update to iTunes 10.1 today my iTunes wouldn't close and said 'The iTunes Library file is locked, on a locked disk, or you do not have write permission for this file'. I've tried dragging my iTunes Library to my desktop - iTu
-
How to install user 'hwd' from CD (SOLVED)
Forgive me, but I've searched on how to install a user program. Namely I want to install 'hwh' I have remade the Don't Panic CD with 'hwd-4.8.2.bin.tar.gz' inside the arch/pkg directory on the cd. pacman see's it, but won't install it. I know using t
-
Where can I find the files I've downloaded off websites in my ipad?
I've downloaded several PDF files and ePub files off of a website and when they are finished downloading they disappear and I can find them anywhere. I have iBooks and some of the times I can send the files to the iBooks but lately the option doesn't