【问题标题】:how to automatically insert foreign key references in tables in mysql or JDBC?如何在 mysql 或 JDBC 的表中自动插入外键引用?
【发布时间】:2014-09-18 18:51:11
【问题描述】:

我正在使用 MySQL。我的问题是如何自动将新添加的行插入到外键表中。一个例子将澄清我的问题:

我有两张表 Employee 和 Salary:

CREATE TABLE Employee(
     emp_id int NOT NULL AUTO_INCREMENT,
     name char(30),
     PRIMARY KEY (emp_id)
)  ENGINE=innoDB;

CREATE TABLE salary {
       sal_id int NOT NULL AUTO_INCREMENT
       salary_figure int,
       emp_id int,
       PRIMARY KEY (sal_id),
       FOREIGN KEY REFERENCES Employee(emp_id)
}

这是连接表:

employee_salary_join Table {
    int sal_id,
    int emp_id
}

上面的连接表没有任何外键关系。

现在当我将员工插入员工表时

INSERT into Employee values ("john")

执行该语句后,在Employee表中创建一行,该行具有由数据库引擎分配的pk。

现在,当我在工资表中为员工 John 插入一行时,如下所示:

INSERT into SALARY values ("30000", ?????)

如何获取上面 John 刚刚插入的行的员工 ID 并将其放置在 ????? 的位置

最后,我有一个连接表,每次在salary表中添加一行,我都想要连接表中的相应条目。这可以通过触发器来完成,但我并不完全清楚如何设置它,因为我需要为连接表行引用 emp_idsal_id

我还想了解这里处理外键插入时的最佳做法。我正在使用 JDBC/mysql 驱动程序。我想这应该不会影响我们如何在 sql 语句中处理上述内容。

【问题讨论】:

  • @MarkRotteveel:该链接有助于澄清第一部分。关于获取连接表 id 的第二部分,JDBC 中有没有一种方法可以自动插入。或者在数据库端需要一个触发器。如果是这样,要使触发器起作用,需要知道两个表中两行的 id
  • 这是您应该坚持关于 SO 的一个特定问题的原因之一。但是,MySQL 有触发器,你可以从插入的记录中获取值插入到另一个表中,参见dev.mysql.com/doc/refman/5.7/en/trigger-syntax.html(具体示例见文末)
  • 顺便说一句:我不清楚你为什么需要那个“连接表”;鉴于薪水表已经包含员工 ID,因此没有必要。
  • @MarkRotteveel:我同意这里没有必要。但我的目的是提供一个例子来说明我的观点。而且我不确定触发器是否是获取连接表插入的最佳实践,或者在 JDBC 级别执行是否更好(在这种情况下,您可以回滚并适当地处理它)

标签: mysql jdbc foreign-keys triggers


【解决方案1】:

您使用函数 LAST_INSERT_ID 获得插入行的 auto_increment 列的 ID: 所以你可以使用

INSERT into SALARY (salary_figure, emp_id) values ("30000", LAST_INSERT_ID());

为您的第二次 INSERT 操作。

如果您想通过触发器将一行添加到第三个表中,使用新的 sal_idemp_id 值,您可以使用 Salary 表上的 AFTER INSERT 触发器,使用新值列 emp_id 和最后插入的 auto_increment id ... 带有已经提到的 LAST_INSERT_ID() 函数。

CREATE TRIGGER salary_after_insert AFTER INSERT ON `SALARY` 
    FOR EACH ROW
    BEGIN
         INSERT INTO join_table (emp_id, sal_id) VALUES (NEW.emp_id, LAST_INSERT_ID());
    END;

【讨论】:

  • LAST_INSERT_ID() 如何从员工表中获取最后插入的键。您没有指定表名。我想我的问题是不同的。请再读一遍。它必须处理外键引用
  • @brainstorm 简单地说:LAST_INSERT_ID() 返回会话中最后生成的 id。因此,如果 INSERT 生成了一个 id,则该 id 将被返回(假设您不执行其他插入)。但是,它不是获取生成密钥的“JDBC”方式,请参阅stackoverflow.com/questions/1915166/…
  • @MarkRotteveel 您对“JDBC”方式的看法是绝对正确的,因为这样的 API 将对 DBMS 功能进行抽象,因此它可以与任何数据库管理系统一起使用。在没有任何 java 代码的情况下,我编写了 SQL 方式...
  • @VMai:如何为连接表插入 id 以触发触发?
  • 就像您处理任何其他值一样。
【解决方案2】:

我使用此代码并正常工作

 try 
        { 
        SqlCommand comm = new SqlCommand("Insert into tbl_sale(Terminal_NO, Date, Sale_Type, Fuel_Type, Unit) values('"+ddl_terminal.SelectedItem+"','"+dt_sales.Value.Date+"', '"+ddl_SaleType.SelectedItem+"', '"+ddl_FuelType.SelectedItem+"', '"+ddl_unit.SelectedItem+"')",conn);
SqlCommand com = new SqlCommand("Insert into tbl_saleDetails(Sale_ID, Unit_Sold, Amount_per_Liter) values((Select Sale_ID from tbl_sale where Sale_ID = (Select MAX(Sale_ID) from tbl_sale)),'" + txt_Cash_Unit_Sold.Text + "','" + txt_Cash_Amount_per_liter.Text + "')", conn);
        conn.Open();
        comm.ExecuteNonQuery();
        com.ExecuteNonQuery();
        conn.Close();
            MessageBox.Show("Data Saved Successfully!");
            }
        catch(Exception ex)
                {
                    MessageBox.Show(ex.Message);
                } 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-01
    相关资源
    最近更新 更多