【问题标题】:The subquery returned more than one value. TSQL子查询返回了多个值。数据库
【发布时间】:2023-01-18 16:36:57
【问题描述】:
CREATE TABLE sales
(id INT PRIMARY KEY IDENTITY, name VARCHAR(30),
percent_part FLOAT, sales FLOAT, sum_bonus DECIMAL);

CREATE TRIGGER TRcointingBonus ON sales 
AFTER UPDATE 
AS BEGIN

DECLARE @sum_bonus FLOAT;
SELECT @sum_bonus = (SELECT ((sales / 100) * percent_part) FROM  sales);
UPDATE sales SET sum_bonus = @sum_bonus

END;

INSERT INTO sales VALUES('staff1', 7.0, 7088, 1);
INSERT INTO sales VALUES('staff2', 3.5, 20590, 1);
INSERT INTO sales VALUES('staff3', 10.5, 6089, 1);

UPDATE sales SET sales = 7088 WHERE id=1;

我创建一个表和一个触发器,对于每个UPATE操作,sum_bonus的每一行都会有计算。

问题是在

DECLARE @sum_bonus FLOAT;
SELECT @sum_bonus = (SELECT ((sales / 100) * percent_part) FROM sales);

如果删除FROM sales,则将无法写入变量。能解释一下是什么原因,如何在不放弃变量的情况下解决这个问题?

【问题讨论】:

  • 您确定要读取表中的所有行、计算总奖金然后更新表中的所有行吗?您不想在更新的行上工作吗?旧值在deleted.sales/deleted.percent_part,新值在inserted.sales/inserted.percent_part。但是,您似乎正试图在这里做一些您不应该做的事情。您只是想根据行的值计算行的奖金吗?那么您可能只需要一个计算列。
  • 不要滥用触发器进行简单的计算。计算仅从同一个表的列中获取值,因此不需要触发器。只需在更新命令中进行计算即可。或者让应用程序计算它并将结果写入更新命令。
  • @ThorstenKettner 如果我写UPDATE sales SET sum_bonus = (SELECT (sales / 100) * procent) 一切正常,我的问题是为什么FROM sales 会中断查询。我试图创建另一个表,同样的查询也不起作用

标签: sql tsql


【解决方案1】:

您的实际错误很清楚,您的子查询返回多个值。如果您获取样本数据,并自行运行子查询:

SELECT ((sales / 100) * percent_part) 
FROM  sales

你得到 3 个值:

(No column name)
496.16
720.65
639.345

然后您试图将其分配给一个十进制变量:

DECLARE @sum_bonus FLOAT;
SELECT @sum_bonus = (SELECT ((sales / 100) * percent_part) FROM sales);

因此 SQL Server 不知道您希望存储 3 个值中的哪一个,因此会抛出一个错误 - 清楚地告诉您子查询只能返回一行以避免歧义。

为避免错误,请将子查询更改为返回一行。

话虽如此,您的触发器存在巨大缺陷,它每次都会更新整个表,因为它没有引用 inserteddeleted 内存驻留伪表,并且如上所述,它试图更新整个表的值with 也没有任何意义。

您想要实现的目标可以通过 Computed Column 非常简单地完成,因此您的创建表变成如下所示:

CREATE TABLE sales
(
    id INT PRIMARY KEY IDENTITY, 
    name VARCHAR(30),
    percent_part FLOAT, 
    sales FLOAT, 
    sum_bonus AS (sales * percent_part / 100)
);

无需存储 sum_bonus 并在基础值更改时使用任何类型的代码来更新它,只需存储表达式并在需要时计算它。

Example on db<>fiddle

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-10
    • 1970-01-01
    • 2015-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多