【问题标题】:Conversion failed when converting the varchar value '' to data type Bit将 varchar 值 '' 转换为数据类型 Bit 时转换失败
【发布时间】:2020-08-06 03:08:03
【问题描述】:

我正在测试我的插入语句:

insert into Gebruiker
values ('Sonja123', 'Sonja', 'Van der Vliet', 'kastanjelaan 45',NULL, '3771jx', 'Heteren', 'Nederland', '1980-04-01','Pdel42@hotmail.com', 'WEBM1MAMV', 1, 'Poekie', 'wel')

但是每次我尝试测试它时,我都会收到错误:

将 varchar 值“wel”转换为数据类型 Bit 时转换失败。

我的触发器是:

CREATE TRIGGER TR_CHECKVERKOPER
   ON  Gebruiker
   FOR INSERT
AS 
BEGIN
    DECLARE @USER_NAME VARCHAR(70)
    SET @USER_NAME = (SELECT gebruikersnaam FROM INSERTED)

    IF (SELECT Verkoper FROM Gebruiker WHERE gebruikersnaam = @USER_NAME) = 'wel'
    BEGIN
        IF (SELECT COUNT(*) FROM Verkoper WHERE Gebruiker = @USER_NAME) = 0
        BEGIN
            UPDATE Gebruiker SET Verkoper = 'niet' WHERE gebruikersnaam = @USER_NAME    
        END
    END
END
GO

我该如何解决?

【问题讨论】:

  • SQL Server 触发器 101:插入的表可以有多行吗?所以你的触发器从一开始就坏了。
  • 所以要生成错误列 Verkoper 必须是 bit 数据类型。我刚刚测试了自己,这正是发生的事情。把Verkoper改成字符串类型就可以了。
  • 插入的表可以有多行吗?是的
  • ^^^ 但您的代码仅处理 1 行,例如SET @USER_NAME = (SELECT gebruikersnaam FROM INSERTED) 因为一个变量只能包含一个值。
  • 触发器每个 statement 触发一次,而不是 row。如果 insert 语句添加 42 行,则 inserted 将包含 42 行。如果您的触发器绝对不能处理多于一行,那么它应该检查行数并使用throw(或RaIsError)表示存在未解决的问题。

标签: sql sql-server tsql database-trigger


【解决方案1】:

varchar 到 bit 的转换不支持语言。内置只有“真”和“假”可以转换。

字符串值 TRUE 和 FALSE 可以转换为位值:TRUE 转换为 1,FALSE 转换为 0。

bit (Transact-SQL)

【讨论】:

【解决方案2】:

要得到错误,您得到的列 Verkoper 必须是 bit 类型。解决方法取决于整体设计,要么更改数据类型,要么使用正确的列。那是微不足道的。

但是我回答这个问题的原因是因为您的触发器当前无法处理 Inserted 伪表可以包含多行的事实。

您应该始终将 T-SQL 问题作为基于集合的问题而不是过程问题来解决 - 因为关系数据库针对基于集合的操作进行了优化。

我认为下面的update 语句与您发布的代码执行相同的功能,但如果不是,希望您能理解并适应它。

UPDATE Gebruiker SET
  Verkoper = 'niet'
WHERE gebruikersnaam in (SELECT gebruikersnaam FROM INSERTED)
and (SELECT COUNT(*) FROM Verkoper V WHERE V.Gebruiker = gebruikersnaam) = 0
and Verkoper = 'wel';

事实上(感谢 David),用位值 0 和 1 替换单词 'niet' 和 'wel' 可能是您正在寻找的解决方案:

UPDATE Gebruiker SET
  Verkoper = 0
WHERE gebruikersnaam in (SELECT gebruikersnaam FROM INSERTED)
and (SELECT COUNT(*) FROM Verkoper V WHERE V.Gebruiker = gebruikersnaam) = 0
and Verkoper = 1;

您需要更改您的 insert 语句,以将 Verkoper 也使用 0 或 1。

注意:最好的做法是列出插入的列名。这不仅意味着您以后可以在不中断插入的情况下添加列,而且对于不熟悉您的方案的人来说,每个值将被插入到哪个列中是显而易见的。

【讨论】:

  • 非常感谢您的回复。我要去测试了。
猜你喜欢
  • 2011-12-01
  • 2016-09-21
  • 2012-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多