从临时表插入

Inserting from a temporary table

提问人:Kevin 提问时间:8/24/2012 最后编辑:Kevin 更新时间:8/24/2012 访问量:308

问:

我有两张表,还有.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
);

我想从中获取一些 ID 并将它们放入 .sprocketscogs

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

如果我将最后一行更改为 ,则没有错误,因此我知道问题一定出在 insert 语句中,而不是在临时表的声明中。select id from sprocketsRequiringCogs

单行插入语句有效,多行插入语句不起作用。我看到的唯一区别是后者是从临时表中获取其值的。

为什么我不能插入临时表中的行?

SQL 甲骨文11g

评论

1赞 Justin Skiles 8/24/2012
请不要在查询中使用。*

答:

0赞 purplesoft 8/24/2012 #1
 insert into cogs (Id) select Id from sprocketsRequiringCogs 

评论

0赞 purplesoft 8/24/2012
检查类型...创建临时表服务器时,请指定类型本身。SQL语句正确。
0赞 Kevin 8/24/2012
您的意思是我必须为临时表中的每一列指定类型吗?我该怎么做?我查看了 WITH 的文档,但我不清楚如何为它们提供类型。
0赞 purplesoft 8/24/2012
铸造它...在 mssq cast(id as int) 或 convert(int, id) 中
0赞 Alexander Tokarev 8/24/2012 #2

尝试用内联视图替换 WITH 子句,即在 from (select) 中使用 select 语句。

评论

0赞 Kevin 8/24/2012
如果你的意思是我可以使用嵌套的 select 语句而不是临时表,你是对的。但是如果可能的话,我想保留我的小临时表。他们减少了大量的水平滚动。
0赞 Alexander Tokarev 8/24/2012
是的,我愿意。如果目标是摆脱水平滚动,你是对的,但如果你想得到有效的sql,替换将是最好的解决方案
3赞 ekholm 8/24/2012 #3

这是一个猜测,我现在没有可能尝试一下,但这可能有效:

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

评论

0赞 Kevin 8/24/2012
嗯,这行得通!不过,我想知道为什么?也许块必须紧接在语句之前?我以为你可以把它们放在任何地方......withselect
0赞 LittleBobbyTables - Au Revoir 8/24/2012
@Kevin - 根据此链接 (psoug.org/reference/with.html) 中的示例,似乎必须出现在您的第一个子句之前。WITH with CONNECT BYinsert into cogsWITH
0赞 ekholm 8/24/2012
@Kevin:是的,我认为你是对的,只有在后面跟着 才能使用 ,见 http://www.morganslibrary.org/reference/with.htmlWITHSELECT