2012-08-23 138 views
3

我有兩個表格,sprocketscogs從臨時表格插入

create table sprockets(
    id NUMBER 
); 

INSERT into sprockets VALUES (4); 
INSERT into sprockets VALUES (8); 
INSERT into sprockets VALUES (15); 
INSERT into sprockets VALUES (16); 
INSERT into sprockets VALUES (23); 
INSERT into sprockets VALUES (42); 

create table cogs(
    id NUMBER 
); 

我想從sprockets採取一些IDS並付諸cogs

insert into cogs select id from sprockets s where s.id < 40 and MOD(s.id, 3) != 0; 

這增加鏈輪4,8,16,23,以按預期cogs

4 rows inserted 

隨着我的鏈輪製造業務的增長,確定哪些鏈輪需要齒輪的業務邏輯將變得更加複雜。所以我想用一系列臨時表格來過濾非候選鏈輪。我相信這比沒有評論的單線聲明更可維持。

--sprockets with ids greater than 40 are too big to frob, 
--so it's impossible to weld a cog to them 
with frobbableSprockets as(
    select id from sprockets where sprockets.id < 40 
), 

--non-greppable sprockets have built-in harmonic oscillators, 
--so cogs are not required 
greppableFrobbableSprockets as(
    select id from frobbableSprockets f where MOD(f.id,3) != 0 
), 

--not pictured: more filtering using arcane business logic, 
--including but not limited to: 
--whether it is raining on a tuesday, 
--and if the moon is in the seventh house. 

--sprockets with ids less than 3 are from the legacy system and already have cogs 
sprocketsRequiringCogs as(
    select id from greppableFrobbableSprockets f where f.id > 3 
) 

insert into cogs select id from sprocketsRequiringCogs 

此代碼相對可讀,但不幸的是它不起作用!

insert into cogs select id from sprocketsRequiringCogs 
Error at Command Line:18 Column:2 
Error report: 
SQL Error: ORA-00928: missing SELECT keyword 

如果我改變最後一行select id from sprocketsRequiringCogs,沒有錯誤,所以我知道這個問題必須在INSERT語句而不是在臨時表的聲明。

單行插入語句起作用,多行插入語句不起作用。我看到的唯一區別是後者從臨時表中獲取其值。

爲什麼我無法從臨時表中插入行?

+1

請不要在查詢中使用'*'。 –

+0

好點,我把它們拿出來了。 – Kevin

回答

3

這是一個猜測,我沒有可能去嘗試它的權利,但可能這可能是工作:

insert into cogs 
with frobbableSprockets as(
    select * from sprockets where sprockets.id < 40 
), 
... 
select * from sprocketsRequiringCogs 
+0

嗯,這個工程!但我想知道爲什麼?也許'帶'塊必須立即在'select'語句之前?我以爲你可以把它們放在任何地方...... – Kevin

+0

@Kevin - 基於這個鏈接中的WITH WITH CONNECT BY的例子(http://psoug.org/reference/with.html),它似乎是'insert into cogs '必須在你的第一個'WITH'子句之前出現。 – LittleBobbyTables

+0

@Kevin:是的,我認爲你說得對,'WITH'只能在後面跟SELECT時使用,參見[http://www.morganslibrary.org/reference/with.html](http:/ /www.morganslibrary.org/reference/with.html) – ekholm

0
insert into cogs (Id) select Id from sprocketsRequiringCogs 
+0

對不起,不適合我。 '再次丟失SELECT關鍵字'。 – Kevin

+0

檢查類型...當您創建臨時表服務器分配類型本身。 SQL語句是正確的。 – innovia

+0

你的意思是我必須爲臨時表中的每一列指定類型嗎?我怎麼做?我查看了[WITH](http://psoug.org/reference/with.html)的文檔,但我不清楚如何爲它們提供類型。 – Kevin

0

嘗試用inline視圖替換WITH子句,即在from(select)中使用您的select語句。

+0

如果您的意思是我可以使用嵌套select語句而不是臨時表,那麼您是對的。但如果可能的話,我想保留我的小臨時表。他們減少了很多水平滾動。 – Kevin

+0

是的,我喜歡。如果目標是擺脫水平滾動你是對的,但如果你想獲得SQL的工作替代將是最好的解決方案 –