About Pl/Sql Block
Hi All,
Is there any way in pl/sql block through which we can run the script file(.sql) which is stored in O.S drive.
Some one said that we can do with ref cursor,but how we can do.
Please suggest..
Thanks
Sandeep
Sandeep Bhutani wrote:
Hi All,
Is there any way in pl/sql block through which we can run the script file(.sql) which is stored in O.S drive.
Some one said that we can do with ref cursor,but how we can do.They lied. It has nothing to do with ref cursors.
The best way is to incorporate your SQL script as a stored procedure and/or package and then call that.
Calling external files would require you calling sql*plus from inside pl/sql which can be done with some java code. There are examples on the forum if you search, but if it were me, I'd just used the stored procedure method... it keeps everything in one place.
Similar Messages
-
My First while loop inside PL/SQL block not working , please help
Hi ,
I am new to PL/sql and struck at PL SQL blocks , please help to solve this .
declare
v_A number constant :=10 ;
j number constant := 3 ;
BEGIN
WHILE j < v_A
LOOP
DBMS_OUTPUT.PUT_LINE('Hai');
END LOOP;
END;
please help as how to resolve this .
Thanks in advance .btw it's a useful habit to use indentation to highlight the block structure. Also it's worth deciding what your convention will be for keywords (I use uppercase, lowercase is also fine as far as I'm concerned but I've set up my editor to uppercase them) and variables, database object names etc (I use lowercase), e.g:
DECLARE
v_a CONSTANT PLS_INTEGER := 10;
j CONSTANT PLS_INTEGER := 3;
i PLS_INTEGER := j;
BEGIN
WHILE i <= v_a LOOP
DBMS_OUTPUT.PUT_LINE(i);
i := i +1;
END LOOP;
END;or perhapsdeclare
v_a constant pls_integer := 10;
j constant pls_integer := 3;
i pls_integer := j;
begin
while i <= v_a loop
dbms_output.put_line(i);
i := i +1;
end loop;
end;When I see "declare" and "BEGIN" in the same block of code I worry about the standard of code I'm going to see... -
Bind Variable in SELECT statement and get the value in PL/SQL block
Hi All,
I would like pass bind variable in SELECT statement and get the value of the column in Dynamic SQL
Please seee below
I want to get the below value
Expected result:
select distinct empno ,pr.dept from emp pr, dept ps where ps.dept like '%IT' and pr.empno =100
100, HR
select distinct ename ,pr.dept from emp pr, dept ps where ps.dept like '%IT' and pr.empno =100
TEST, HR
select distinct loc ,pr.dept from emp pr, dept ps where ps.dept like '%IT' and pr.empno =100
NYC, HR
Using the below block I am getting column names only not the value of the column. I need to pass that value(TEST,NYC..) into l_col_val variable
Please suggest
----- TABLE LIST
CREATE TABLE EMP(
EMPNO NUMBER,
ENAME VARCHAR2(255),
DEPT VARCHAR2(255),
LOC VARCHAR2(255)
INSERT INTO EMP (EMPNO,ENAME,DEPT,LOC) VALUES (100,'TEST','HR','NYC');
INSERT INTO EMP (EMPNO,ENAME,DEPT,LOC) VALUES (200,'TEST1','IT','NYC');
INSERT INTO EMP (EMPNO,ENAME,DEPT,LOC) VALUES (300,'TEST2','MR','NYC');
INSERT INTO EMP (EMPNO,ENAME,DEPT,LOC) VALUES (400,'TEST3','HR','DTR');
INSERT INTO EMP (EMPNO,ENAME,DEPT,LOC) VALUES (500,'TEST4','HR','DAL');
INSERT INTO EMP (EMPNO,ENAME,DEPT,LOC) VALUES (600,'TEST5','IT','ATL');
INSERT INTO EMP (EMPNO,ENAME,DEPT,LOC) VALUES (700,'TEST6','IT','BOS');
INSERT INTO EMP (EMPNO,ENAME,DEPT,LOC) VALUES (800,'TEST7','HR','NYC');
COMMIT;
CREATE TABLE COLUMNAMES(
COLUMNAME VARCHAR2(255)
INSERT INTO COLUMNAMES(COLUMNAME) VALUES ('EMPNO');
INSERT INTO COLUMNAMES(COLUMNAME) VALUES ('ENAME');
INSERT INTO COLUMNAMES(COLUMNAME) VALUES ('DEPT');
INSERT INTO COLUMNAMES(COLUMNAME) VALUES ('LOC');
COMMIT;
CREATE TABLE DEPT(
DEPT VARCHAR2(255),
DNAME VARCHAR2(255)
INSERT INTO DEPT(DEPT,DNAME) VALUES ('IT','INFORMATION TECH');
INSERT INTO DEPT(DEPT,DNAME) VALUES ('HR','HUMAN RESOURCE');
INSERT INTO DEPT(DEPT,DNAME) VALUES ('MR','MARKETING');
INSERT INTO DEPT(DEPT,DNAME) VALUES ('IT','INFORMATION TECH');
COMMIT;
PL/SQL BLOCK
DECLARE
TYPE EMPCurTyp IS REF CURSOR;
v_EMP_cursor EMPCurTyp;
l_col_val EMP.ENAME%type;
l_ENAME_val EMP.ENAME%type;
l_col_ddl varchar2(4000);
l_col_name varchar2(60);
l_tab_name varchar2(60);
l_empno number ;
b_l_col_name VARCHAR2(255);
b_l_empno NUMBER;
begin
for rec00 in (
select EMPNO aa from EMP
loop
l_empno := rec00.aa;
for rec in (select COLUMNAME as column_name from columnames
loop
l_col_name := rec.column_name;
begin
l_col_val :=null;
l_col_ddl := 'select distinct :b_l_col_name ,pr.dept ' ||' from emp pr, dept ps where ps.dept like ''%IT'' '||' and pr.empno =:b_l_empno';
dbms_output.put_line('DDL ...'||l_col_ddl);
OPEN v_EMP_cursor FOR l_col_ddl USING l_col_name, l_empno;
LOOP
l_col_val :=null;
FETCH v_EMP_cursor INTO l_col_val,l_ename_val;
EXIT WHEN v_EMP_cursor%NOTFOUND;
dbms_output.put_line('l_col_name='||l_col_name ||' empno ='||l_empno);
END LOOP;
CLOSE v_EMP_cursor;
END;
END LOOP;
END LOOP;
END;user1758353 wrote:
Thanks Billy, Would you be able to suggest any other faster method to load the data into table. Thanks,
As Mark responded - it all depends on the actual data to load, structure and source/origin. On my busiest database, I am loading on average 30,000 rows every second from data in external files.
However, the data structures are just that - structured. Logical.
Having a data structure with 100's of fields (columns in a SQL table), raise all kinds of questions about how sane that structure is, and what impact it will have on a physical data model implementation.
There is a gross misunderstanding by many when it comes to performance and scalability. The prime factor that determines performance is not how well you code, what tools/language you use, the h/w your c ode runs on, or anything like that. The prime factor that determines perform is the design of the data model - as it determines the complexity/ease to use the data model, and the amount of I/O (the slowest of all db operations) needed to effectively use the data model. -
Can some one please tell me what is the problem in the below pl/sql block
Hi, I have problem with the following pl/sql block, I need this with bulk operation.
-- Assume the following scenario, we are validating dept (master) and emp(child) which are my temporary tables and updating the status back to
-- dept ( for all the validation errors, even if we have any validation at child it has to update the header record with error message),
-- upon successful validation insert the data into dept3, and emp3 interms of batches
-- I have give the sample example with dept and emp, but i have around 10 million records which has around 30-40 validations,
-- I would like to process them in terms of batches using bulk collection as this would do fast processing
-- Can some one please tell me how to insert them in terms of bulk with every set of 1000 records in each batch in this example,for every set of 1000 records
-- i need update batch id with unique number in dept table
-- with current data i can have 50 batches , I need to pass, deptno as parameter to my emp cursor.
-- can some one please tell me how to make this validation and insertion more efficient. so that while inserting the data for every batch it should insert batch id
-- Tried with LIMIT clause as well but not working
-- I am correcting the code as per your comments Request you to please suggest me so that I can correct , I am new to PL/sql, started learning now.
step - 1:
CREATE TABLE DEPT
(DEPTNO NUMBER(6) primary key,
DNAME VARCHAR2(25),
LOC VARCHAR2(23),
batch_id number );
INSERT INTO DEPT VALUES (10, 'ACCOUNTING', 'NEW YORK', null);
INSERT INTO DEPT VALUES (20, 'RESEARCH', 'DALLAS', null);
INSERT INTO DEPT VALUES (30, 'SALES', 'CHICAGO', null);
INSERT INTO DEPT VALUES (40, 'OPERATIONS', 'BOSTON', null);
step - 2:
declare
begin
for i in 1..50000 loop
insert into dept values(40+i, 'OPERATIONS'||i,'BOSTON'||i, null);
end loop;
commit;
exception
when others then
dbms_output.put_line('Exception occured:'||SQLERRM);
end;
step - 3:
create sequence emp_seq start with 1 increment by 1;
step - 4:
CREATE TABLE EMP
(EMPNO NUMBER(15) NOT NULL primary key,
ENAME VARCHAR2(20),
JOB VARCHAR2(20),
MGR NUMBER(4),
HIREDATE DATE,
SAL NUMBER(7, 2),
COMM NUMBER(7, 2),
DEPTNO NUMBER(6));
INSERT INTO EMP VALUES
(7369, 'SMITH', 'CLERK', 7902,
TO_DATE('17-DEC-1980', 'DD-MON-YYYY'), 800, NULL, 20);
INSERT INTO EMP VALUES
(7499, 'ALLEN', 'SALESMAN', 7698,
TO_DATE('20-FEB-1981', 'DD-MON-YYYY'), 1600, 300, 30);
INSERT INTO EMP VALUES
(7521, 'WARD', 'SALESMAN', 7698,
TO_DATE('22-FEB-1981', 'DD-MON-YYYY'), 1250, 500, 30);
INSERT INTO EMP VALUES
(7566, 'JONES', 'MANAGER', 7839,
TO_DATE('2-APR-1981', 'DD-MON-YYYY'), 2975, NULL, 20);
INSERT INTO EMP VALUES
(7654, 'MARTIN', 'SALESMAN', 7698,
TO_DATE('28-SEP-1981', 'DD-MON-YYYY'), 1250, 1400, 30);
INSERT INTO EMP VALUES
(7698, 'BLAKE', 'MANAGER', 7839,
TO_DATE('1-MAY-1981', 'DD-MON-YYYY'), 2850, NULL, 30);
INSERT INTO EMP VALUES
(7782, 'CLARK', 'MANAGER', 7839,
TO_DATE('9-JUN-1981', 'DD-MON-YYYY'), 2450, NULL, 10);
INSERT INTO EMP VALUES
(7788, 'SCOTT', 'ANALYST', 7566,
TO_DATE('09-DEC-1982', 'DD-MON-YYYY'), 3000, NULL, 20);
INSERT INTO EMP VALUES
(7839, 'KING', 'PRESIDENT', NULL,
TO_DATE('17-NOV-1981', 'DD-MON-YYYY'), 5000, NULL, 10);
INSERT INTO EMP VALUES
(7844, 'TURNER', 'SALESMAN', 7698,
TO_DATE('8-SEP-1981', 'DD-MON-YYYY'), 1500, NULL, 30);
INSERT INTO EMP VALUES
(7876, 'ADAMS', 'CLERK', 7788,
TO_DATE('12-JAN-1983', 'DD-MON-YYYY'), 1100, NULL, 20);
INSERT INTO EMP VALUES
(7900, 'JAMES', 'CLERK', 7698,
TO_DATE('3-DEC-1981', 'DD-MON-YYYY'), 950, NULL, 30);
INSERT INTO EMP VALUES
(7902, 'FORD', 'ANALYST', 7566,
TO_DATE('3-DEC-1981', 'DD-MON-YYYY'), 3000, NULL, 20);
INSERT INTO EMP VALUES
(7934, 'MILLER', 'CLERK', 7782,
TO_DATE('23-JAN-1982', 'DD-MON-YYYY'), 1300, NULL, 10);
commit;
step :- 5
declare
cursor c1 is select * from dept;
k number:=0;
m number:=0;
begin
for i in c1 loop
k:=k+1;
--dbms_output.put_line('k:'||k);
--dbms_output.put_line('i.deptno:'||i.deptno);
m:=0;
for j in 1..5 loop
m:=m+1;
--dbms_output.put_line('m:'||m);
--dbms_output.put_line('i.deptno:'||i.deptno);
insert into emp values
(9000+emp_seq.nextval, 'SMITH'||'_'||emp_seq.currval, 'CLERK'||'_'||emp_seq.currval, 7902,
TO_DATE('17-DEC-1980', 'DD-MON-YYYY'), 800, NULL, i.deptno);
end loop;
end loop;
commit;
exception
when others then
dbms_output.put_line('Exception occured:'||sqlerrm);
end;
step :-6
create table dept3 as select * from dept where 1=2;
create table emp3 as select * from emp where 1=2;
alter table dept add object_id number;
alter table dept add status varchar(20);
alter table dept add err_msg varchar2(200);
alter table emp add object_id number;
-- I have not included the alter statements in the inital creation because i dont want them to insert into dept3 and emp3
CREATE OR REPLACE
PACKAGE test_b
AS
g_batch_id NUMBER;
PROCEDURE emp_ins(
p_EMPNO NUMBER,
p_ENAME VARCHAR2,
p_JOB VARCHAR2,
p_MGR NUMBER,
p_HIREDATE DATE,
p_SAL NUMBER,
p_COMM NUMBER,
p_DEPTNO NUMBER);
PROCEDURE dept_ins(
p_DEPTNO NUMBER,
p_dname VARCHAR2 ,
p_LOC VARCHAR2,
p_batch NUMBER);
PROCEDURE validate_prc;
PROCEDURE main;
TYPE dept_t
IS
TABLE OF dept%ROWTYPE;
hdr_tbl dept_t;
TYPE emp_t
IS
TABLE OF emp%ROWTYPE;
line_tbl emp_t;
TYPE dept_i_t
IS
TABLE OF dept3%ROWTYPE;
hdr_ins_tbl dept_i_t;
TYPE emp_i_t
IS
TABLE OF emp3%ROWTYPE;
line_ins_tbl emp_i_t;
END;
-- pacakge body
CREATE OR REPLACE
PACKAGE body test_b
AS
PROCEDURE emp_ins(
p_EMPNO NUMBER,
p_ENAME VARCHAR2,
p_JOB VARCHAR2,
p_MGR NUMBER,
p_HIREDATE DATE,
p_SAL NUMBER,
p_COMM NUMBER,
p_DEPTNO NUMBER)
IS
BEGIN
INSERT
INTO EMP3
EMPNO ,
ENAME ,
JOB ,
MGR ,
HIREDATE ,
SAL ,
COMM ,
DEPTNO
VALUES
P_EMPNO ,
P_ENAME ,
P_JOB ,
P_MGR ,
P_HIREDATE ,
P_SAL ,
P_COMM ,
P_DEPTNO
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('EXCEPTION AT EMP INSERT'||SQLERRM);
END;
PROCEDURE dept_ins
p_DEPTNO NUMBER,
p_dname VARCHAR2 ,
p_LOC VARCHAR2,
p_batch NUMBER
IS
BEGIN
INSERT
INTO DEPT3
DEPTNO ,
DNAME ,
LOC ,
batch_id
VALUES
p_DEPTNO ,
p_DNAME ,
p_LOC ,
p_batch
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('EXCEPTION AT DEPT INSERT'||SQLERRM);
END ;
PROCEDURE validate_prc
IS
CURSOR c1
IS
SELECT * FROM dept WHERE status IS NULL ;--AND rownum <25;
CURSOR c2(p_dept NUMBER )
IS
SELECT * FROM emp WHERE deptno=p_dept;
e_validation EXCEPTION;
BEGIN
OPEN c1;
LOOP
FETCH c1 BULK COLLECT INTO hdr_tbl limit 5000;
SELECT emp_seq.nextval INTO g_batch_id FROM dual;
EXIT
WHEN hdr_tbl.count = 0;
dbms_output.put_line('batch'||g_batch_id);
END LOOP;
CLOSE c1;
dbms_output.put_line('C1 closed');
--------- Loading data into the inv line table type -------------------------------
FOR i IN 1 .. hdr_tbl.count
LOOP
dbms_output.put_line('started validation');
-- do header level validations
IF hdr_tbl(i).dname IS NULL THEN
hdr_tbl(i).status := 'ERROR';
hdr_tbl(i).err_msg :=',DNAME is null';
END IF;
OPEN c2(hdr_tbl(i).deptno);
LOOP
FETCH c2 BULK COLLECT INTO line_tbl;
-- EXIT WHEN c2%NOTFOUND;
END LOOP;
CLOSE c2;
FOR j IN 1 .. line_tbl.count
LOOP
-- do line validations
IF line_tbl(j).ename IS NULL THEN
hdr_tbl(i).status := 'ERROR';
hdr_tbl(i).err_msg :=',ENAME is null';
END IF;
BEGIN
FORALL j IN line_tbl.FIRST .. line_tbl.LAST
SAVE EXCEPTIONS
UPDATE EMP
SET object_id =3
-- I have multiple columns to update based on validations
WHERE deptno =hdr_tbl(i).deptno------------
AND empno =line_tbl (j).empno;
COMMIT;
line_tbl.DELETE;
dbms_output.put_line( 'Successfully updated emp temp table.');
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
dbms_output.put_line( 'Error while updating line temp table. ' || sqlerrm );
FOR j IN 1 .. sql%BULK_EXCEPTIONS.COUNT
LOOP
DBMS_OUTPUT.put_line(' occurred during line temp table updation ' || sql%BULK_EXCEPTIONS(i).ERROR_INDEX );
END LOOP;
raise e_validation;
END;
END LOOP; -- j
--CLOSE c2;
IF hdr_tbl(i).err_msg IS NULL THEN
hdr_tbl (i).status := 'VALID';
hdr_tbl (i).err_msg := NULL;
END IF;
-- even if I have line validation failed I have to update header status and erorr msg
BEGIN
FORALL i IN hdr_tbl.FIRST .. hdr_tbl.LAST
SAVE EXCEPTIONS
UPDATE DEPT
SET object_id =4,
status = hdr_tbl (i).status,
err_msg = hdr_tbl (i).err_msg
-- batch_id =
-- I have multiple columns to update based on validations
WHERE deptno = hdr_tbl (i).deptno
AND status IS NULL; ------------
COMMIT;
hdr_tbl.DELETE;
dbms_output.put_line( 'Successfully updated dept temp table.');
--close c1;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
dbms_output.put_line( 'Error while updating hdr temp table. ' || sqlerrm );
FOR i IN 1 .. sql%BULK_EXCEPTIONS.COUNT
LOOP
DBMS_OUTPUT.put_line(' occurred during line temp table updation ' || sql%BULK_EXCEPTIONS(i).ERROR_INDEX );
END LOOP;
raise e_validation;
END;
END LOOP; --i
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('EXCEPTION AT validate'||SQLERRM);
END ;
PROCEDURE main
IS
CURSOR dept_ins_cur
IS
SELECT * FROM dept WHERE status='VALID';
CURSOR emp_ins_cur(p_deptno NUMBER)
IS
SELECT * FROM emp WHERE deptno= p_deptno;
BEGIN
validate_prc;
OPEN dept_ins_cur;
LOOP
FETCH dept_ins_cur BULK COLLECT INTO hdr_ins_tbl limit 1000
EXIT
WHEN dept_ins_cur%NOTFOUND;
END LOOP;
CLOSE dept_ins_cur;
--------- Loading data into the inv line table type -------------------------------
FOR i IN 1 .. hdr_tbl.count
loop
dept_ins(hdr_ins_tbl(i).deptno ,
hdr_ins_tbl(i).DNAME ,
hdr_ins_tbl(i).LOC , emp_seq.nextval);
commit;
OPEN emp_ins_cur(hdr_ins_tbl(i).deptno);
LOOP
FETCH emp_ins_cur BULK COLLECT INTO line_ins_tbl;
--EXIT WHEN emp_ins_cur%NOTFOUND;
END LOOP;
CLOSE emp_ins_cur;
for j in 1..line_ins_tbl.count loop
emp_ins(line_ins_tbl(j).EMPNO ,
line_ins_tbl(j).ENAME ,
line_ins_tbl(j).JOB ,
line_ins_tbl(j).MGR ,
line_ins_tbl(j).HIREDATE ,
line_ins_tbl(j).SAL ,
line_ins_tbl(j).comm ,
line_ins_tbl(j).DEPTNO );
end loop;
end loop;
commit;
BEGIN
forall i IN hdr_ins_tbl.first .. hdr_ins_tbl.last
SAVE exceptions
UPDATE dept
SET status = 'INSERTED',
err_msg = null
WHERE deptno=hdr_ins_tbl (i).deptno
AND status = 'VALID';
COMMIT;
hdr_ins_tbl.delete;
dbms_output.put_line( 'inserting into temp tables.');
EXCEPTION
WHEN OTHERS THEN
rollback;
end;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('exception in main' ||SQLERRM);
END ;
END;
Thanks in advance...
Message was edited by: 888025Hi, I have problem with the following pl/sql block
Well, as Hoek already said, that is the understatement of the century.
I can't be absolutely certain but I think that set of DDL and code that you posted has just about every possible error and design issue that there is! It would make an excellent addition to BluShadow's FAQs an an example of what NOT to do.
I don't think it is even possible to 'fix the basics first' as Hoek suggested. IMHO the first step needs to be to create a functional requirements document (FRD) that explains in detail WHAT needs to be done. That doc should also contain info about how any errors/recovery/restart is to be handled. It is premature to try to implement ANY solution without first knowing what is needed functionally.
Once the FRD is done you should do a walk-through based on your current architecture and sample data to make sure that the document really covers ALL of the steps that need to be performed and that it adequately explains how to deal with any processing or data issues that might arise.
The next document you need is the TRD - Technical Requirements Doc that covers the different technical implementions of the FRD that can be done and the advantages/disadvantages of each.
Then you can start working on a prototype.
1. The DDL you posted isn't coherent - there are CREATE table statements and then later ALTER statements that add additional columns. There doesn't appear to be any reason for not including ALL of the columns in the CREATE table statement.
2. You are using PL/SQL types instead of SQL types. That makes it impossible to use those types in SQL statements and makes it much more difficult to test since it is much easier to test a query in SQL (e.g. using sql*plus) that to embed the query in PL/SQL.
3. You are defining the same type twice but giving it different names.
TYPE dept_t
IS
TABLE OF dept%ROWTYPE
INDEX BY binary_integer;
TYPE dept_i_t
IS
TABLE OF dept%ROWTYPE
INDEX BY binary_integer;
Those are both based on the same DEPT table! Why the duplication?
Also you are using associative arrays instead of just using nested tables. Get rid of the INDEX BY clause.
4. You have some serious architectural and data model issues
-- Assume the following scenario, we are validating dept (master) and emp(child) which are my temporary tables and updating the status back to
-- dept ( for all the validation errors, even if we have any validation at child it has to update the header record with error message),
Why would you do that? You say 'it has to update the header record ...'. Says who? That is just one indication that you are trying to implement a 'solution' before you have adequately defined the 'problem'.
Typically you would NOT alter any of the data tables; any validation errors/issues would get inserted into a table specifically designed to hold/log those issues. That table would contain key field values to correlate with the source of the error.
Those 'master' and 'child' entities are two SEPARATE things. Issues with a 'master' row have NOTHING to do with any possible child rows.
And issues with a 'child' row have NOTHING to do with any possible master rows. The ONLY connection between 'child' and 'master' is the foreign key that correlates them.
So you don't necessarily have to validate the 'child' rows in sync with their 'master' row. In many cases you would have a procedure that performs validation of the entire set of 'master' rows and log those issues/problems. You would use a different procedure to validate the entire set of 'child' rows and log their issues.
Those validation procedures can often work with ALL of the data using SQL statements instead of bulk processing.
5. You are using loop constructs that are not valid for the type of processing you are using
LOOP
FETCH c1 BULK COLLECT INTO hdr_tbl;
EXIT
WHEN c1%NOTFOUND;
END LOOP;
There can be NO exit since the bulk collect with either get EVERYTHING or NOTHING. Possibly that is just a holdover from your attempt to use the LIMIT clause but you removed that clause from the FETCH; I don't know.
There is so much wrong with what you posted it is really rather pointless to try to 'fix' it.
I suggest you start over and clarify and DOCUMENT the actual requirements without prejudice about the solution that someone seems to want to force on you. -
Can't create a sequence within a pl/sql block with execute immediate.
Hi All. I created a user and granted it the 'create sequence' privilege though a role. In a pl/sql block I try to create a sequence using 'execute immediate' but get a 1031-insufficient privileges error. If I grant create sequence directly to the user, the pl/sql block completes successfully. Can anyone explain this behavior? We're running 11.2 Enterprise Editon.
Thanks,
MarkIn a definer's rights stored procedure (the default), you only have access to privileges that have been granted directly, not via a role.
There are two basic reasons for that. First, roles can be enabled or disabled, default and non-default, password-protected, etc. so the set of roles a particular user actually has is session-specific. Oracle needs to know at compile time what privileges the owner of the procedure has. The only way to do that (without deferring the privilege check) is to ignore privileges granted through roles.
Second, since 99% of privilege management DBAs do involves granting and revoking roles, it's helpful that changing role privileges will never cause objects to be marked invalid and recompiled which can have side-effects on applications. DBAs only need to worry about causing problems on those rare cases where they are granting or revoking direct privileges to users.
You can create an invoker's rights stored procedure by adding the clause (AUTHID CURRENT_USER). That defer's the security check to run-time but allows the procedure to see privileges granted through roles in the current session. But that means that the caller of the procedure would need to have the CREATE SEQUENCE privilege through the role, not the owner of the procedure.
And just to make the point, dynamic object creation in PL/SQL is almost always a red flag that there is something problematic in your design. If you are creating sequences dynamically, that means that you'd have to refer to them dynamically throughout your code which means that your inserts would need to use dynamic SQL. That's not a particularly easy or safe way to develop code.
Justin -
Exception in declarative section to propagating in PL/SQL Block
Hi All, I have a requirement to send emails to some receipient whenever there is an error in a process. The is working untill the put a wrong database link in the parameter, the cursor is in declarative statement, hence when other exception does not work, create and enclosing block around the initial block so that the exception can propagate to the enclosing block, but this does not work either, please advice. Below is the a brief pseudo code. The bold is the initial block. Please advice.
DECLARE
Invalid_table EXCEPTION;
PRAGMA EXCEPTION_INIT(Invalid_table, -00942);
BEGIN
declare
c_test number;
cursor c1 is select 1 from tt@sro4link1 --- wrong databaselink sent as a parameter
where 1 =1;
*/*Because the error is in the cursor select, no email is been sent, that was the reason I put an enclosing block, but the exception is not propagate either */*
BEGIN
OPEN C1;
FETCH C1 into c_test;
CLOSE C1;
EXCEPTION
WHEN OTHERS THEN
--- Send email
END; EXCEPTION
WHEN Invalid_table THEN
--- send email
END;
/Ade2 wrote:
it is not a dynamic sql. Your description is not very clear about what is code and what is pseudo code, but if you are using substitution variables in sqlplus, then that is dynamic SQL.
sqlplus scans for substitution variables, prompts when needed, replaces the variable (substitutes) with the text input and passes the entire result to the database for validation.
If the substitution text input results in an invalid PL/SQL block then a compilation error is returned from the database. The PL/SQL cannot be compiled, it never runs, no run time exceptions are possible.
So you cannot use exceptions to detect errors in values input to substitution variables.
SQL> declare
2 l_dummy number;
3 begin
4 select 1 into l_dummy from dual;
5 end;
6 /
PL/SQL procedure successfully completed.
SQL> declare
2 l_dummy number;
3 begin
4 &5
5 end;
6 /
Enter value for 5: select 1 into l_dummy from dual;
old 4: &5
new 4: select 1 into l_dummy from dual;
PL/SQL procedure successfully completed.
SQL> /
Enter value for 5: this will not compile
old 4: &5
new 4: this will not compile
this will not compile
ERROR at line 4:
ORA-06550: line 4, column 8:
PLS-00103: Encountered the symbol "WILL" when expecting one of the following:
:= . ( @ % ; -
Update Statement(with Case) in PL/SQL Block
Can we use Oracle case syntax (In a Update SQL)in a PL/SQL Block .
UPDATE table_name a
SET a.colum1 =
case when a.col2 IN (SELECT col1
FROM table_name1 b )
then 'Y'
else 'N'
end
It throws me an Error of code PLS-00103(This error message is from the parser. It found a token (language element) that is inappropriate in this context.)
Is there any alternative...
Thanx in Advance
nullAlas, PL/SQL has own SQL parser, and this parser dosn't know about CASE expressions (at least, it's true up to Oracle 8.1.7).
Try to use DECODE instead, something like
UPDATE table_name a
SET a.colum1 =
SELECT decode(count(*),0,'N','Y)
FROM table_name1 b
WHERE b.col1=a.colum1 -
HTML not working in PL/SQL block..Help me ASAP
declare
l_col VARCHAR2(30) :=to_number(to_char(to_date('01-feb-2011','dd-mon-yyyy'),'dd'));
CURSOR name_cur IS
select name
from od_shift_schedule
where year=2011
and (month)=('Feb')
and decode(l_col,1,"01",2,"02",3,"03",4,"04",5,"05",6,"06",7,
"07",8,"08",9,"09",10,"10",11,"11",12,"12",13,"13",14,"14",15,"15",16,"16",17,"17",18,"18",19,"19",20,"20",
21,"21",22,"22",23,"23",24,"24",25,"25",26,"26",
27,"27",28,"28",29,"29",30,"30",31,"31")='W';
BEGIN
DELETE FROM nam;
commit;
FOR i IN name_cur
LOOP
dbms_output.put_line(i.name);
htp.p('<b>Employee '||i.name||' has been ticked.
</b><br/>');
EXECUTE IMMEDIATE 'insert into nam(name) values('''||i.name||''')';
commit;
END LOOP;
end;Kindly help me with this
If i'm wrong here kindly help me that how can i place a display messageRe: HTML not working in PL/SQL block..Help me ASAP
Using the community discussion forums for urgent issues is rude and a violation of the terms and conditions.
http://www.oracle.com/html/terms.html
>
4. Use of Community Services
Community Services are provided as a convenience to users and Oracle is not obligated to provide any technical support for, or participate in, Community Services. While Community Services may include information regarding Oracle products and services, including information from Oracle employees, they are not an official customer support channel for Oracle.
You may use Community Services subject to the following: (a) Community Services may be used solely for your personal, informational, noncommercial purposes; (b) Content provided on or through Community Services may not be redistributed; and (c) personal data about other users may not be stored or collected except where expressly authorized by Oracle
>
Also please read the FAQ on how to ask questions.
SQL and PL/SQL FAQ
>
2) Thread Subject line
Give your thread a meaningful subject, not just "help please", "Query help" or "SQL". This is the SQL and PL/SQL forum. We know your question is going to be about those things, make it meaningful to the type of question so that people with the right sort of knowledge can pick it up and those without can ignore it. Never, EVER, mark your subject as "URGENT" or "ASAP"; this forum is manned by volunteers giving their own time to help and your question is never urgent or more important than their own work or than other people's questions. It may be urgent to you, but that's not forum members issue. -
Exception error in PL/SQL block
Hi,
do the following conditions in a PL/SQL block cause an exception error to occur ?
A- Select statement does not return a row.
B- Select statement returns more than one row.
Thank you.If you're talking about SELECT INTO then yes:
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.4.0
Connected as cmza
SQL> set serveroutput on
SQL>
SQL> declare
2 v_text varchar2(4000);
3 begin
4 -- question 1
5 select banner
6 into v_text
7 from v$version;
8 end;
9 /
declare
v_text varchar2(4000);
begin
-- question 1
select banner
into v_text
from v$version;
end;
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at line 6
SQL> declare
2 v_text varchar2(4000);
3 begin
4 -- question 2
5 select banner
6 into v_text
7 from v$version
8 where 1 = 2;
9 end;
10 /
declare
v_text varchar2(4000);
begin
-- question 2
select banner
into v_text
from v$version
where 1 = 2;
end;
ORA-01403: no data found
ORA-06512: at line 6
SQL> -
Hi
If I run PL/SQL block
DECLARE
CURSOR C1 is SELECT CLM_CASE_NO FROM CLAIM_OBJECT.CLM_INVLVD_PRTY_T where CLM_CASE_NO=XXXX;
BEGIN
FOR X in C1 loop
INSERT INTO POSTL_ADDRS_ARCHIVE P (SELECT A.* FROM CLAIM_OBJECT.POSTL_ADDRS A, CLAIM_OBJECT.CLM_INVLVD_PRTY_T C WHERE
C.CLNT_NO = A.CLNT_NO AND C.CURR_ROW_IND='A' AND C.CLM_CASE_NO =X.CLM_CASE_NO );
end loop;
end;
there is no error with the above block
If I remove where clause in cursor and run block
DECLARE
CURSOR C1 is SELECT CLM_CASE_NO FROM CLAIM_OBJECT.CLM_INVLVD_PRTY_T;
BEGIN
FOR X in C1 loop
INSERT INTO POSTL_ADDRS_ARCHIVE P (SELECT A.* FROM CLAIM_OBJECT.POSTL_ADDRS A, CLAIM_OBJECT.CLM_INVLVD_PRTY_T C WHERE
C.CLNT_NO = A.CLNT_NO AND C.CURR_ROW_IND='A' AND C.CLM_CASE_NO =X.CLM_CASE_NO );
end loop;
end;
ERROR at line 1:
ORA-01013: user requested cancel of current operation
ORA-06512: at line 12
I searched for ORA-06512
Cause:
This error message indicates the line number in the PLSQL code that the error resulted.
SELECT CLM_CASE_NO FROM CLAIM_OBJECT.CLM_INVLVD_PRTY_T has over 800,672 records.
SELECT CLM_CASE_NO FROM CLAIM_OBJECT.CLM_INVLVD_PRTY_T where CLM_CASE_NO=XXXX; has 2 records.
I am not not understanding why block 2 is throwing error (with no where clause in cursor)
Any help will be greatly appreciated
Thanks in advanceAs the error message indicates clearly the process was cancelled as you pressed CTRL+C. And yes you can’t see any data you insert in one session from other session until it gets committed. And as others have mentioned row by row operation is very expensive think about revising your approach.
Instead of having a cursor why don’t you join it directly in you select in the insert statement and try?
Thanks,
Karthick.
Message was edited by:
karthick_arp -
Alter database statement in anonymous pl/sql block
Is it possible to include an alter database statement in an anonymous pl/sql block?
When I execute this code to query user_tables for all table names, disable their constraints and drop the table, I got the following error:
***MY CODE
-- DECLARE VARIABLE(S)
DECLARE
v_TABLE_NAME TABLE_NAME.USER_TABLE%TYPE;
-- DECLARE AND DEFINE CURSOR
CURSOR c_GETTABLES is
SELECT TABLE_NAME from USER_TABLES;
BEGIN
OPEN c_GETTABLES;
LOOP
FETCH c_GETTABLES into v_TABLE_NAME;
EXIT when c_GETTABLES%notfound;
ALTER TABLE v_TABLE_NAME DISABLE PRIMARY KEY CASCADE;
DROP TABLE v_TABLE_NAME;
END LOOP;
CLOSE c_GETTABLES;
END;
***RESPONSE FROM SERVER
ALTER TABLE v_TABLE_NAME DISABLE PRIMARY KEY CASCADE;
ERROR at line 15:
ORA-06550: line 15, column 1:
PLS-00103: Encountered the symbol "ALTER" when expecting one of the following:
begin case declare exit for goto if loop mod null pragma
raise return select update while with <an identifier>
<a double-quoted delimited-identifier> <a bind variable> <<
close current delete fetch lock insert open rollback
savepoint set sql execute commit forall merge
<a single-quoted SQL string> pipe
ThanksWhen you want to perform ddl statements in a (anonymous) PL/SQL block, you have to use dynamic SQL because ddl is not possible in pl/sql.
Dynamic sql means that you sort of execute ddl statements in a sql manner. To use dynamic sql, two options exist:
- dbms_sql package : for oracle before 8i. To use this package is not always easy. Read about it carefully first before using.
- Native Dynamic SQL : implemented in 8i and very easy to use. An example would be :
declare
lv_statement varchar2(32676);
begin
lv_statement := 'ALTER TABLE MY_TABLE DISABLE CONSTRAINT MY_TABLE_CK1';
execute immediate lv_statement;
lv_statement := 'ALTER TABLE MY_TABLE ENABLE CONSTRAINT MY_TABLE_CK1';
execute immediate lv_statement;
end;
Good luck.
Edwin van Hattem -
Group By function inside a PL/sql Block
Hi,
I have a select statement which looks like this -
select Region, count(region) from QUOTE_LETTERS_MASTER where version != 'v112012' and source = 'http://esource.oraclecorp.com/portal/pls/portal/esrc.esr_portlet.show?id=74,34,12202' and region != 'eSource'
group by region
REGION COUNT(REGION)
EMEA 25
NA 1
LAD 10
Japan 1
Now the above code will have different result based on the version and source provided.
I want to use a code on similar lines where the based on version and source which will come from a cursor, i want the region and count of region, but because the result will keep on changing based on the where clause i am not sure how to use the similar code as above inside a pl/sql block.
Thank you,
rakeshHi, I haven't tested this but how about something like this:
create or replace procedure testproc(p_version VARCHAR2, p_source VARCHAR2)
as
v_version varchar2(100);
v_source varchar2(1000);
cursor c1 is
select Region, count(region) as cnt
from QUOTE_LETTERS_MASTER
where version != v_version
and source = v_source
and region != 'eSource'
group by region;
begin
v_version := p_version;
v_sourse := p_source;
for r1 in c1 loop
dbms_output.put_line(r1.region||' '||r1.cnt);
end loop;
end; -
This question sound funny. I just want to make sure this rule. In Oracle database before 10g, we can only use DML and transaction control code within PL/SQL block. We can not use DDL or other control languages within PL/SQL block. How about 10g? can I use DDL in PL/SQL block in 10g?
I have created a procedure to drop all materialized view. Drop object is DDL. I used a piece of code like this:
v_sql_stmt1 := 'DROP MATERIALIZED VIEW'||v_schema||'.'||x.mview_name;
EXECUTE IMMEDIATE v_sql_stmt1;
The procedure was compiled successfully. However, when I run this SP, it generate ORA-00905 missing keyword error on EXECUTE IMMEDIATE statement part. Is this caused by missing keyword in sql statement or DROP as DDL can not be used in PL/SQL block? If it is first one, what is the keyword for DROP MATERIALIZED VIEW statement?The versions of Oracle that run on this planet have been able to do DDL in PL/SQL for quite some time now. The DBAs who blasted off into space with you and worked in a vacuum the past however many years you feel you've been limited by this need to be replaced or re-introduced to Oracle.
For what it's worth, the error looks like you're missing a space. -
How to use Pl/sql block to edit check user input
Hi,
Please advise on PL/SQL Block code that could be used to Check User input from within a Loop and proceed conditionally based upon User Supplied compliant Input. Thanks in advance.Hi,
yakub21 wrote:
You could use the ACCEPT to get user input and then assign the input to a variable that could then be verified.
I believe that anything is possible because we don't yet have proof that it is not!
I do have code that can accept user input. Is it PL/SQL code? Sybrand was clearly talking about PL/SQL:
sybrand_b wrote:
Pl/sql is for server side code, it is not a front end tool, and it is incapable of the functionality you describe.If you do have PL/SQL code that accepts user input, please post an example. A lot of people, including me, would be very interested.
Pass the user-input value to a variable and then assign that value to another variable from within a Declare of a PL/SQL Block.
The opportunity here is to figure a way to loop with user input until desired input is entered by the user before proceeding with the code. I'm using PL/SQL Block because I don't want the code to persist. I just want to run it as part of database configuration procedure. ThanksIt sounds like you're talking about SQL*Plus, which is a very poor tool for looping or branching.
It's possible, but it's not pretty. The following thread shows one way of looping in SQL*Plus:
Re: How to give the different values to runtime parameters in a loop? -
PL/SQL block to generate i/o
Dear all,
10.2.0.4 on solaris
I want to generate I/O on a table. how can I create a a PL/SQL block which loops into and inserts/updates/deletes and commits on this table and thereby testing the I/O on the table ?
KaiKaiS wrote:
I want to generate I/O on a table. how can I create a a PL/SQL block which loops into and inserts/updates/deletes and commits on this table and thereby testing the I/O on the table ?What about the db buffer cache? What about Oracle attempting to optimise I/O performance by reducing physical I/O? What about the file system used and the o/s file system cache that does the exact same thing?
How do you now "+test+" I/O? What exactly are you testing? The Oracle buffer cache? The o/s file system cache? The speed of the file system? The speed of the disk(s)?
And if you get a result like "+100 inserts/per second+" - just what does that mean? How are you going to use this number to determine performance for application code, determine potential bottlenecks and so on?
A journey can only start when you know the route and most importantly, the destination. Else you're just wandering around without a clue.
Maybe you are looking for
-
Flex time and minor tempo adjustments
Hey y'all! So I'm working on a project in which vintage analog synths were run through tape before being digitized and brought into logic. Because tape is tape, this introduced some drift into the tempo. Instead of it being a nice clean 120bpm, it's
-
IP Address or sender did not respond messages
I am on Tiger and my mother in law is on Leopard, both are Macbooks. She is the only person I cannot video chat with. The errors come up either Invalid IP address or that I (when calling her) did not respond. On her end it says that I cancelled the c
-
MR02 exemption to certain Document Types
Hi all, Greetings of the Day Iam having a typical problem, I have an Invoice for which TDS has been deducted & TDS Document is generated. Both the Invoice & TDS Documents are Flagged with Payment Block "R". When I released the Invoice Document and tr
-
cannot find anything on computer regarding mozilla, but stuill saying must restart to complete uninstall. will not reinstall. please help
-
Batch split error message: Item category not defined
Hi gurus, I'm trying to use the batch split in an inbound delivery but I get the error message of the subject of this thread while saving. Could you bring some light here please? Many thanks, Marc