用于检查依赖于输入值的特定约束的数据库约束?

发布于 2024-09-28 22:52:04 字数 502 浏览 2 评论 0原文

我正在一个没有外键约束的数据库程序上运行维护,即使它确实应该有......

有一个日志表,其中有一个 ParentID 列和一个 ParentType 列。 ParentType 列中的条目确定 ParentID 引用哪个表。

我正在寻找的是关于添加此依赖于输入的外键约束的最佳方法的想法......令人厌恶......

我希望能够扔掉这个程序的整个后端并重新开始,但如果我不破坏一切,它就已经非常不可靠了。收紧后端似乎是我目前最好的选择。唯一真正的选择似乎是放弃整个计划。

那么,是的,关于在 SQL 端约束此列中的数据的最佳方法的想法?

编辑:我已经可以说不清楚了...

对,所以我有日志表,然后是 TableOne 和 TableTwo。如果正在输入 Logging 的行尝试添加 ParentType 列中为 1 的行,则 ParentID 必须出现在 TableOne 中,如果 ParentType 为 2,则 ParentID 必须出现在 TableTwo 中。

I'm running maintenance on a database program with no foreign key constraints, even though it really should have...

There is a Logging table which has a ParentID column, and a ParentType column. The entry in the ParentType column determines which table ParentID references.

What I'm looking for is for ideas on the best way to add this input-dependent foreign key constraint... abomination...

I'd love to be able to just throw out the whole back end of this program and start again, but it's already unreliable as hell without me breaking everything. Tightening up the back end seems to be my best best at this point. The only real alternative seems to be to throw out the entire program.

So, yeah, ideas on the best way to constrain the data in this column on the SQL side?

EDIT: I can tell this unclear already...

Right, so I have have the Logging table, then TableOne and TableTwo. If the row being entered into Logging tries to add a row with 1 in the ParentType column, then the ParentID must appear in TableOne, if ParentType is 2, ParentID must appear in TableTwo.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

千と千尋 2024-10-05 22:52:04

您最好的选择可能是在日志记录表上将此规则实现为 INSTEAD OF 触发器,您可以在其中根据相应的表检查 ID,并在发生 FK 违规时拒绝 INSERT/UPDATE。在粗略的伪代码中,类似于:

CREATE TRIGGER tr_io_iu_Logging ON Logging
INSTEAD OF INSERT, UPDATE
AS
BEGIN
    IF UPDATE(ParentID) BEGIN
        IF NOT EXISTS(SELECT 1 FROM Inserted i LEFT JOIN TableOne t1 ON i.ParentID = t1.ID WHERE i.ParentType=1 AND t1.ID IS NULL)
            /* perform the insert */
        ELSE 
           /* raise error */

        IF NOT EXISTS(SELECT 1 FROM Inserted i LEFT JOIN TableTwo t2 ON i.ParentID = t2.ID WHERE i.ParentType=2 AND t2.ID IS NULL)
            /* perform the insert */
        ELSE 
           /* raise error */
    END /* IF */    
END /* trigger */

Your best bet may be to implement this rule as an INSTEAD OF trigger on the Logging table, where you could check the IDs against the appropriate table and reject the INSERT/UPDATE if a FK violation would occur. In rough pseudo-code, something like:

CREATE TRIGGER tr_io_iu_Logging ON Logging
INSTEAD OF INSERT, UPDATE
AS
BEGIN
    IF UPDATE(ParentID) BEGIN
        IF NOT EXISTS(SELECT 1 FROM Inserted i LEFT JOIN TableOne t1 ON i.ParentID = t1.ID WHERE i.ParentType=1 AND t1.ID IS NULL)
            /* perform the insert */
        ELSE 
           /* raise error */

        IF NOT EXISTS(SELECT 1 FROM Inserted i LEFT JOIN TableTwo t2 ON i.ParentID = t2.ID WHERE i.ParentType=2 AND t2.ID IS NULL)
            /* perform the insert */
        ELSE 
           /* raise error */
    END /* IF */    
END /* trigger */
烙印 2024-10-05 22:52:04

假设您通过 SP 输入数据,我会考虑使用带有值和表类型参数的 UDF,该 UDF 会针对表类型中的相应表执行查找验证。就性能而言,这不会是一个令人尖叫的问题,但您将能够在插入之前将调用放入插入 SP 中以进行验证,并且您将能够将验证集中在 UDF 中。

Assuming you are entering data via an SP, I'd consider using a UDF with parameters for the value and tabletype that performs a lookup for validation against the appropriate table in the tabletype. This won't be a screamer in terms of performance, but you'll be able to put the call in prior to insert for validation purposes in the insert SP, and you'll be able to centralize the validation in the UDF.

一梦浮鱼 2024-10-05 22:52:04

创建两个持久计算列,如下所示:

CarID AS (CASE WHEN Type='Car' THEN ParentID END)

TruckID AS (CASE WHEN Type='Truck' THEN ParentID END)

并让 FK 将它们引用到您的表中。

Create two persisted computed columns, like this:

CarID AS (CASE WHEN Type='Car' THEN ParentID END)

TruckID AS (CASE WHEN Type='Truck' THEN ParentID END)

and have FK refer them it to your tables.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文