I tried to run the following code via apex online
DECLARE
t1 VARCHAR(44);
t2 VARCHAR(11);
c VARCHAR(3);
BEGIN
t1:='061,065,059,067,064,066,071,111,110,121,077.';
t2:=NULL;
FOR I IN LENGTH(t1)/4
loop
c:=SUBSTR(t1,((LENGTH(t1)/4),3);
t2:=t2||CHR(TO_NUMBER(c));
end loop;
DBMS_OUTPUT.PUT_LINE(t2);
END;
But got the following error
ORA-06550: line 9, column 2:
PLS-00103: Encountered the symbol "LOOP" when expecting one of the following:
* & - + / at mod remainder rem .. <an exponent (**)> ||
Thanks guys, i solved the second error, actually
c:=SUBSTR(s1,1+((LENGTH(s1)/4)-I)*4,3);
FOR I IN 1..LENGTH(t1)/4 LOOP
END LOOP;
Try this one:
DECLARE
t1 VARCHAR(50);
t2 VARCHAR(100);
c VARCHAR(50);
BEGIN
t1:='061,065,059,607,064,066,071,111,110,121,077.';
t2:=NULL;
FOR I IN 1..LENGTH(t1)/4 loop
c:=SUBSTR(t1,(LENGTH(t1)/4),3);
-- t2:=t2||CHR(TO_NUMBER(c));
t2:=t2||(c);
end loop;
DBMS_OUTPUT.PUT_LINE(t2);
END;
Related
My code:
create table info(str varchar2(30));
declare
cursor c(job emp_ast.job_id%type, dep emp_ast.department_id%type) is select employee_id
from emp_ast
where job_id=job and department_id=dep;
type t_job is table of emp_ast.job_id%type;
t t_job:=t_job();
emp emp_ast.employee_id%type;
i number(3);
begin
select job_id
bulk collect into t
from emp_ast;
for i in 10..270 loop
for j in 1..t.count loop
open c(i, t(j));
loop
fetch c into emp;
insert into info
values (i||' '||t(j)||' '||emp);
exit when c%notfound;
end loop;
i:=i+10;
end loop;
end loop;
end;
/
I get "expression 'I' cannot be used as an assignment target", reffering to the line where I increment i by 10. I am trying to save the department_id, employee_id and job_id as a string in a table for each department and each job.
At the point where you get that message, i refers to the loop control variable i defined in the line for i in 10..270 loop, not the int(3) variable defined earlier. In PL/SQL a loop definition defines a variable which is only accessible inside the loop, and which you cannot alter. I suggest you change the name of one or the other to make them unique.
EDIT
PL/SQL doesn't provide a way to step by more than 1 in a computed FOR loop. Instead, you will need to compute the desired department number value within the loop:
DECLARE
CURSOR c(job EMP_AST.JOB_ID%TYPE,
dep EMP_AST.DEPARTMENT_ID%TYPE)
IS SELECT EMPLOYEE_ID
FROM EMP_AST
WHERE JOB_ID = job AND
DEPARTMENT_ID = dep;
TYPE t_job IS TABLE OF EMP_AST.JOB_ID%TYPE;
t t_job := t_job();
emp EMP_AST.EMPLOYEE_ID%TYPE;
nDepartment NUMBER;
BEGIN
SELECT job_id
BULK COLLECT INTO t
FROM EMP_AST;
FOR i IN 1..27 LOOP
nDepartment := i * 10;
FOR j IN 1..t.COUNT LOOP
OPEN c(t(j), nDepartment);
LOOP
FETCH c INTO emp;
INSERT INTO info
VALUES (nDepartment || ' ' || t(j) || ' ' || emp);
EXIT WHEN c%notfound;
END LOOP; -- cursor c
CLOSE c;
END LOOP; -- j
END LOOP; -- i
END;
/
Note that in the code above the nDepartment value is computed within the i loop, which now increments from 1 to 27 instead of going from 10 to 270.
Previously,I asked about creating a function that returns total amount of salaries from a parameter city.
I chose Dallas for instance.Tables are EMP and DEPT:
You can find them below
https://livesql.oracle.com/apex/livesql/file/content_O5AEB2HE08PYEPTGCFLZU9YCV.html
Mistakenly I wrote in my language instead of english at the end of it but I corrected it.
Now I need to create a procedure which lists ascending the employees and their salaries from another parameter city.After listing them I need to call the function for the second city.Problem is I get an error for the 'loop' from the procedure and i got no idea why.
set serveroutput on;
create or replace function show_sal (local dept.loc%type) return number as
vval number;
begin
select sum(emp.sal)
into vval
from emp inner join dept on dept.deptno = emp.deptno
where upper(dept.loc) = upper(local);
return vval;
end;
/
begin
dbms_output.put_line('Total sum of salaries from DALLAS = ' || show_sal('DALLAS'));
end;
/
-------------------------------------------------------------------------------------------------
CREATE OR REPLACE PROCEDURE show_employees(v_loc dept.loc%TYPE) AS
CURSOR c IS
SELECT ename,sal
FROM emp INNER JOIN dept ON emp.deptno = dept.deptno
WHERE UPPER(loc)=UPPER(v_loc)
ORDER BY ename ASC;
v_name VARCHAR2;
v_salaries emp.sal%TYPE;
BEGIN
OPEN c
LOOP
FETCH c INTO v_name,v_salaries;
EXIT WHEN c%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_name||' '|| v_salaries);
END LOOP;
CLOSE c;
END;
/
EXECUTE show_employees('CHICAGO');
BEGIN
show_sal('CHICAGO');
END;
/
You simply forgot the semicolon after OPEN c.
And here is how to do the same with an implicit cursor, which is much easier to deal with in my opinion:
CREATE OR REPLACE PROCEDURE show_employees(v_loc dept.loc%TYPE) AS
BEGIN
FOR rec IN
(
SELECT ename, sal
FROM emp
WHERE deptno IN (SELECT deptno FROM dept WHERE UPPER(loc) = UPPER(v_loc))
ORDER BY ename
) LOOP
DBMS_OUTPUT.PUT_LINE(rec.ename || ' ' || rec.sal);
END LOOP;
END show_employees;
Errors i get:
Function SHOW_SAL compiled
Total sum of salaries from DALLAS = 10875
PL/SQL procedure successfully completed.
Procedure SHOW_EMPLOYEES compiled
LINE/COL ERROR
9/9 PLS-00215: String length constraints must be in range (1 .. 32767)
Errors: check compiler log
Error starting at line : 40 in command -
BEGIN show_employees('CHICAGO'); END;
Error report -
ORA-06550: line 1, column 61:
PLS-00905: object HR.SHOW_EMPLOYEES is invalid
ORA-06550: line 1, column 61:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Error starting at line : 42 in command -
BEGIN
show_sal('CHICAGO');
END;
Error report -
ORA-06550: line 2, column 1:
PLS-00221: 'SHOW_SAL' is not a procedure or is undefined
ORA-06550: line 2, column 1:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
set serveroutput on;
create or replace function show_sal (local dept.loc%type) return number as
vval number;
begin
select sum(emp.sal)
into vval
from emp inner join dept on dept.deptno = emp.deptno
where upper(dept.loc) = upper(local);
return vval;
end;
/
begin
dbms_output.put_line('Total sum of salaries from DALLAS = ' || show_sal('DALLAS'));
end;
/
-------------------------------------------------------------------------------------------------
CREATE OR REPLACE PROCEDURE show_employees(v_loc dept.loc%TYPE) AS
CURSOR C is SELECT ename,sal
FROM emp,dept
WHERE emp.deptno=dept.deptno AND UPPER(loc)=UPPER(v_loc)
ORDER BY ename ASC;
v_nume emp.ename%TYPE;
v_salariu emp.sal%TYPE;
v_tot emp.sal%TYPE;
BEGIN
v_tot:=show_sal('CHICAGO');
dbms_output.put_line('nume salar total: '||v_tot);
OPEN C;
LOOP
FETCH C INTO v_nume,v_salariu;
EXIT WHEN C%NOTFOUND;
dbms_output.put_line(v_nume||' '||v_salariu);
END LOOP;
CLOSE C;
END;
/
EXECUTE show_employees('CHICAGO');
DECLARE
c SYS_REFCURSOR;
lv_emp emp%ROWTYPE;
BEGIN
OPEN c FOR SELECT employee_id FROM emp;
--fetch c into lv_emp;
DBMS_OUTPUT.put_line (c.emloyee_id);
END;
ERROR at line 7:
ORA-06550: line 7, column 24:
PLS-00487: Invalid reference to variable 'C'
ORA-06550: line 7, column 1:
Statement ignored
If the objective is to list all the employee_id, you could do with REFCURSOR as cited below in an anonymous block.
VARIABLE c REFCURSOR
DECLARE
BEGIN
OPEN :c FOR SELECT empno FROM scott.emp;
END;
/
PRINT c;
SYS_REFCURSOR in an anonymous block
DECLARE
c_cursor SYS_REFCURSOR;
l_row scott.emp%ROWTYPE;
BEGIN
OPEN c_cursor FOR SELECT * FROM scott.emp;
LOOP
FETCH c_cursor INTO l_row;
EXIT WHEN c_cursor%NOTFOUND;
DBMS_OUTPUT.put_line (l_row.empno || ' : ' || l_row.ename);
END LOOP;
CLOSE c_cursor;
END;
/
Using SYS_REFCURSOR in a Procedure
Procedure Creation
CREATE OR REPLACE PROCEDURE test_proc_cursor (c OUT SYS_REFCURSOR)
AS
BEGIN
OPEN c FOR SELECT empno FROM scott.emp;
END test_proc_cursor;
/
Execution of the above procedure
DECLARE
cur SYS_REFCURSOR;
p_empno VARCHAR2 (50);
BEGIN
test_proc_cursor (c => cur);
LOOP
FETCH cur INTO p_empno;
EXIT WHEN cur%NOTFOUND;
DBMS_OUTPUT.put_line ('empno -->' || p_empno);
END LOOP;
CLOSE cur;
END;
/
I have the below code to insert clob datatype from SQL server to Oracle Database using DBlink.
I m currently facing the error :
ORA-06502: PL/SQL: numeric or value error: invalid LOB locator specified: ORA-22275
ORA-06512: at "SYS.DBMS_LOB", line 639. Can you please help me what could be the issue with the code?
declare
v_REGION_CODE CLOB ;
l_clob CLOB;
c integer;
nr integer;
BEGIN
DBMS_LOB.CREATETEMPORARY(l_clob,true);
EXECUTE IMMEDIATE 'TRUNCATE TABLE SVQ_DI_XLS_COUNTRY_POP_DETAILS';
c := DBMS_HS_PASSTHROUGH.OPEN_CURSOR#PPRLEG;
DBMS_HS_PASSTHROUGH.PARSE#PPRLEG(c,' SELECT "REGION CODE" FROM TBL_SVQ_DI_XLS_COUNTRY_POP_DETAILS');
LOOP
nr := DBMS_HS_PASSTHROUGH.FETCH_ROW#PPRLEG(c);
EXIT
WHEN nr = 0;
DBMS_HS_PASSTHROUGH.GET_VALUE#PPRLEG(c, 1 , v_REGION_CODE ) ;
FOR i IN 1..10
LOOP
INSERT INTO SVQ_DI_XLS_COUNTRY_POP_DETAILS (REGION_CODE) VALUES (empty_clob()) --Insert an "empty clob" (not insert null)
RETURNING REGION_CODE INTO l_clob;
FOR i IN 1..100
LOOP
dbms_lob.append(l_clob, v_REGION_CODE);
--dbms_lob.append(l_clob, 'string chunk to be inserted (maximum 4000 characters at a time)');
END LOOP;
END LOOP;`enter code here`
END LOOP;
DBMS_HS_PASSTHROUGH.CLOSE_CURSOR#PPRLEG(c);
COMMIT;
END;
I'm trying to run the following PLSQL script in APEX:
DECLARE
total NUMBER;
BEGIN
SELECT COUNT(*)
INTO total
FROM one_table;
FOR i IN 0:100 --This is line 8
LOOP
INSERT INTO other_table(id, column_a) SELECT id + i * total, column_a FROM one_table;
END LOOP;
COMMIT;
END;
And I get this error:
ORA-06550: line 8, column 15: PLS-00103: Encountered the symbol "" when expecting one of the following: * & - + / at mod remainder rem .. <an exponent (**)> || multiset The symbol ".." was substituted for "" to continue.'
I don't think this is legal syntax:
FOR i IN 0:100
I think you mean:
FOR i IN 0..100