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
Related
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');
I have a table T1 and I want to insert multiple rows at a time through a procedure using collection. I have written the code but when I'm trying to execute it throws an error. Please advise.
create table t1 ( id number , name varchar2(10));
/
create or replace PACKAGE PKG1 AS
TYPE TAB_LIST IS TABLE OF T1%ROWTYPE;
PROCEDURE PROC1 (p_val IN TAB_LIST);
END PKG1;
/
create or replace PACKAGE BODY PKG1 AS
PROCEDURE PROC1 (P_VAL IN TAB_LIST
)
IS
BEGIN
FOR i IN p_val.FIRST..p_val.LAST
LOOP
insert INTO T1
(
id, name
)
VALUES
(
p_val(i).id,
p_val(i).name
);
END LOOP;
END;
END;
error after executing
DECLARE
p_val PKG1.TAB_LIST;
BEGIN
p_val := PKG1.TAB_LIST(123,'XYZ');
END;
Error report -
ORA-06550: line 5, column 11:
PLS-00306: wrong number or types of arguments in call to 'TAB_LIST'
ORA-06550: line 5, column 11:
PLS-00306: wrong number or types of arguments in call to 'TAB_LIST'
ORA-06550: line 5, column 2:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
DECLARE
P_VAL PKG1.TAB_LIST := PKG1.TAB_LIST();
BEGIN
P_VAL.extend;
P_VAL(1).id := 123;
P_VAL(1).name := 'XYZ';
PKG1.PROC1( P_VAL );
END;
example for multiple records:
DECLARE
P_VAL PKG1.TAB_LIST := PKG1.TAB_LIST();
BEGIN
for i in 1 .. 10
loop
P_VAL.extend;
P_VAL(P_VAL.LAST).id := i;
P_VAL(P_VAL.LAST).name := 'XYZ' || i;
end loop;
PKG1.PROC1( P_VAL );
END;
#hekko": its not a string .sorry about formatting . The multiple values (n) can be passed from application like this and all should be inserted into table at once.
123 'XYZ'
456 'DFK'
866 'HKK'
#Kaushik :it is not a string but formatting issue.. the question remains the same "I have a table T1 and I want to insert multiple rows at a time through a procedure using collection.
Im trying to learn PL/SQL. I am struck with this code. Please notify me where im going wrong. I use Oracle 10g in a command line .
declare
grade char(1):='&v_grade';
app varchar(15);
begin
app:=case v_grade
when 'a' then
dbms_output.put_line('Excellent');
when 'b' then
dbms_output.put_line('Good');
else
dbms_output.put_line('Bad');
end case;
dbms_output.put_line('Grade'||grade||' Appraisal:'||app);
end;
/
It shows
Enter value for v_grade: a
old 2: grade char(1):='&v_grade';
new 2: grade char(1):='a';
dbms_output.put_line('Excellent');
*
ERROR at line 7:
ORA-06550: line 7, column 34:
PLS-00103: Encountered the symbol ";" when expecting one of the following:
. ( * % & = - + < / > at else end in is mod remainder not rem
when <an exponent (**)> <> or != or ~= >= <= <> and or like
LIKE2_ LIKE4_ LIKEC_ between || multiset member SUBMULTISET_
The symbol ";" was ignored.
ORA-06550: line 9, column 29:
PLS-00103: Encountered the symbol ";" when expecting one of the following:
. ( * % & = - + < / > at else end in is mod remainder not rem
when <an exponent (**)> <> or != or ~= >= <= <> and or like
LIKE2_ LIKE4_ LIKEC_ between ||
ORA-06550: line 11, column 28:
PLS-00103: Encountered the symbol ";" when expecting one of the following:
. ( * % & = - + < / > at end in is mod remainder not rem
<an exponent (**)> <> or != or ~= >= <= <> and or like LIKE2_
LIKE4_ LIKEC_ between || multiset
please notify me where i am going wrong.
T.J. Crowder is sort of right, you shouldn't have a semicolon within a case statement in SQL, but this is the PL/SQL version so it's slightly different.
You are currently trying to assign the (non-existent) return from the dbms_output.put_line procedure (not function) call to your app variable.
For the assignment to work you need the case to evaluate to a string, so you can just use text literals; but the assignment needs to be in each branch:
declare
grade char(1):='&v_grade';
app varchar(15);
begin
case grade
when 'a' then app:= 'Excellent';
when 'b' then app:= 'Good';
else app := 'Bad';
end case;
dbms_output.put_line('Grade '||grade||' Appraisal: '||app);
end;
/
Which when run gets:
Enter value for v_grade: a
Grade b Appraisal: Excellent
PL/SQL procedure successfully completed.
Or use a query to do the assignment, though this is not quite as efficient:
declare
grade char(1):='&v_grade';
app varchar(15);
begin
select case grade
when 'a' then 'Excellent'
when 'b' then 'Good'
else 'Bad'
end case
into app
from dual;
dbms_output.put_line('Grade '||grade||' Appraisal: '||app);
end;
/
Enter value for v_grade: b
Grade b Appraisal: Good
PL/SQL procedure successfully completed.
Or you can do the output directly in each branch:
declare
grade char(1):='&v_grade';
begin
dbms_output.put('Grade '||grade||' Appraisal: ');
case grade
when 'a' then
dbms_output.put_line('Excellent');
when 'b' then
dbms_output.put_line('Good');
else
dbms_output.put_line('Bad');
end case;
end;
/
Enter value for v_grade: c
Grade c Appraisal: Bad
PL/SQL procedure successfully completed.
The first part of your output is before the case now.
You're basically mixing up the different approaches.
You might want to change the first line to:
grade char(1):= upper('&v_grade');
... and then make the case look for A,B,C instead of a,b,c - then it won't matter what case the input is in.
You can read more about the PL/SQL case statemnt here and here.
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 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;