【问题标题】:how to Iterate through list of ids and insert a record in table for that each id in oracle如何遍历 id 列表并在表中为 oracle 中的每个 id 插入一条记录
【发布时间】:2018-05-14 13:53:01
【问题描述】:

您好,我有一个 ID 列表,例如 1,6,8,9,12,45,67,.... 我想遍历这些 id 并在表中为每个 id 示例插入一条记录-

for each id {
  insert into table_name(user_id, sys_id, crt_tsp) values (nextval,{this value is from above list}, current_timestamp)
}

我的数据库是oracle,我如何在sql中实现这一点?

【问题讨论】:

  • 将该列表放入临时表中。加入。
  • 您是表格中的 id 列表吗?如果是,您可以通过查询来完成,如果不是,您可以创建一个存储过程
  • 这个列表在哪里(一个文件,在某种语言的数组中,在一个表中?)。你打算用哪种语言写这篇文章?

标签: sql oracle stored-procedures plsql


【解决方案1】:

您可以使用集合。 SYS.ODCINUMBERLIST 是一个内置的VARRAY 你可以使用:

SQL Fiddle

Oracle 11g R2 架构设置

CREATE TABLE table_name(
  user_id NUMBER,
  sys_id  NUMBER,
  crt_tsp TIMESTAMP
);

CREATE SEQUENCE sequence_name;

INSERT INTO table_name( user_id, sys_id, crt_tsp) 
SELECT sequence_name.NEXTVAL,
       COLUMN_VALUE,
       current_timestamp
FROM   TABLE( SYS.ODCINUMBERLIST( 1,6,8,9,12,45,67 ) );

查询 1

SELECT * FROM table_name

Results

| USER_ID | SYS_ID |                    CRT_TSP |
|---------|--------|----------------------------|
|       1 |      1 | 2018-05-14 14:14:08.157393 |
|       2 |      6 | 2018-05-14 14:14:08.157393 |
|       3 |      8 | 2018-05-14 14:14:08.157393 |
|       4 |      9 | 2018-05-14 14:14:08.157393 |
|       5 |     12 | 2018-05-14 14:14:08.157393 |
|       6 |     45 | 2018-05-14 14:14:08.157393 |
|       7 |     67 | 2018-05-14 14:14:08.157393 |

或者您可以创建自己的类型:

CREATE TYPE NumberList IS TABLE OF NUMBER;

INSERT INTO table_name( user_id, sys_id, crt_tsp) 
SELECT sequence_name.NEXTVAL,
       COLUMN_VALUE,
       current_timestamp
FROM   TABLE( NumberList( 1,6,8,9,12,45,67 ) );

更新

来自 OP 对另一个答案的评论:

我想从另一个表中获取数字列表

select id from table_name

您可以直接从该表中选择:

INSERT INTO table_name( user_id, sys_id, crt_tsp) 
SELECT sequence_name.NEXTVAL,
       id,
       current_timestamp
FROM   table_name;

【讨论】:

  • 谢谢。我想从另一个表中获取数字列表。例子 。 .....FROM TABLE(NumberList(select id from table_name));但我在 SQL 错误下不断收到错误:ORA-00936: missing expression 00936. 00000 - "missing expression"
【解决方案2】:

补充@MT0的回答,在Oracle 12.2及以上,你甚至不需要TABLEfunction,你可以直接从SYS.ODCINUMBERLIST或者FROM NumberList(1, 6, 8, 9, 12, 45, 67)中选择

INSERT INTO table_name (
    user_id
    ,sys_id
    ,crt_tsp
    )
SELECT sequence_name.NEXTVAL
    ,COLUMN_VALUE
    ,current_timestamp
FROM SYS.ODCINUMBERLIST(1, 6, 8, 9, 12, 45, 67);

如果您可以传递包含在 字符串 中的逗号分隔的数字列表,也可以使用 XMLTABLE(适用于 11g)

INSERT INTO table_name (
    user_id
    ,sys_id
    ,crt_tsp
    )
SELECT sequence_name.NEXTVAL
    ,to_number(COLUMN_VALUE)
    ,current_timestamp
FROM XMLTABLE('1, 6, 8, 9, 12, 45, 67');

【讨论】:

  • 谢谢,我想从另一个表中获取数字列表。例如 ..FROM SYS.ODCINUMBERLIST(从表名中选择 id);但我在 SQL 错误以下不断收到错误:ORA-00936: missing expression 00936. 00000 - "missing expression"
  • @question_tech : “数字列表”,是作为id存储在多行还是一行作为字符串?
【解决方案3】:

这里有一些匿名块的伪代码,可以按照您的要求执行。您需要使用所需的 ID 创建一个临时表。

declare
  cursor c0 is
    select 
    a.id_value,
    b.user_id,
    b.crt_tsp
    from temporary_table a
    join data_table b on b.id_value = a.id_value;

begin
for rec in c0 loop
  insert into table_name (...) values(rec.id_value, rec.user_id, rec.crt_tsp ...);
end loop;
end;

【讨论】:

  • 为什么不直接使用INSERT INTO ... SELECT ... FROM temporary_table 就可以摆脱整个PL/SQL 块、游标和循环?但是,您也可以询问 OP 如何将列表放入临时表中,而您有一个鸡与蛋的问题,这无法解决。
  • 我非常喜欢你的回答。如果没有额外的逻辑,它会更有效。但是您的回答不允许他按照 OP 的要求遍历 ID。我的有。
  • 这将是有用的信息,可以添加到您关于此版本的好处的答案中,而不是更简单的东西 - 您可以在 sn-p 中添加注释,指示您将在何处执行预处理在循环中或一些附加逻辑的简单示例中。
猜你喜欢
  • 1970-01-01
  • 2016-12-26
  • 1970-01-01
  • 2023-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-04
  • 1970-01-01
相关资源
最近更新 更多