[英]Oracle SQL: Insert selected values as well as next value from sequence
這似乎是一件非常簡單的事情,但它似乎並不像我想象的那樣工作......
假設我有一些任意映射表,例如:
+--------+--------+
| 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;
這樣做的正確方法是什么?
您的第三種方法是正確的,並且有效(具有一致的列名):
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
則最有可能是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
使用似乎沒有用的合成密鑰。 (而且我不確定在技術上保證訂單會被保留;主要是並行處理的現實問題)。
您也可以在over()
子句中使用 @Artbaji 的方法和order by
,但是您需要確保您的序列遞增超過生成的值。
INSERT INTO my_logging_table(rid, letter, colour)
select row_number() over(), letter, color from my_mapping_table;
希望這會有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.