如何解决如何使用条件和联接基于SELECT子查询更新SQL列?
假设我有2张桌子,如下所示:
- 表1(产品)包含有关产品的所有信息
- ProID:代表产品ID主键
- UnitType:产品的单位度量
- Pkg:每箱产品的包装数量
- 表2(Products_stock)包含有关产品数量和包装数量的所有信息
- NoPkg:根据(Products_stock.Qty_on_hand / Products.Pkg和Products_stock.Qty_on_hand%Products.Pkg以及其他一些条件)计算的每种产品的包装总数
目的与问题
每当我对Products_stock表中的Qty_on_hand或Products表中的Pkg进行更改时,我都希望更新NoPkg列中的每一行。我计划通过在删除,插入,更新时使用触发器来实现这一目标,但是我在sql语句方面苦苦挣扎
我已经尝试过:
UPDATE dbo.Products_stock SET
NoPkg = (
SELECT (CASE WHEN (dbo.Products_stock.Qty_on_hand / dbo.Products.Pkg) = 0 THEN '' WHEN ((dbo.Products_stock.Qty_on_hand / dbo.Products.Pkg) <> 0) AND ((dbo.Products_stock.Qty_on_hand % dbo.Products.Pkg) > 0))) THEN CONVERT([nvarchar] (4),dbo.Products_stock.Qty_on_hand / dbo.Products.Pkg) +' boxes + ' + CONVERT([nvarchar](4),dbo.Products_stock.Qty_on_hand % dbo.Products.Pkg) +' ' + Products.UnitType WHEN((dbo.Products_stock.Qty_on_hand / dbo.Products.Pkg <> 0) AND(dbo.Products_stock.Qty_on_hand % dbo.Products.Pkg = 0)) THEN CONVERT([nvarchar] (4),dbo.Products_stock.Qty_on_hand / dbo.Products.Pkg) +' boxes ' ELSE '' END)
FROM dbo.Products_stock
LEFT OUTER JOIN dbo.Products ON dbo.Products_stock.product_id = dbo.Products.ProductID
WHERE dbo.Products.ProductID = dbo.Products_stock.product_id
)
我遇到以下错误:
子查询返回了多个值。当子查询遵循=,!=,,> =或将子查询用作表达式时,不允许这样做。
我的问题是如何解决此问题?还有什么建议比使用触发器更好的方法来更新Qty_on_hand或NoPkg?因为我是新来的,而且是一种自学成才的人,所以我以前没有开发软件的经验。
解决方法
如果您并非真正希望每次都更新整个表(这不是最佳实践),请首先构建产生正确结果的查询,然后将其转换为更新。
在开始之前,出于多种原因,它的最佳实践是在查询中使用表别名,而对于此类更新,则需要使用它们。所以我添加了它们。
假设您的查询正在运行,您可以按以下步骤进行操作:
SELECT
CASE
WHEN dbo.Products_stock.Qty_on_hand / dbo.Products.Pkg = 0 THEN ''
WHEN dbo.Products_stock.Qty_on_hand / dbo.Products.Pkg <> 0 AND dbo.Products_stock.Qty_on_hand % dbo.Products.Pkg > 0 THEN CONVERT([nvarchar] (4),dbo.Products_stock.Qty_on_hand / dbo.Products.Pkg) +' boxes + ' + CONVERT([nvarchar](4),dbo.Products_stock.Qty_on_hand % dbo.Products.Pkg) +' ' + Products.UnitType WHEN((dbo.Products_stock.Qty_on_hand / dbo.Products.Pkg <> 0) AND(dbo.Products_stock.Qty_on_hand % dbo.Products.Pkg = 0)) THEN CONVERT([nvarchar] (4),dbo.Products_stock.Qty_on_hand / dbo.Products.Pkg) +' boxes '
ELSE '' END
FROM dbo.Products_stock PS
LEFT JOIN dbo.Products P ON P.ProductId = PS.product_id;
转换为:
UPDATE PS SET
NoPkg =
CASE
WHEN dbo.Products_stock.Qty_on_hand / dbo.Products.Pkg = 0 THEN ''
WHEN dbo.Products_stock.Qty_on_hand / dbo.Products.Pkg <> 0 AND dbo.Products_stock.Qty_on_hand % dbo.Products.Pkg > 0 THEN CONVERT([nvarchar] (4),dbo.Products_stock.Qty_on_hand / dbo.Products.Pkg) +' boxes '
ELSE '' END
FROM dbo.Products_stock PS
LEFT JOIN dbo.Products P ON P.ProductId = PS.product_id;
我建议在每个表上都有一个触发器,并将您的更新限制为已更改的行,例如
-- Inside trigger on dbo.Products_stock
UPDATE PS SET NoPkg =
CASE
WHEN dbo.Products_stock.Qty_on_hand / dbo.Products.Pkg = 0 THEN ''
WHEN dbo.Products_stock.Qty_on_hand / dbo.Products.Pkg <> 0 AND dbo.Products_stock.Qty_on_hand % dbo.Products.Pkg > 0 THEN CONVERT([nvarchar] (4),dbo.Products_stock.Qty_on_hand / dbo.Products.Pkg) +' boxes '
ELSE '' END
FROM dbo.Products_stock PS
LEFT JOIN dbo.Products P ON P.ProductId = PS.product_id
WHERE PS.product_id in (SELECT product_id from Inserted UNION ALL SELECT product_id from Deleted);
-- Inside trigger on dbo.Products
UPDATE PS SET NoPkg =
CASE
WHEN dbo.Products_stock.Qty_on_hand / dbo.Products.Pkg = 0 THEN ''
WHEN dbo.Products_stock.Qty_on_hand / dbo.Products.Pkg <> 0 AND dbo.Products_stock.Qty_on_hand % dbo.Products.Pkg > 0 THEN CONVERT([nvarchar] (4),dbo.Products_stock.Qty_on_hand / dbo.Products.Pkg) +' boxes '
ELSE '' END
FROM dbo.Products_stock PS
LEFT JOIN dbo.Products P ON P.ProductId = PS.product_id
WHERE P.product_id in (SELECT ProductId from Inserted UNION ALL SELECT ProductId from Deleted)
我想知道您是否需要LEFT JOIN
还是更适合使用INNER JOIN
。
注意:如果您有充分的理由,我只会在触发器中更新NoPkg
,否则,我会在需要时在查询中计算它。
您可以执行以下操作:
UPDATE PS
SET NoPkg = (CASE WHEN (dbo.Products_stock.Qty_on_hand / dbo.Products.Pkg) = 0 THEN '' WHEN ((dbo.Products_stock.Qty_on_hand / dbo.Products.Pkg) <> 0) AND ((dbo.Products_stock.Qty_on_hand % dbo.Products.Pkg) > 0))) THEN CONVERT([nvarchar] (4),dbo.Products_stock.Qty_on_hand / dbo.Products.Pkg) +' boxes ' ELSE '' END)
FROM dbo.Products_stock PS
LEFT OUTER JOIN dbo.Products P ON PS.product_id = P.ProductID
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。