Insert 语句将错误的随机数插入 table Oracle

Insert statement inserts wrong random numbers into table Oracle

我尝试生成示例数据,因此我想将多行插入到我的 Oracle table。列值应介于 1-5 之间,并且应该完全随机。我需要 20 个随机整数。

我的插入语句:

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;

它有效,但在一行中,数字都是相同的。它不会为每一列生成一个新的随机数,只是生成一个并将其插入到我的 table 的所有字段中。为什么会这样?你可以在 102 id 行之后看到它。第一个插入的行 (163 id) 已经是错误的。

INSERT ALL 有一些怪癖,但你不需要它,你可以只删除 ALL 和虚拟 select 使其成为一个简单的插入值语句:

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;
/

不过你也不需要 PL/SQL,你可以使用分层查询(或递归 CTE)而不是循环:

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;

或按照@MTO的建议,使用地板而不是圆形:

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(为简单起见,列数较少)。