【问题标题】:Insert trigger issue ,subquery returned more than 1 row插入触发器问题,子查询返回超过 1 行
【发布时间】:2014-07-22 09:58:12
【问题描述】:

尝试检查插入的表列 level_name 中输入的值是否与 Levels 表列 level_name 匹配。我的查询返回错误 Subquery returned more than 1 value. 。尝试按照 Dan Guzman 的代码编写代码。

Declare @levelname nvarchar(MAX)= 
( 
 SELECT [LEVEL_NAME] + ' '
 FROM inserted 
 WHERE (select LEVEL_NAME from levels where level_name=(select level_name 
 from  inserted)) IS NULL 
 FOR XML PATH('') 
); 
if @levelname is not null 
BEGIN 
  RAISERROR(); 
END

【问题讨论】:

  • 为什么要使用触发器来强制引用完整性?不确定此触发器适用于哪个表,但这是外键或唯一约束。不要通过这样的代码来做这件事,从长远来看,它会给你带来无尽的痛苦。
  • 我认为是因为我的要求是在日志中记录不匹配的值

标签: sql-server triggers insert


【解决方案1】:

我建议在您的查询中使用 Top 1 或使用以下格式:

IF Exists(SELECT  [LEVEL_NAME]
          FROM inserted i
          INNER JOIN levels l ON l.Level_name = i.Level_name) Begin
  RAISERROR('Your error message',16,1); 
END

IF (SELECT  COUNT(*)
    FROM inserted i
    INNER JOIN levels l ON l.Level_name = i.Level_name)=0 Begin
  RAISERROR('Your error message',16,1); 
END

我建议在 level_name 列上使用 UNIQUE INDEX。为了限制您的用户插入重复的 level_name 值。

【讨论】:

  • 感谢代码,但收到错误An expression of non-boolean type specified in a context where a condition is expected, near ')'.
  • 在 where 子句中添加了 =0 并得到相同的错误 more than 1 row 。更新代码IF Exists(SELECT [GEOLEVEL_NAME] FROM inserted WHERE (select GEOLEVEL_NAME from RIF40_COVARIATES where geolevel_name=(select geolevel_name from inserted)) =0 ) Begin RAISERROR('geolevel name does not exit',16,1); END END
  • 你需要知道插入的表有没有行。使用Exists时不需要加=0
  • 我编辑我的问题。如果你想使用=0,必须从插入的表中获取行数。
  • 仍然收到错误An expression of non-boolean type specified in a context where a condition is expected, near ')'. 这是完整的触发代码:create trigger tr_test on [dbo].[test] instead of insert, update as begin IF Exists(SELECT [LEVEL_NAME] FROM inserted WHERE (select LEVEL_NAME from [dbo].levels where level_name=(select LEVEL_NAME from inserted)) ) Begin RAISERROR('Your error message',16,1); END end
【解决方案2】:

试试这个:

DECLARE @levelname NVARCHAR(MAX)= 
( 
 SELECT [LEVEL_NAME] + ' '
 FROM   inserted 
 WHERE  EXISTS (SELECT LEVEL_NAME FROM levels
                    WHERE  level_name IN (SELECT level_name FROM inserted))
 FOR XML PATH('') 
); 
IF @levelname IS NOT NULL 
BEGIN 
  RAISERROR(); 
END

【讨论】:

  • insert into test(level_name) values('level_medium'),('level_high') 如果 Levels 表中缺少两个级别,则代码有效。如果缺少一个并且存在一个,则不会引发错误。
  • 现在,如果两者都没有丢失,则代码可以工作,但如果缺少一个且存在 1,则代码无效。
猜你喜欢
  • 2021-07-20
  • 2022-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多