【问题标题】:Informix 4GL and triggersInformix 4GL 和触发器
【发布时间】:2012-08-10 16:37:28
【问题描述】:

我想要一个用于重复检查的简单 SQL(触发器)。 我的表名是test1,有两列,codesname。在插入新记录之前,检查记录是否已经存在:如果存在,则产生错误,不插入;如果没有,让插入继续。

我该怎么做?

【问题讨论】:

  • 您尝试了哪些方法,为什么没有成功?可以在Informix 11.70 Information Center 找到这些手册。为什么你想要一个触发器而不是简单地在每一列上创建一个唯一的约束?除非需要,否则不要编写触发器;非触发约束将“更有效”。还有一整套独立的问题与 I4GL 是否会识别 CREATE TRIGGER 的语法有关;您可能需要将该语句包含在 SQL CREATE TRIGGER ... END SQL 块中。
  • 我不知道这个informix 4GL。这里他们要我创建一个触发器,我尝试通过select语句添加,但不知道。
  • 如果它是一个课堂练习,那么它可能会有一些优点,尽管具体的约束最好按照讨论的方式处理。如果是用于生产代码,那么你需要向他们解释他们的要求是不合理的,你可以让他们看看这个,和/或与我讨论它(请参阅我的个人资料以获取电子邮件地址)。
  • 解决此问题的简单方法非常简单,如果您使用的是表单画家,只需添加唯一键即可。我花了几天时间来解决这个简单的问题。感谢乔纳森的支持。

标签: informix 4gl


【解决方案1】:

确保表中没有重复数据的最简单、最可靠的方法是根本不使用触发器,而是使用 UNIQUE 或 PRIMARY KEY 约束:

CREATE TABLE test1
(
    code    INTEGER NOT NULL PRIMARY KEY,
    sname   VARCHAR(32) NOT NULL UNIQUE
);

四个约束(两个 NOT NULL,一个 PRIMARY KEY,一个 UNIQUE)自动确保没有重复记录插入到表中。

如果您选择添加触发器,它将复制由这些约束完成的工作。

至于如何做,您需要创建一个从触发器语句调用的存储过程。它将被赋予新代码和新名称,并执行 SELECT 以查看是否出现任何匹配记录,如果匹配则引发异常,否则不会引发异常。

CREATE PROCEDURE trig_insert_test1(ncode INTEGER, nname VARCHAR(32))
    DEFINE ocode INTEGER;
    FOREACH SELECT code INTO ocode
              FROM test1
             WHERE code = ncode OR sname = nname
        RAISE EXCEPTION -271, -100, "Value to be inserted already exists in table test1";
    END FOREACH;
END PROCEDURE

然后你使用:

CREATE TRIGGER ins_test1 INSERT ON test1
    REFERENCING NEW AS NEW
    FOR EACH ROW (EXECUTE PROCEDURE ins_trig_test1(new.code, new.sname))

在 Informix 4GL 中,您可以创建包含这些语句的字符串,然后准备和执行(和免费)它们,或者您可以使用 SQL 块:

SQL
    CREATE TRIGGER ins_test1 INSERT ON test1
        REFERENCING NEW AS NEW
        FOR EACH ROW (EXECUTE PROCEDURE ins_trig_test1(new.code, new.sname))
END SQL

但是,正如我一开始所说,为此使用触发器并不是最好的方法;鉴于表定义,这是多余的。

我没有通过服务器运行任何 SQL 或 SPL;您需要检查分号是否在 SPL 中的正确位置,因为 SPL 对此很挑剔。

您可以在Informix 11.70 Information Centre 中找到 SQL 和 SPL 语句的语法。

【讨论】:

  • 那么您需要稍微解释一下您的设置。您的数据库服务器是 SE 或 IDS(或者不太可能是 OnLine 或 XPS)。它很可能在同一台机器上。您使用的是哪个版本的 I4GL? (运行i4gl -V 找出答案。)如果您不对服务器进行任何管理,您可能正在运行SE。您可以运行$INFORMIXDIR/lib/sqlexec -V 来确认并打印版本。如果你没有sqlexec 程序,你就没有 SE;然后应该有一个$INFORMIXDIR/bin/oninit(或者可能是$INFORMIXDIR/bin/tbinit);您可以使用-V 标志运行它以获取版本。
  • SE 7.25 在哪个操作系统上运行?以及哪个版本的 I4GL?
  • 否;我无法进一步帮助您,因为您没有显示崩溃的程序。它需要简短、甜美和完整。您不应该让程序崩溃(如在“转储核心”中);您可能会因为出现问题而停止它。但由于我看不到你有什么代码,所以没有机会帮助你解决问题。要添加代码,请编辑问题。
  • 很高兴您设法解决了这些问题。请记住您作为提问者的职责——在上面对您的问题的评论中概述。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多