I am trying to insert values into a table using a for loop. I can't understand why it isnt working. I am a beginner. Any help would be appreciated.
create or replace procedure valueinput
as i number;
begin
for i in 1..10
loop
man_id number:=&Manager_Id;
man_fname varchar2(100):=&First_Name;
man_lname varchar2(100):=&Last_Name;
emp_id number:=&Employee_ID_Managed;
insert into managerinfo
values (man_id,man_fname,man_lname,emp_id);
i:=i+1;
end loop;
end;
You must declare your variables in the DECLARATION section of your PL/SQL block, right now you're trying to do it in the EXECUTION section.
Also, for a PL/SQL FOR..IN loop, you don't need to declare or increment your index.
Try something like this-
create or replace procedure valueinput
as
man_id number;
man_fname varchar2(100);
man_lname varchar2(100);
emp_id number;
begin
for i in 1..10
loop
man_id :=&Manager_Id;
man_fname :=&First_Name;
man_lname :=&Last_Name;
emp_id :=&Employee_ID_Managed;
insert into managerinfo
values (man_id,man_fname,man_lname,emp_id);
end loop;
end;
It would also be best practice to declare your variable types as the same as the table column that you're inserting into.
For example-
man_id managerinfo.manager_id%TYPE;
Related
I am stuck with this approach not getting. How do I need to go with it.
I have table which as column -> KEYS. This as more then 500+ keys
Like below the data would be :
KEYS
12RTY
UIIJ9
GHSJ8
HJSKI
I should not be making use of cursor need to loop one by one values from column : KEYS to my PLSQL logic
This is how I want to convert that data to comma separated format and used in my loop to read one by one value
(key1,key2,key3....)
My code :
DECLARE
v_name varchar2(10 char);
BEGIN
FOR v_counter in 1..(key1,key2,key3..) LOOP
select NAME into v_name from EMP where KEY=v_counter;
DBMS_OUTPUT.PUT_LINE(v_name)
END;
END;
I would have made use of list_agg but only 10 values can be created as comma separated.
More then that it throws error like exceeded 4000
You can use a cursor:
DECLARE
v_name varchar2(10 char);
BEGIN
FOR v_row IN (SELECT key FROM your_key_table)
LOOP
select NAME into v_name from EMP where KEY=v_row.key;
DBMS_OUTPUT.PUT_LINE(v_name);
END LOOP;
END;
/
But you could combine the two queries into one:
DECLARE
v_name varchar2(10 char);
BEGIN
FOR v_row IN (SELECT e.name
FROM your_key_table ykt
INNER JOIN emp e
ON (ykt.key = e.key)
ORDER BY ykt.key)
LOOP
DBMS_OUTPUT.PUT_LINE(v_row.name);
END LOOP;
END;
/
db<>fiddle here
Instead of using a cursor, you can use BULK COLLECT to store all of the keys into a collection, then loop through that collection selecting and printing the data you are looking for.
DECLARE
TYPE keys_t IS TABLE OF your_schema.key_table.keys%TYPE;
l_keys keys_t;
l_name your_schema.emp.name%TYPE;
BEGIN
SELECT keys
BULK COLLECT INTO l_keys
FROM your_schema.key_table;
FOR i IN 1 .. l_keys.COUNT
LOOP
SELECT NAME
INTO l_name
FROM EMP
WHERE KEY = l_keys (i);
DBMS_OUTPUT.PUT_LINE (l_name);
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL; --No employee exists with that key
END LOOP;
END;
If you are just trying to tie the keys to EMPs, it would probably make more sense to just do a join.
table :
create table emp
(
E_ID number,
E_NAME varchar2(30)
);
select * from emp;
101 name1
102 name2
My code:
declare
v1 varchar2(30) := '101,102';
begin
for i in (select e_id,e_name
from emp
where e_id in (v1)) loop
dbms_output.put_line(i.e_id);
end loop;
end;
/
ISSUE:
Getting ORA -01722:invalid number
Please help to understand this issue and suggest me the solution.
It is syntax error.
E_ID is of number type and you are comparing it will v1 which is varchar2 type.
Welcome to SO. A great place to ask questions: I can see what you're trying to do. Syntactically, you'd be forgiven for trying to query your table using the "IN" clause, but as others have said, this can not be done where you have committed your numeric values into a varchar2. In anycase, an array or a collection, (even if you had created one) it isn't an easy option here. But you do have a variety of solutions open to you:
1/ Place your numbers into an Array and use a condition in your loop and check that e_id forms part of the your array. But in-elegant!
2/ Create a global temporary table and add your numbers in and add the table into your query, specify a join.
3/ Create some dynamic PL/SQL using a Ref Cursor. I've included an example for you below, using your table (emp) and values. In this case, you'd be able to build up your string according to the values you want to query. See below. The varchar2 string: sqlString can be manipulated however you want. Paste into a test-harness and see. Hope it helps
declare
type refCursor is ref cursor;
tableCursor refCursor;
emp_record emp%rowtype;
sqlString varchar2(200);
begin
-- Dynamic SQL statement with placeholder:
sqlString := 'SELECT * FROM emp WHERE e_id in
(101, 102)';
-- Open cursor:
open tableCursor for sqlString;
-- Fetch rows from result set one at a time:
loop
fetch tableCursor
into emp;
exit when tableCursor%notfound;
dbms_output.put_line(emp.e_id);
end loop;
-- Close cursor:
close tableCursor;
end;
I used oracle
I want to declare a procedure that allows me to make insertion in a table
I try with this code without success
CREATE OR REPLACE PROCEDURE ADDSTEP(nbrStep character varying)
is
i integer :=0;
BEGIN
FOR i IN 0..nbrStep LOOP
INSERT INTO mytabletest
VALUES (i);
END LOOP;
END;
I have this error :
PROCEDURE ADDSTEP compiled
Errors: check compiler log
There are multiple issues with your code:
nbrStep character varying
There is no such data type called "character varying" in Oracle. For string you would use VARCHAR2. However, since you want to use it later in the loop for iteration, you need it to be NUMBER.
FOR i IN 0..nbrStep LOOP
You need to iterate from 1 till the boundary.
i integer :=0;
Not needed.
Modify the procedure as:
CREATE OR REPLACE PROCEDURE ADDSTEP(nbrStep NUMBER)
is
i integer :=0;
BEGIN
FOR i IN 0..nbrStep LOOP
INSERT INTO mytabletest
VALUES (i);
END LOOP;
END;
/
Anyway, you entire procedure could be done in a single INSERT SQL. It is called row generator method.
Try,
INSERT INTO mytabletest
SELECT LEVEL FROM DUAL CONNECT BY LEVEL <= 100;
Above, in place of 100, you could use the value of your choice which is the value you are passing as parameter **nbrStep ** in the above procedure.
Strange syntax of input variables. Corrected for Oracle -
CREATE OR REPLACE PROCEDURE addstep(nbrstep IN NUMBER)
IS
BEGIN
FOR i IN 0.. nbrstep
LOOP
INSERT INTO mytabletest
VALUES (i);
END LOOP;
END;
Table abc has the following column
approved_ain
1
2
12
34
i have a procedure
create or replace procedure abc( p_admin varchar2,
p_approved_ain abc.approved_ain)--plsql table in parameter
begin
end;
now when i call this procedure in an anonymous block :-
declare
l_Admin varchar2(100);
l_approved_ain abc.approved_ain;
begin
abc(l_Admin ,l_approved_ain);
commit;
end;
How can i pass values of the approved_ain of plsql table to this anonymous block.? that is i want to test it by passing the values of abc table approved_ain column.......
Answer :
declare
l_Admin varchar2(100);
l_approved_ain abc.approved_ain;
begin
l_approved_ain(1) :=123;
l_approved_ain(2) :=4645;
abc(l_Admin ,l_approved_ain);
commit;
end;
Given the fact that you only want to test, what about just setting the values in the anonymous block:
declare
l_Admin varchar2(100) := 'string';
l_approved_ain abc.approved_ain := ???;
begin
abc(l_Admin ,l_approved_ain);
commit;
end;
Lets create a table first
create table test
(
id number,
name varchar2(20)
);
Now during insert, I want to hold the data into variable first & then dynamically pass the variable into the VALUES clause like this:
declare
v_data varchar2(50);
begin
v_data:='1,sunny';
execute immediate 'insert into test values(v_data)';
commit;
end;
But its showing some errors(Not enough values)...... plz help how to achieve this??
You need to use different variables for each value
declare
v_data1 number
v_data2 varchar2(50);
begin
v_data1 :=1
v_data2 = 'sunny';
insert into test values(v_data1,v_data2);
-- Alternatively insert into test (Name) values (v_data2);
commit;
end;
Table test has two columns. You're only inserting one and not naming which column it is hence "not enough values". So you need:
INSERT INTO test (name) VALUES (data)
or probably better is to put in an ID:
INSERT INTO test (id, name) VALUES (1, data)
or simply:
INSERT INTO test VALUES (1, data)
For this kind of thing though I would use a cursor rather than dynamic SQL (or even inline SQL).
The normal way to pass values into dynamic SQL statements is with bind variables like this:
declare
v_id integer;
v_name varchar2(50);
begin
v_id := 1;
v_name := 'sunny';
execute immediate
'insert into test (id, name) values(:b1, :b2)'
using v_id, v_name;
commit;
end;
That needs one variable per value.
Your approach works, but you need to adjust your query a little:
execute immediate 'insert into test values(' || v_data|| ')';
so that the contents of your v_data variable are actually inserted into the string, not the value "v_data" itself.