sql – 如果满足条件,则阻止插入

前端之家收集整理的这篇文章主要介绍了sql – 如果满足条件,则阻止插入前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个表这样的内容
id | text | date | idUser → User | contentType

另一张表答案:

idAnswer → Content | idQuestion → Content | isAccepted

我想确保答案的日期大于问题的日期.问题是ContentType =’QUESTION’的内容.

我尝试使用以下触发器解决此问题,但是当我尝试插入Answer时出现错误

06002

触发:

CREATE TRIGGER check_valid_answer 
AFTER INSERT ON "Answer"
FOR EACH ROW EXECUTE PROCEDURE check_valid_date_answer();

触发功能

CREATE FUNCTION check_valid_date_answer() RETURNS trigger
    LANGUAGE plpgsql
    AS $$BEGIN
  IF (SELECT "Content".date FROM "Content"
      WHERE "Content".id = NEW.idAnswer)
   < (SELECT "Content".date FROM "Content"
      WHERE "Content".id = NEW.idQuestion) 
  THEN
    RAISE NOTICE 'This Answer is an invalid date';
  END IF;
  RETURN NEW;
END;$$;

所以,我的问题是:我真的需要为此创建触发器吗?我看到我无法使用CHECK in Answer,因为我需要与另一个表的属性进行比较.还有其他(更简单/更好)的方法吗?如果没有,为什么错误,我该如何解决

解决方法

你的基本方法是合理的.触发器是有效的解决方案.它应该工作除了3个问题:

1)您的命名约定:

我们需要确定您的确切表定义,但证据就在那里.错误消息说:没有字段“idanswer” – 小写.不说“idAnswer” – CaMeL案.如果您在Postgres中创建CaMeL案例标识符,则必须在您的余生中将它们双重引用.

2)中止违反插入

>提出EXCEPTION而不是友好通知实际中止整个交易.
>或RETURN NULL而不是RETURN NEW,只是静默地中止插入的行,而不会引发异常并且不返回任何内容.

我会做第一个.这可能会解决手头的错误和工作:

CREATE FUNCTION trg_answer_insbef_check()
  RETURNS trigger AS
$func$
BEGIN
   IF (SELECT c.date FROM "Content" c WHERE c.id = NEW."idAnswer")
    < (SELECT c.date FROM "Content" c WHERE c.id = NEW."idQuestion") THEN
      RAISE EXCEPTION 'This Answer is an invalid date';
   END IF;
   RETURN NEW;
END
$func$ LANGUAGE plpgsql;

正确的解决方案是专门使用legal,lower case names并完全避免这些问题.这包括你不幸的表名以及列名日期,它是标准sql中的reserved word,不应该用作标识符 – 即使Postgres允许它.

3)应该是BEFORE trigger

CREATE TRIGGER insbef_check
BEFORE INSERT ON "Answer"
FOR EACH ROW EXECUTE PROCEDURE trg_answer_insbef_check();

您希望在执行任何其他操作之前中止无效插入.

当然,您必须确保时间戳表内容无法更改,或者您需要更多触发器以确保满足您的条件.答案中的fk列也是如此.

猜你在找的MsSQL相关文章