After a looong research i have decided i have no idea what causes the following problem! I want to create a stored procedure that will increase the value of a column if that satisfied a statement.I can run the procedure as a anonymous block but i cant run it as a stored procedure!
Here is the stored procedure code:
1 create or replace
2 Procedure RaiseSalary
3 Is
4 Salary number;
5 Cursor RaiseCursor
6 Is
7 Select Salary_A From Person Where Salary_A<400 for update of Salary_A;
8 Begin
9 Open RaiseCursor;
10 Loop
11 Fetch RaiseCursor Into Salary;
12 Exit When RaiseCursor%Notfound;
13 Update Person Set Salary_A=(Salary + 200) Where Current Of RaiseCursor;
14 End Loop;
15 Close RaiseCursor;
16 Commit;
17 End;
I am getting an error at line 3 that says "Encountered the symbol "SALARY" when expecting one of the following:...." and i am getting the same error at line 5 at the "s" letter of the word Cursor ,but at this time it says ";" instead of "Salary". The compiler log shows "insufficient privileges" but i can't find a reasonable explanation for this.
I have tried to run the code as an anonymous block like this:
Declare
Salary number;
Cursor RaiseCursor
Is
Select Salary_A From Person Where Salary_A<400 for update of Salary_A;
Begin
Open RaiseCursor;
Loop
Fetch RaiseCursorInto Salary ;
Exit When RaiseCursor%Notfound;
Update Person Set Salary_A =(Salary + 200) Where Current Of RaiseCursor;
End Loop;
Close RaiseCursor;
Commit;
End;
.
run;
And works great!!!I am sure that i have the privileges to write stored procedures because i have created some successfully!
Am i doing something so wrong? I can't figure out what causes the problem, if you have any suggestions i would really appreciate that:)
EDIT: For some reason my procedure got wrong Schema that's why i had that problem! I only dropped the Procedure and create it again and it fixed!!!!
Thanks for your time anyway!
Let me just point out this would be vastly more efficient if you did it as:
UPDATE Person Set Salary_A=(Salary_A + 200)
Where Salary_A<400
No cursor, no looping. It would also be a lot simpler.
Related
I have executed a block of code which generates a simple text file using utl_file package
with a word 'test' and outputs the file to the location in server.
When i run the procedure it compiles successfully but the file is not
generated in the path.
set serveroutput on
declare
l_file utl_file.file_type;
l_dir varchar2(500):='WMS_IFILEOUT';
l_file_name varchar2(500):='test.txt';
begin
l_file :=utl_file.fopen(l_dir,l_file_name,'w',32767);
utl_file.put_line(l_file,'test123');
utl_file.fclose(l_file);
end;
The path and directory are available in the dba_directories
and read and write privileges are available on it.
I noticed that when i print
show parameter utl_file
then no values are displayed alongside to it.
Do I have to set this parameter in order to generate the files in the server path.
If so, can you please tell how to set it.
Thanks
I tried code you posted; the only modification was to rename directory).
SQL> DECLARE
2 l_file UTL_FILE.file_type;
3 l_dir VARCHAR2 (500) := 'DPDIR';
4 l_file_name VARCHAR2 (500) := 'test.txt';
5 BEGIN
6 l_file :=
7 UTL_FILE.fopen (l_dir,
8 l_file_name,
9 'w',
10 32767);
11 UTL_FILE.put_line (l_file, 'test123');
12 UTL_FILE.fclose (l_file);
13 END;
14 /
PL/SQL procedure successfully completed.
SQL>
Result: file is here:
So ... no, there's nothing else you should do. Everything you wrote seems to be just fine (from my point of view).
You said something about "show parameter utl_file" - what is that, exactly? UTL_FILE is a package, and you have to have EXECUTE privilege on it. You already have it, otherwise procedure wouldn't work at all.
I have a stored procedure that only sums and retrieves data with SELECT statements ( by using other stored procedures ). There is no update or insert at all in these stored procedures and of course all of involved data are static. This main stored procedure returns double. The weird thing is if I execute it a couple of times, usually after 3 - 4 times, the results are different from the first 3 - 4 results then it stays like that although I keep executing it.
I thought its because of computer precision problem, but the results are still under 1 million and the difference can be up to 4 to 8.
The problem is most likely here:
IF (FOUND) THEN
vSaldo := vRecSearchSaldoAwal.balance;
RAISE NOTICE 'Balance Adjustment: %', vRecSearchSaldoAwal.balance;
...
SELECT (_dateStart - INTERVAL '1 day'), NULL, NULL, vSaldo, TX_STOCKADJ, 'Saldo Sebelumnya' INTO vRetval;
RETURN NEXT vRetval;
ELSEIF (NOT FOUND) THEN
vSaldo := SumQtyBeginningBal(_idproduct, _idGudang);
...
The phrase ELSEIF (NOT FOUND) THEN looks at the FOUND value which has been set by the last SELECT statement inside the IF/IFELSE block. You probably want to put a simple ELSE instead.
I am getting no data found error while looping over an array. The execute immediate has data, but the forall loop is giving no data found error and not able to iterate over the collection.
Please find the code below. code_arr.FIRST seems to have some issue. Table has data and executing sql gives data on editor. Could you please help.
create or replace PACKAGE TEST AS
FUNCTION TEST RETURN NUMBER;
END;
create or replace PACKAGE BODY TEST AS
FUNCTION TEST RETURN NUMBER
IS
TYPE typ_varchar IS TABLE OF VARCHAR2 (1000) INDEX BY BINARY_INTEGER;
lv_statement VARCHAR2 (1000);
code_arr typ_varchar;
var1 varchar(1000);
BEGIN
lv_statement := 'SELECT lnm.code FROM employee lnm';
EXECUTE IMMEDIATE lv_statement BULK COLLECT
INTO code_arr;
FORALL ix1 IN code_arr.FIRST .. code_arr.LAST SAVE EXCEPTIONS
SELECT code_arr(ix1) into var1 FROM DUAL;
RETURN 1;
END;
END;
Thanks in advance for your help.
Mathew
FORALL is meant for bulk DML and not for looping through data. The syntax diagram shows this:
To be pedantic, SELECT is a form of DML, although it's usually considered separate from commands that modify objects. That might be why the original code sort of works but throws an error at run time instead of at compile time.
If all you need to do is loop through data, just use a cursor for loop like this. Oracle automatically uses bulk collect for these types of loops:
begin
for employees in
(
SELECT lnm.code FROM employee lnm
) loop
--Do something here.
null;
end loop;
end;
/
Hi, everybody.
I am new to PL/SQL and Oracle Databases.
I need to read/write file that exists on server so i'm using utl_file.fopen('/home/tmp/','text.txt','R') but Oracle shows error 'invalid directory path'.
Main problem is that i have only user privileges, so i cant use commands like create directory user_dir as '/home/temp/' or view utl_file_dir with just show parameter utl_file_dir;
I used this code to view utl_file_dir:
SQL> set serveroutput on;
SQL> Declare
2 Intval number;
3 Strval varchar2 (500);
4 Begin
5 If (dbms_utility.get_parameter_value('utl_file_dir', intval,strval)=0)
6 Then dbms_output.put_line('value ='||intval);
7 Else dbms_output.put_line('value = '||strval);
8 End if;
9 End;
10 /
and output was 'value = 0'.
I google'd much but didnt find any solution of this problem, so i'm asking help here.
To read file i used this code:
declare
f utl_file.file_type;
s varchar2(200);
begin
f := utl_file.fopen('/home/tmp/','text.txt','R');
loop
utl_file.get_line(f,s);
dbms_output.put_line(s);
end loop;
exception
when NO_DATA_FOUND then
utl_file.fclose(f);
end;
If you do not have permission to create the directory object (and assuming that the directory object does not already exist), you'll need to send a request to your DBA (or someone else that has the appropriate privileges) in order to create a directory for you and to grant you access to that directory.
utl_file_dir is an obsolete parameter that is much less flexible than directory objects and requires a reboot of the database to change-- unless you're using Oracle 8.1.x or you are dealing with a legacy process that was written back in the 8.1.x days and hasn't been updated to use directories, you ought to ignore it.
I wanted to check my monthly payroll in which there are employee salary along with other detail.
I have created a PL/SQL block but when I place my condition for checking of existing employee id with another table some return null value and hence my table does not go further.
set serveroutput on
declare
emp_id NUMBER :=&emp;
temp NUMBER;
begin
select nvl(employee_id,10) into temp FROM bhavya_temp where bhavya_temp.employee_id=emp_id;
dbms_output.put_line(temp);
if temp is NULL
then
dbms_output.put_line('employee ID does not exist');
else
dbms_output.put_line('bye');
end if;
end;
When I enter employee id 1 or 2 which exist in table the result is
anonymous block completed
1
bye
When I enter 3 or more which is not there
Error report:
ORA-01403: no data found
ORA-06512: at line 6
01403. 00000 - "no data found"
*Cause:
*Action:
Thanks for help in advance.
I've never written any PL/SQL, but a very similar error is reported here.
It looks like you can handle the problem by placing the SELECT ... INTO portion inside of a BEGIN ... EXCEPTION .. END block.
Hope this helps.
It would be helpful to have the create table statements with some example data, so that the problem can be reproduced.
To the question : If the row with the ID does not exist vou get the ORA-1403 . There is no data, there is no NULL to convert. Oracle does not dream a row up for you.
Wrap your select stament in an exception block and catch the 'no data found' exception, and act accordingly