在Oracle的INSERT INTO中进行选择

时间:2018-10-30 19:19:42

标签: sql oracle sql-insert

我有一个带有SELECT的插入物,但是它给了我错误,并且说缺少右括号,但是我不知道在哪里

INSERT INTO DETALLEVENTA(Idventa, IdProducto, Cantidad, Precio_Uni, Descuento)
VALUES((SELECT IdVenta 
        FROM Venta WHERE ROWNUM = 1 
        ORDER BY IdVenta DESC), pIdProducto, pCantidad, pPrecio_Uni, pDescuento);

3 个答案:

答案 0 :(得分:2)

该错误来自ORDER BY IdVenta DESC,这是语句中当时所预期的错误。如果在values子句中使用子查询,则它必须返回单个值,并且对单个值进行排序没有多大意义。 (这是更普遍的规则,尽管在某些地方允许但忽略了。)

由于您似乎拥有ROWNUM的顺序,因此无论如何您都需要另一级子查询:

INSERT INTO DETALLEVENTA(Idventa, IdProducto, Cantidad, Precio_Uni, Descuento)
VALUES((
  SELECT IdVenta 
  FROM (
    SELECT IdVenta 
    FROM Venta
    ORDER BY IdVenta DESC
  )
  WHERE ROWNUM = 1
  ), pIdProducto, pCantidad, pPrecio_Uni, pDescuento);

如果您只是这样做,则暂时忽略它在values子句中

SELECT IdVenta 
FROM Venta
WHERE ROWNUM = 1 
ORDER BY IdVenta DESC

然后首先应用rownum过滤器,然后对单行进行排序,这毫无意义。您实际获得的行是不确定的-它取决于优化程序执行查询的方式,甚至在同一查询的调用之间也可能有所不同。

您真正想要的是:

SELECT IdVenta 
FROM (
  SELECT IdVenta 
  FROM Venta
  ORDER BY IdVenta DESC
)
WHERE ROWNUM = 1

首先对整个结果集进行排序,然后在外部查询中应用rownum过滤器。这样操作意味着您将获得期望的IdVenta,最后订购的那个。

因此,您需要将相同的子查询作为自己的子查询嵌入到values子句中。

可能有更好的方法可以做到这一点;您似乎正在PL / SQL块中运行此命令,因此您可以一次执行该查询并将其存储在一个变量中。从12c开始,还有其他方法可以获取“顶部”行。或者,您可以通过更改为{Barbaros显示的insert .. select来跳过子查询和values子句。

答案 1 :(得分:2)

您可以这样使用:

INSERT INTO DETALLEVENTA(Idventa, IdProducto, Cantidad, Precio_Uni, Descuento)
SELECT *
  FROM
  (
   SELECT IdVenta,pIdProducto, pCantidad, pPrecio_Uni, pDescuento 
     FROM Venta 
    ORDER BY IdVenta DESC
   )
  WHERE ROWNUM = 1;

答案 2 :(得分:0)

别名应该解决问题的子查询