SQL:如何将两个表中的主键值INSTO到主表中

时间:2010-04-04 09:43:50

标签: sql insert relational-database

我很感激SQL语句的一些帮助,我真的无法理解。

我想要做的是相当简单,我需要从两个不同的表中获取值,并在将新行插入两个表之一时将它们复制到主表中。

这个问题可能是最好的解释:

我有三个表,productcategories,regioncategories和mastertable。

         ---------------------------
TABLE:   PRODUCTCATEGORIES
         ---------------------------
COLUMNS: CODE       | DESCRIPTION
         ---------------------------
VALUES:  BOOKS      | Books
         ---------------------------

         ---------------------------
TABLE:   REGIONCATEGORIES
         ---------------------------
COLUMNS: CODE       | DESCRIPTION
         ---------------------------
VALUES:  EU         | European Union
         ---------------------------

         ------------------------------------------
TABLE:   MASTERTABLE
         ------------------------------------------
COLUMNS: REGION     | PRODUCT       | ACCOUNT
         ------------------------------------------
VALUES:  EU         | BOOKS         | NULL
         ------------------------------------------

我希望在productcategories或regioncategories中创建新行时,可以像这样插入值。

创建新行。

         ---------------------------
TABLE:   PRODUCTCATEGORIES
         ---------------------------
COLUMNS: CODE       | DESCRIPTION
         ---------------------------
VALUES:  BOOKS      | Books
         ---------------------------
VALUES:  DVD        | DVDs
         ---------------------------

SQL语句将新值复制到mastertable中。

         ------------------------------------------
TABLE:   MASTERTABLE
         ------------------------------------------
COLUMNS: REGION     | PRODUCT      | ACCOUNT
         ------------------------------------------
VALUES:  EU         | BOOKS        | NULL
         ------------------------------------------
VALUES:  EU         | DVD          | NULL
         ------------------------------------------

如果在regioncategories中创建了一行,也是如此。

新行。

         ---------------------------
TABLE:   REGIONCATEGORIES
         ---------------------------
COLUMNS: CODE       | DESCRIPTION
         ---------------------------
VALUES:  EU         | European Union
         ---------------------------
VALUES:  US         | United States
         ---------------------------

复制到mastertable。

         ------------------------------------------
TABLE:   MASTERTABLE
         ------------------------------------------
COLUMNS: REGION     | PRODUCT       | ACCOUNT
         ------------------------------------------
VALUES:  EU         | BOOKS         | NULL
         ------------------------------------------
VALUES:  EU         | DVD           | NULL
         ------------------------------------------
VALUES:  US         | BOOKS         | NULL
         ------------------------------------------
VALUES:  US         | DVD           | NULL
         ------------------------------------------

我希望这是有道理的。

谢谢,

的Stefan

4 个答案:

答案 0 :(得分:2)

您可以在运行时轻松构建“主表”:

SELECT  *
FROM    regiontable
CROSS JOIN
        producttable

它会更高效,因为与物化主表不同,两个表都可能适合缓存。

如果由于某种原因你需要实现它,那么只需在两个表上写入触发器:

INSERT
INTO    mastertable
SELECT  r.code, NEW.code
FROM    regiontable t

mastertable

INSERT
INTO    mastertable
SELECT  NEW.code, p.code
FROM    producttable p

on producttable

答案 1 :(得分:1)

有两种方法可以将额外信息插入MASTERTABLE。

  1. 使用触发器 - 当在PRODUCTCATEGORIES或REGIONCATEGORIES中发生插入时,插入触发器将触发并检查MASTERTABLE中是否存在该行。如果不是,则添加。

  2. 创建存储过程以将数据插入到PRODUCTCATEGORIES和REGIONCATEGORIES表中。然后,存储过程负责检查MASTERTABLE并在必要时插入。

  3. 第二种方法的优势在于,对于其他维护代码的人来说,显而易见的事情是显而易见的。触发器可以隐藏重要功能。出于性能原因,存储过程通常是交易SQL的首选。

答案 2 :(得分:1)

您的主表似乎是所有潜在组合的交叉联接。因此,当您添加新区域时,您必须添加该区域中的所有潜在产品。对于可以从所有潜在区域和所有潜在类别推断的数据,这需要付出很多努力。

我知道你提到还有其他专栏。这些附加列包含哪些内容?

我通常不会将这样的表格保留在规范化数据库中 - 除非您提到的其他列需要在创建时以某种特殊方式分配,然后在某种维护中进行更改 - 即使在这种情况下,具有适当默认值的稀疏表(即仅偏离默认值)可以很好地工作。

我在我的一个系统中有一个类似的交叉连接,它包含大约25米的行,并允许我们在2维2500总帐帐户x 10000成本中心空间中替换非常复杂的逻辑,其中有“行”和“列”具有相同的逻辑,但逻辑的“孤岛”。

答案 3 :(得分:0)

好的,谢谢你的回答和建议。

我正在使用连接到MsSQL数据库的访问项目。我试图通过使用表触发器解决这个问题,但没有一个建议对我有用。因此,我决定在客户端用VBA代码解决这个问题。

这可能不是解决它的正确方法,但知道任何人阅读都可能有用。

表结构相同,但我为product和region表创建了相应的表单。在表单AfterInsert事件上,我有以下代码:

地区表:

Private Sub Form_AfterInsert()

Dim varRegion As String
Dim strSQL As String

varRegion = Me![code]
strSQL = "INSERT INTO master([region], [product]) SELECT '" & varRegion & "', & _
          [code] FROM product;"

    DoCmd.RunSQL strSQL

End Sub

产品表:

Private Sub Form_AfterInsert()

Dim varProduct As String
Dim strSQL As String

varProduct = Me![code]
strSQL = "INSERT INTO master([region], [product]) SELECT [code], & _ 
          '" & varProduct & "' FROM region;"

    DoCmd.RunSQL strSQL

End Sub

编辑:稍微研究一下这个问题,我发现如果您使用SQL Server,这是您需要用于触发器的代码,如果您不想使用客户端设置。

显然,在SQL Server中,当需要获取插入行的值时,需要引用一个名为“inserted”的隐藏表。查看此链接以获取更多信息:Multirow Considerations for DML Triggers

大!

产品表:

-- Trigger statement
CREATE TRIGGER "name-of-trigger"
ON producttable
FOR INSERT AS

    -- Insert statement
INSERT INTO mastertable ([region],[product])
SELECT regiontable.[code], inserted.[code]
FROM regiontable, inserted;

地区表:

-- Trigger statement
CREATE TRIGGER "name-of-trigger"
ON regiontable
FOR INSERT AS

    -- Insert statement
INSERT INTO mastertable ([product],[region])
SELECT producttable.[code], inserted.[code]
FROM producttable, inserted;