sql server触发器 子查询返回值不止一个 如何解决?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sql server触发器 子查询返回值不止一个 如何解决?相关的知识,希望对你有一定的参考价值。

例如,插入两名学生的记录各一条插入某表中,触发器便无法执行。

参考技术A 你说的是
SELECT ...... FROM inserted; 返回多行的情况么?

--假设这个A是主表

CREATE TABLE A(
AID INT IDENTITY(1, 1) PRIMARY KEY,
money INT
);

-- 假设这个B是 日志表, 负责记录 A表 发生的变化。
CREATE TABLE B(
BID INT IDENTITY(1, 1) PRIMARY KEY,

AID INT,
money INT
);
go

-- 假设这个C也是日志表, 负责记录 A表 发生的变化。

-- 但是这个C表是用于演示 不正确使用的例子。

CREATE TABLE C(
CID INT IDENTITY(1, 1) PRIMARY KEY,
AID INT,
money INT
);
go

-- 测试的存储过程

-- 当 A 表 插入 / 更新 / 删除的时候i, 都触发。

CREATE TRIGGER AfterA
ON A
FOR INSERT,UPDATE,DELETE
AS
DECLARE @aid INT, @money INT;
BEGIN

IF EXISTS(SELECT 1 FROM inserted) AND NOT EXISTS(SELECT 1 FROM deleted)
BEGIN
-- 插入触发.
-- 正确的使用.
INSERT INTO B
SELECT
inserted.aid,
inserted.money
FROM
inserted;

-- 不正确的使用.
SELECT @aid = aid, @money = money FROM inserted;
INSERT INTO C VALUES ( @aid, @money);
END;

IF EXISTS(SELECT 1 FROM inserted) AND EXISTS(SELECT 1 FROM deleted)
BEGIN
-- 更新触发.
-- 正确的使用.
INSERT INTO B
SELECT
inserted.aid,
inserted.money - deleted.money
FROM
inserted, deleted
WHERE
inserted.AID = deleted.AID;

-- 不正确的使用.
SELECT @aid = aid, @money = money FROM inserted;
SELECT @money = @money - money FROM deleted;
INSERT INTO C VALUES ( @aid, @money);
END;

IF NOT EXISTS(SELECT 1 FROM inserted) AND EXISTS(SELECT 1 FROM deleted)
BEGIN
-- 删除触发
-- 正确的使用.
INSERT INTO B
SELECT
deleted.aid,
0 - deleted.money
FROM
deleted;

-- 不正确的使用.
SELECT @aid = aid, @money = 0 - money FROM deleted;
INSERT INTO C VALUES ( @aid, @money);
END;
END;
go

-- 一条SQL语句,插入一条数据
INSERT INTO A VALUES (100);

-- 一条SQL语句,插入多条数据
INSERT INTO A
SELECT 10
UNION ALL SELECT 20;
GO

-- 一条SQL语句,更新一条数据
UPDATE A SET money = money - 50 WHERE AID = 1;

-- 一条SQL语句,更新多条数据
UPDATE A SET money = money + 50 WHERE AID != 1;
GO

-- 一条SQL语句,删除一条数据
DELETE FROM A WHERE AID = 1;

-- 一条SQL语句,删除多条数据
DELETE FROM A WHERE AID != 1;
GO

SELECT * FROM B
GO
BID AID money
----------- ----------- -----------
1 1 100
2 3 20
3 2 10
4 1 -50
5 3 50
6 2 50
7 1 -50
8 3 -70
9 2 -60

(9 行受影响)

SELECT * FROM C
go
CID AID money
----------- ----------- -----------
1 1 100
2 2 10
3 1 -50
4 2 30
5 1 -50
6 2 -60

(6 行受影响)

这里, AID = 3 的数据,没有被触发器处理。本回答被提问者和网友采纳
参考技术B where in (子查询)

SQL Server:子查询返回多于1个值

我有两个表一个包含的表

a b c d e f

和表二包含

b c d e f g h i j k l

我想显示表二中的数据,不应该在表一中使用数据(k l)这里应该打印值k and l

在我的例子中,我写了查询

select comarea from companyarea where comarea !=(select area from companyallot where comname='24' and zone='west' and location='mumbai')

但错误即将来临

消息512,级别16,状态1,行1子查询返回的值超过1。当子查询跟随=,!=,<,<=,>,> =或子查询用作表达式时,不允许这样做。

在我的例子中,我想使用名为companyallot的表中未使用的区域

答案
In Where condition "=" operator will deal with single value, "in" operator will deal with multiple values. So instead of using != use "not in" operator as below.
SELECT comarea FROM companyarea 
     WHERE comarea NOT IN
     (SELECT area FROM companyallot WHERE comname='24' AND zone='west' AND      
     location='mumbai')
另一答案

!=算子替换NOT IN

SELECT COMAREA FROM COMPANYAREA WHERE COMAREA NOT IN  (
        SELECT AREA
        FROM COMPANYALLOT
        WHERE COMNAME = '24'
            AND ZONE = 'WEST'
            AND LOCATION = 'MUMBAI'
        )
另一答案

只要子查询没有返回NOT IN值,NULL运算符就可以正常工作,但只要子查询中有一个空值,它就会变成梨形。

更安全的选择是使用EXISTS/NOT EXISTS运算符,类似......

select a.comarea 
from companyarea a
where NOT EXISTS (select 1 
                 from companyallot t 
                 where t.comname='24' 
                   and t.zone='west' 
                   and t.location='mumbai'
                   and a.comarea = t.area)
另一答案

你需要做两件事才能让它发挥作用:

- >使用多值运算符NOT IN(OR)IN

- >虽然你的情况没有指定它,但是如果你通过在内部子查询结果中使用NVL来提高NULLS的效果总是好的。

- > NOT EXISTS操作员仍然可以工作

以上是关于sql server触发器 子查询返回值不止一个 如何解决?的主要内容,如果未能解决你的问题,请参考以下文章

SQL server 建立的触发器子查询返回值不唯一,需要用多个返回值如何操作

sqlserver 表 无法更新和删除 子查询返回的值不止一个

SQL问题,子查询返回的值不止一个!

sql 问题子查询返回的值不止一个。

sql 子查询返回的值不止一个怎么解决?

sql提示子查询返回的值不止一个,求解如何修改,谢谢。