Oracle SQL:插入所选值以及序列中的下一个值

时间:2016-04-21 14:51:40

标签: sql oracle oracle11g

我使用的是Oracle Database 11g,PL / SQL和SQL开发人员。

这似乎很简单,但它似乎并没有像我想的那样工作......

假设我有一些任意的映射表,例如:

+--------+--------+
| Letter | Color  |
+--------+--------+
| N      | Yellow |
+--------+--------+
| P      | Orange |
+--------+--------+
| Q      | Violet |
+--------+--------+
| A      | Green  |
+--------+--------+
| C      | Blue   |
+--------+--------+
| F      | Red    |
+--------+--------+ 

我已经创建了一个空白日志记录表,用于跟踪此映射表随时间的变化。

目前这个日志记录表是空的,我想用数据初始化它,所以它看起来像这样:

+-----+------+-------+--------+--------+
| RID | blah | blahh | Letter | Color  |
+-----+------+-------+--------+--------+
| 1   |      |       | N      | Yellow |
+-----+------+-------+--------+--------+
| 2   |      |       | P      | Orange |
+-----+------+-------+--------+--------+
| 3   |      |       | Q      | Violet |
+-----+------+-------+--------+--------+
| 4   |      |       | A      | Green  |
+-----+------+-------+--------+--------+
| 5   |      |       | C      | Blue   |
+-----+------+-------+--------+--------+
| 6   |      |       | F      | Red    |
+-----+------+-------+--------+--------+ 

我知道我能做到:

INSERT INTO my_logging_table(LETTER, COLOR)
SELECT letter, color FROM my_mapping_table; 

如果RID是一个不可为空的值,那么我需要将其与所选的颜色/字母值一起插入? (而且我不能放弃限制,比如说)

这样的事情给了我一个ORA-00926: missing VALUES keyword

INSERT INTO my_logging_table(rid, letter, color)
mysequence.nextval, SELECT letter, color, FROM my_mapping_table; 

这给了我ORA-00947: Not enough values

insert into my_logging_table(rid, letter, color)  
values mySequence.nextval, select letter, color from my_mapping_table; 

最后,这个认可给了我:ORA-02287: sequence number not allowed here

insert into my_logging_table(rid, letter, color)  
select mySequence.nextval, letter, color from my_mapping_table; 

这样做的正确方法是什么?

基本上,我如何进行包含一些选定值的插入,以及一些静态或序列值?

2 个答案:

答案 0 :(得分:0)

您的第三种方法是正确的,并且有效(具有一致的列名称):

create table my_mapping_table (letter varchar2(1), color varchar2(10));
insert into my_mapping_table (letter, color) values ('N', 'Yellow');
insert into my_mapping_table (letter, color) values ('P', 'Orange');
insert into my_mapping_table (letter, color) values ('Q', 'Violet');
insert into my_mapping_table (letter, color) values ('A', 'Green');
insert into my_mapping_table (letter, color) values ('C', 'Blue');
insert into my_mapping_table (letter, color) values ('F', 'Red');

create table my_logging_table (rid number, foo number, bar varchar2(10),
  letter varchar2(1), color varchar2(10));

create sequence mysequence;

insert into my_logging_table(rid, letter, color)  
select mySequence.nextval, letter, color from my_mapping_table; 

select * from my_logging_table;

       RID        FOO BAR        L COLOR    
---------- ---------- ---------- - ----------
         1                       N Yellow    
         2                       P Orange    
         3                       Q Violet    
         4                       A Green     
         5                       C Blue      
         6                       F Red       

如果您使用的insert all语法不允许序列引用,则会出现该错误:

insert all into my_logging_table(rid, letter, color)  
select mySequence.nextval, letter, color from my_mapping_table;

Error report -
SQL Error: ORA-02287: sequence number not allowed here
02287. 00000 -  "sequence number not allowed here"
*Cause:    The specified sequence number (CURRVAL or NEXTVAL) is inappropriate
           here in the statement.
*Action:   Remove the sequence number.

如果您的查询包含group by子句或order by子句或其他各种内容,您也会看到此内容;你没有表现出来。

如果您单独测试查询,则最有可能order by。将任何顺序应用于生成的ID并没有任何意义,但如果您确实想要出于某种原因(可能基于时间戳),那么您需要使用子查询并参考中的顺序外部查询:

insert into my_logging_table(rid, letter, color)
select mySequence.nextval, letter, color from (
  select letter, color from my_mapping_table
  order by letter
); 

select * from my_logging_table;

       RID        FOO BAR        L COLOR    
---------- ---------- ---------- - ----------
         1                       A Green     
         2                       C Blue      
         3                       F Red       
         4                       N Yellow    
         5                       P Orange    
         6                       Q Violet    

使用合成键但看起来并不实用。 (而且我不确定技术上是否保证订单会被保留;主要是并行处理的实际问题)。

你也可以在order by子句中使用{Artbaji的方法over(),但是你需要确保你的序列增加超过生成的值

答案 1 :(得分:0)

INSERT INTO my_logging_table(rid,letter,color)从my_mapping_table选择row_number()over(),letter,color;

希望这有帮助。