简体   繁体   English

使用列名指定预定义表

[英]Use a column name to specify a predefined table

I'm trying to use set up a database for a school project, and I'm using triggers to set up referential integrity for one table. 我正在尝试为学校项目使用建立数据库,并且正在使用触发器来为一个表设置参照完整性。 I have a table, Addresses, which stores the address for People, Studios, and Directors. 我有一个表Addresses,其中存储了People,Studio和Director的地址。 Then I have a table called Address Reference. 然后,我有一个称为地址引用的表。 This table points to the Address table, and it has a two fields, the ReferenceID and the TableName to show which table and row this address is for. 该表指向“地址”表,它具有两个字段,即ReferenceID和TableName,用于显示此地址用于哪个表和行。 I have a Constraint so TableName will always be valid. 我有一个约束,所以TableName将始终有效。

I'm trying to set up a trigger to make sure any rows inserted are valid, which I can do, I'm just trying to improve it. 我正在尝试设置一个触发器,以确保插入的任何行都有效,这是我可以做的,我只是在尝试改进它。 My code would look like this: 我的代码如下所示:

SELECT * 
    FROM inserted 
        WHERE ReferenceID IN 
            (SELECT PersonID 
                FROM inserted.TableName)

However I found I needed to use dynamic sql. 但是我发现我需要使用动态sql。 So I was thinking something like this: 所以我在想这样的事情:

SELECT * 
    FROM inserted 
        WHERE ReferenceID IN 
            (EXEC('SELECT PersonID FROM' + inserted.TableName))

Which didn't work, even when I removed the exec. 即使我删除了执行程序,这也不起作用。

I'm doing this in SQL Server Management Studio With SQL Server 11.0.3128 我正在使用SQL Server 11.0.3128的SQL Server Management Studio中执行此操作

Let me know if you need any more information. 让我知道您是否需要更多信息。 I've looked around, and I haven't found any answers to this question that work. 我环顾四周,但没有找到任何可行的答案。

This is a poor way to maintain referential integrity. 这是维护引用完整性的一种糟糕方法。 There are a number of ways you could approach this. 您可以通过多种方法来解决此问题。

The first would be to have an address table, then multiple tables to contain the links, eg 首先是要有一个地址表,然后是多个表以包含链接,例如

CREATE TABLE StudioAddress
(       StudioID INT NOT NULL,
        AddressID INT NOT NULL,
    CONSTRAINT PK_StudioAddress__StudioID_AddressID PRIMARY KEY (StudioID, AddressID),
    CONSTRAINT FK_StudioAddress__StudioID FOREIGN KEY (StudioID) REFERENCES Studio (StudioID),
    CONSTRAINT FK_StudioAddress__AddressID FOREIGN KEY (AddressID) REFERENCES Address (AddressID)
);

This maintains your referenctial integrity without needing triggers, and still caters for a 1 to many relationship. 这可以保持您的参考完整性,而无需触发,并且仍然可以满足一对多的关系。

Another option would be to have 3 nullable columns in your address table (StudioID, PersonID, DirectorID), each with a foreign key to the relevant table, you can the add a check constraint to ensure only one of the 3 fields is populated (if this is required). 另一个选择是在地址表中具有3个可为空的列(StudioID,PersonID,DirectorID),每个列均具有相关表的外键,您可以添加检查约束以确保仅填充这三个字段中的一个(如果这是必需的)。

I much prefer the first option though, it is much cleaner, and also allows for the same address to be used for multiple things. 我更喜欢第一种选择,因为它更清洁,并且允许将同一地址用于多种用途。


ADENDUM 附录

If this has to be done using triggers, then I think you would need to use something like this: 如果必须使用触发器来实现,那么我认为你需要使用这样的事情:

IF EXISTS(  SELECT  1
            FROM    inserted i
            WHERE   NOT EXISTS
                    (   SELECT  1
                        FROM    People p
                        WHERE   p.PersonID = i.ReferenceID
                        AND     i.TableName = 'People'
                        UNION ALL
                        SELECT  1
                        FROM    Studios s
                        WHERE   s.StudioID = i.ReferenceID
                        AND     i.TableName = 'Studios'
                        UNION ALL
                        SELECT  1
                        FROM    Directors d
                        WHERE   d.DirectorID = i.ReferenceID
                        AND     i.TableName = 'Directors'
                    )
        )
        BEGIN
            ROLLBACK TRANSACTION;
            RAISERROR('Referential integrity error', 16, 1);
        END

This essentially checks that for all inserted/updated rows a record exists with the relevant ID in the relevant table. 实质上,这将检查是否存在所有插入/更新的行,并且相关表中的记录具有相关ID。

I still stand by my earlier answer though, that this is a terrible approach, and I would question any syllabus this is on! 不过,我仍然坚持我先前的回答,认为这是一种糟糕的方法,并且我会对提出的任何教学大纲表示怀疑!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM