Reputation: 315
I try to generate sample data, therefore I would like to insert multiple rows into my Oracle table. Column values should be in between 1-5 and should be totally random. I need 20 random whole number.
My insert statement:
BEGIN
FOR i IN 163 .. 400 LOOP
INSERT ALL INTO results
(student_id,OPN1,OPN2,OPN3,OPN4,AGG1,AGG2,AGG3,AGG4,NEU1,NEU2,NEU3,NEU4,EXT1,EXT2,EXT3,EXT4,CSN1,CSN2,CSN3,CSN4)
VALUES
(i,
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)))
SELECT * FROM DUAL;
END LOOP;
COMMIT;
END;
It works but in one row the numbers are all the same. It is not generating a new random number to every column, just one and insert it to all fields of my table. Why is it happening? You can see it after 102 id row. First inserted row (163 id) is already wrong.
Upvotes: 0
Views: 173
Reputation: 191315
INSERT ALL
has some quirks, but you don't need it here, you can just remove ALL
and the dummy select to make it a simple insert-values statement:
BEGIN
FOR i IN 163 .. 400 LOOP
INSERT INTO results
(student_id,OPN1,OPN2,OPN3,OPN4,AGG1,AGG2,AGG3,AGG4,NEU1,NEU2,NEU3,NEU4,EXT1,EXT2,EXT3,EXT4,CSN1,CSN2,CSN3,CSN4)
VALUES
(i,
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)));
END LOOP;
COMMIT;
END;
/
You don't need PL/SQL either though, you could use a hierarchical query (or recursive CTE) instead of a loop:
INSERT INTO results
(student_id,OPN1,OPN2,OPN3,OPN4,AGG1,AGG2,AGG3,AGG4,NEU1,NEU2,NEU3,NEU4,EXT1,EXT2,EXT3,EXT4,CSN1,CSN2,CSN3,CSN4)
SELECT
level + 162,
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5)),
round(dbms_random.value(1,5))
FROM dual
CONNECT BY level <= 1 + 400 - 163;
or as @MTO suggested, using floor instead of round:
INSERT INTO results
(student_id,OPN1,OPN2,OPN3,OPN4,AGG1,AGG2,AGG3,AGG4,NEU1,NEU2,NEU3,NEU4,EXT1,EXT2,EXT3,EXT4,CSN1,CSN2,CSN3,CSN4)
SELECT
level + 162,
floor(dbms_random.value(1,6)),
floor(dbms_random.value(1,6)),
floor(dbms_random.value(1,6)),
floor(dbms_random.value(1,6)),
floor(dbms_random.value(1,6)),
floor(dbms_random.value(1,6)),
floor(dbms_random.value(1,6)),
floor(dbms_random.value(1,6)),
floor(dbms_random.value(1,6)),
floor(dbms_random.value(1,6)),
floor(dbms_random.value(1,6)),
floor(dbms_random.value(1,6)),
floor(dbms_random.value(1,6)),
floor(dbms_random.value(1,6)),
floor(dbms_random.value(1,6)),
floor(dbms_random.value(1,6)),
floor(dbms_random.value(1,6)),
floor(dbms_random.value(1,6)),
floor(dbms_random.value(1,6)),
floor(dbms_random.value(1,6))
FROM dual
CONNECT BY level <= 1 + 400 - 163;
db<>fiddle (with fewer columns for simplicity).
Upvotes: 2