ORA-00907 缺少右括号问题 - 在插入查询中按顺序选择

Posted

技术标签:

【中文标题】ORA-00907 缺少右括号问题 - 在插入查询中按顺序选择【英文标题】:ORA-00907 Missing right parenthesis issue - select with order by inside insert query 【发布时间】:2012-02-07 11:50:57 【问题描述】:

我正在尝试插入一个表,它对一列使用一个选择语句。下面是我的查询的图示。

INSERT INTO MY_TBL (MY_COL1, MY_COL2)
VALUES (
(SELECT DATA FROM FIR_TABL WHERE ID = 1 AND ROWNUM = 1 ORDER BY CREATED_ON DESC),
1
);

它抛出ORA-00907 Missing right Parenthesis。如果我从中删除ORDER BY,它会按预期工作。但我需要订购它。我该如何解决?

【问题讨论】:

如果您“依赖”插入到 RDBMS 表中的数据顺序,我会质疑您的数据模型。插入顺序应该是无关紧要的,您在查询数据时执行排序。 您认为ORDER BY 在这种情况下会为您做什么? 我举了一个例子,该选择可以有多行。此外,MY_TBL 中有许多列。请检查我的更新。 @Vanathi 你添加了rownum = 1。这将只返回一行。如果您想一次插入多行,只需删除 rownnum 条件(如果限制行,还删除 id),因为 insert into ... select 支持多行插入 我只需要添加一行。我正在使用 order by 获取最新数据并插入它。 【参考方案1】:

当前的两个答案都忽略了这样一个事实,即在同一查询中使用 order byrownum 本质上是危险的。绝对不能保证您将获得所需的数据。如果您想要有序查询的第一行,您必须使用子查询:

insert into my_tbl ( col1, col2 )
select data, 'more data'
  from ( select data
           from fir_tabl
          where id = 1
          order by created_on desc )
 where rownum = 1
       ;

您还可以使用rank 之类的函数以您想要的方法对数据进行排序,但如果您有两个相同的created_on 日期,您最终会得到两个rnk = 1 的值。

insert into my_tbl ( col1, col2 )
select data, 'more data'
  from ( select data
              , rank() over ( order by created_on desc ) as rnk
           from fir_tabl
          where id = 1)
 where rnk = 1
       ;

【讨论】:

这似乎为 Oracle 解决了这个问题。将其转换为使用额外的子查询,并且“缺少右括号”(即使它没有缺少括号)消息消失。谢谢! 在同一个查询中使用 order by 和 rownum 本身就很危险,是否有任何参考资料? 我确信 Tom Kate 会写一些东西@jeromerg,但你应该能够从第一原则中看到它。堆表被存储,因此被检索,未排序。 ORDER BY 子句始终是最后发生的操作。因此,ROWNUM 谓词将在无序集的排序之前使用。您需要先排序,并且由于 SQL 语句的操作顺序,排序必须发生在内部选择中(直到 12c 使用(并且仅使用)FETCH N ROWS 语法)【参考方案2】:

在使用 VALUES 关键字时不要使用 SELECT。改用这个:

INSERT INTO MY_TBL (MY_COL)
SELECT DATA FROM FIR_TABL WHERE ID = 1 ORDER BY CREATED_ON DESC
;

您编辑的查询如下所示:

INSERT INTO MY_TBL (MY_COL1, MY_COL2)
SELECT DATA, 1 FROM FIR_TABL WHERE ID = 1 AND ROWNUM = 1 ORDER BY CREATED_ON DESC
;

【讨论】:

【参考方案3】:

我同意在提取数据时而不是在插入数据时进行排序。

但是,作为一种解决方法,您可以将 ORDER BY 子句与 INSERT 隔离,将整个 SELECT 封装到另一个 SELECT 中。

这样可以避免错误:

INSERT INTO MY_TABLE (
SELECT * FROM (
    SELECT columns
    FROM table
    ORDER BY clause
    )
)

【讨论】:

以上是关于ORA-00907 缺少右括号问题 - 在插入查询中按顺序选择的主要内容,如果未能解决你的问题,请参考以下文章

获取 ORA-00907 的 Oracle 查询:缺少右括号

ORA-00907: 缺少右括号

ORA-00907: 缺少右括号 2

ORA-00907: 缺少右括号 00907. 00000 - “缺少右括号” *原因:*操作:行错误:44 列:30

ORDER BY 与内部查询,给出 ORA-00907 缺少右括号

ORA-00907: 两个子查询的左连接缺少右括号