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)