在Oracle的INSERT INTO中选择内部



我有一个带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);

错误来自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);

忽略它现在在一个值子句中,如果你刚刚这样做的话:

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开始,还有其他方法可以获得"顶"行。或者,您可以跳过子查询和values子句,如@Barbaros所示,更改为insert .. select

您可以这样使用:

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;

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

最新更新