Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 避免在触发器中重写相同的代码_Sql_Oracle_Triggers - Fatal编程技术网

Sql 避免在触发器中重写相同的代码

Sql 避免在触发器中重写相同的代码,sql,oracle,triggers,Sql,Oracle,Triggers,我正在使用表在数据库级别编写数据验证 以下是我用于验证的表结构:用于理解的记录有限 SRNO | COL_NAME | OBJ_NAME | IS_MANDATORY | ALTER_COL | ERROR_MSG 1 | TITLE | Customer | Y | | Enter first name! 2 | FNAME | Customer | Y | LNAME | Either fi

我正在使用表在数据库级别编写数据验证

以下是我用于验证的表结构:用于理解的记录有限

 SRNO | COL_NAME | OBJ_NAME | IS_MANDATORY | ALTER_COL | ERROR_MSG
 1    | TITLE    | Customer | Y            |           | Enter first name!
 2    | FNAME    | Customer | Y            | LNAME     | Either first or last name are required!
 3    | MNAME    | Customer | N            |           | 
 4    | LNAME    | Customer | Y            | FNAME     | Either first or last name are required!
我编写了一个触发器,在按照验证表将数据插入数据库之前验证数据:

上面的触发器检查所有必填字段是否都有值。上面的触发器工作正常

现在我想使用validations表中的ALTER_COL列。如果原始列为空,将检查ALTER_COL列。例如,FNAME或LNAME都是必需的。所以,若并没有提供FNAME,那个么触发器必须在引发错误之前检查LNAME,并且只有当LNAME也为空时,才会引发错误

我的问题是,我是否需要在if条件下重写case语句,以获得ALTER_COL的长度,如:

还是有更好的方法

任何建议都将不胜感激

在@Wernfried给出答案后更新1

我尝试编写可以避免重写代码的函数,但我无法将新代码传递给该函数。我试过的函数看起来像

CREATE FUNCTION FN_VALIDATE_CUST(COL_NAME in VARCHAR) return NUMBER as
BEGIN
 return CASE COL_NAME
        WHEN 'FNAME' THEN nvl(length(:NEW.FNAME),0)
        WHEN 'MNAME' THEN nvl(length(:NEW.MNAME),0)
        WHEN 'LNAME' THEN nvl(length(:NEW.LNAME),0)
        WHEN 'TITLE' THEN nvl(length(:NEW.TITLE),0)
        ELSE length('OK')
    END;
END;

我无法将新对象传递给上述函数以访问列值。所以,如果我使用函数,我需要在触发器事件中编写case语句。

您可以编写一个过程并在触发器中调用此过程

您可以编写一个过程并在触发器中调用此过程

还是有更好的方法

绝对-使用NOTNULL并检查数据库中的约束来执行此操作。这就是他们的目的,他们比你的方法更高效、可靠和灵活

如果确实需要为约束冲突提供自定义错误消息,那么请确保命名了约束,并提供一个自定义消息表,以便在违反约束时使用

编辑

如果约束的实施取决于另一个表中是否存在客户编号,那么我希望在表中有一个标志,指示是否应用检查和非空约束,并将其包含在约束定义中

例如:

... add constraint lname_required check (apply_constraints = 0 or lname is not null)
我认为,在这种情况下,您不可能不需要触发器,因为您必须根据另一个表中的客户号来维护apply_约束的值,以确保该表中的删除或插入更新该表中的相关值

还是有更好的方法

绝对-使用NOTNULL并检查数据库中的约束来执行此操作。这就是他们的目的,他们比你的方法更高效、可靠和灵活

如果确实需要为约束冲突提供自定义错误消息,那么请确保命名了约束,并提供一个自定义消息表,以便在违反约束时使用

编辑

如果约束的实施取决于另一个表中是否存在客户编号,那么我希望在表中有一个标志,指示是否应用检查和非空约束,并将其包含在约束定义中

例如:

... add constraint lname_required check (apply_constraints = 0 or lname is not null)

我不认为在这种情况下,您可以不需要触发器,因为您必须根据另一个表中的客户编号来维护apply_constraints的值,以确保该表中的删除或插入更新该表中的相关值。

感谢您的回答和+1,但我不能使用NOT NULL,因为主键以外的每一列都可以允许NULL,即使它在验证表中是必需的。根据存储客户编号的其他表,即使缺少必需的列,也可以保存客户编号。感谢您的回答和+1,但我不能使用NOT NULL,因为除了主键之外的每一列都可以允许NULL,即使它在验证表中是必需的。这取决于存储客户编号的其他表,即使缺少必需的列,也可以保存这些客户编号。您在验证数据方面投入了这么多精力,这真是太好了。但多表约束或SQL断言很难正确实现。我建议你看看我没用过这个工具,但你至少可以看看博客。作者在这些问题上花了很多心思。你花了这么多精力验证你的数据,真是太好了。但多表约束或SQL断言很难正确实现。我建议你看看我没用过这个工具,但你至少可以看看博客。作者对这些问题进行了大量的思考。
... add constraint lname_required check (apply_constraints = 0 or lname is not null)