【问题标题】:MYSQL: How do I perform an INSERT inside a SELECT?MYSQL:如何在 SELECT 中执行 INSERT?
【发布时间】:2014-08-08 03:26:12
【问题描述】:

我正在尝试在选择中执行插入操作。这是为了将多个相互依赖的插入链接在一起。因此,它看起来像这样。

INSERT (Parent)
--SELECT (Return the Child's uuid created and assigned by TRIGGER)
---INSERT (Child)

数据库中的每条记录都有一个通过触发器插入时分配的 uuid。我为要捕获的每种类型的实体(例如人员、地址、电话、电子邮件)都有一个表格。

解决方案 1:我可以先插入一个依赖实体,例如电话,选择它的 uuid,然后将其包含在父实体中。在这种情况下是“人”。

解决方案2:我可以创建父实体,然后是依赖,然后在获取依赖uuid后更新父实体。

解决方案 3:我要做的是在创建父项的同时创建依赖项,并将其 uuid 返回给父项以插入父记录。这依赖于操作顺序来确保一切都以适当的顺序发生。

由于 mysql 数组支持的问题,我正在伪造一个父/子 uuid_array 表。因此涉及到额外的操作,但给定的示例要简单得多。

知道如何解决这个问题吗?有没有更好的方法来返回 uuid?

INSERT INTO person (Name_First,Name_Middle,Name_Last,Phone_UUID_Array)
VALUES  (
    'John',
    'Diddly',
    'Doe',
    SELECT @last_uuid
        INSERT INTO phone (Phone_Number,Phone_Type)
        VALUES  (
            '1-555-555-5555',
            (SELECT UUID FROM VIEW_TYPE_CATEGORY WHERE Reference_Type='Personal cell' AND Category='phone')
        )
);

我为每个表创建的触发器示例

CREATE TRIGGER uuid_person BEFORE INSERT ON person FOR EACH ROW SET NEW.UUID = UUID();
CREATE TRIGGER last_uuid_person AFTER INSERT ON person FOR EACH ROW SET @last_uuid = NEW.UUID;

CREATE TRIGGER uuid_phone BEFORE INSERT ON phone FOR EACH ROW SET NEW.UUID = UUID();
CREATE TRIGGER last_uuid_phone AFTER INSERT ON phone FOR EACH ROW SET @last_uuid = NEW.UUID;

【问题讨论】:

  • 我已经看过那个了。似乎取决于设置的自动增量,我没有使用。
  • 我通常发现使用编程语言编写所有插入和选择脚本并跟踪所有内容是最简单的。说 perl 什么的。
  • 这就是我认为我要解决的问题。因为我可能无法控制界面,所以我更喜欢在数据库中做尽可能多的事情,并提供简单的视图来使用。我还想使用该功能建立系统中所有记录更改的自动日志记录。

标签: mysql sql


【解决方案1】:

不,您不能在 SELECT“内部”执行 INSERT,也不能在另一个 INSERT 内部执行 INSERT。

您可以使用触发器,但恕我直言,这比它的价值更麻烦。

我建议不要使用触发器执行此操作,而是生成 uuid 并将其保存在会话变量中。然后,您可以在任意数量的后续语句中使用它。

SELECT UUID() INTO @phone_uuid;

INSERT INTO phone (Uuid,Phone_Number,Phone_Type) VALUES (@phone_uuid, ...);

INSERT INTO person (Name_First,Name_Middle,Name_Last,Phone_UUID_Array)
VALUES ('John', 'Diddly', 'Doe', @phone_uuid);

这些会话变量的作用域是会话,因此您不必担心并发客户端自己的工作会覆盖您的工作,即使每个会话都使用相同的变量名。

另外,我担心您的描述Phone_UUID_Array 是一个逗号分隔的 UUID 列表。你可能不会对那个设计感到满意,for a number of other reasons。

您的参考方向错误。 Person 不应尝试引用其所有相关电话号码。换一种方式——phone 中的每一行都应该引用其父级person。这样你就不需要一个逗号分隔的列表,你可以以更合理的顺序插入它们——首先是parent,然后是一个或多个phone行,每个行都引用同一个父项。插入phone 后无需更新parent。

【讨论】:

  • 没有逗号分隔的列表。父/子关系将在它自己的表下捕获,除非我可以移动到 postgre 或支持数组的东西。我没有想过像那样预先生成 UUID。我要调查一下。谢谢(你的)信息。对于参考,它们是双向的,具体取决于您在哪个方向查看的对象。我希望在描述实体及其关系时获得最大的灵活性。
猜你喜欢
  • 1970-01-01
  • 2016-09-11
  • 2019-03-13
  • 1970-01-01
  • 2014-07-31
  • 2010-09-24
  • 1970-01-01
  • 2011-08-25
  • 1970-01-01
相关资源
最近更新 更多