簡體   English   中英

Oracle SQL:插入選定的值以及序列中的下一個值

[英]Oracle SQL: Insert selected values as well as next value from sequence

我正在使用 Oracle 數據庫 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; 

這樣做的正確方法是什么?

基本上,如何插入包含一些選定值和一些靜態或序列值的插入?

您的第三種方法是正確的,並且有效(具有一致的列名):

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM