使用表字段作为存储过程参数(将给定的表字段重新分配到其他表中)

Metafaniel

我具有下表的结构:

ITEMS:
╔═══════════╤══════════════╤══════╤═════╤═════════╤════════════════╗
║ FIELD     │ TYPE         │ NULL │ KEY │ DEFAULT │ EXTRA          ║
╠═══════════╪══════════════╪══════╪═════╪═════════╪════════════════╣
║ id        │ int          │ NO   │ PRI │         │ auto_increment ║
╟───────────┼──────────────┼──────┼─────┼─────────┼────────────────╢
║ image_url │ varchar(255) │ NO   │     │         │                ║
╚═══════════╧══════════════╧══════╧═════╧═════════╧════════════════╝

ITEM_TRANSLATIONS:
╔═════════════╤══════════════╤══════╤═════╤═════════╤════════════════╗
║ FIELD       │ TYPE         │ NULL │ KEY │ DEFAULT │ EXTRA          ║
╠═════════════╪══════════════╪══════╪═════╪═════════╪════════════════╣
║ id          │ int          │ NO   │ PRI │         │ auto_increment ║
╟─────────────┼──────────────┼──────┼─────┼─────────┼────────────────╢
║ description │ varchar(255) │ NO   │     │         │                ║
╟─────────────┼──────────────┼──────┼─────┼─────────┼────────────────╢
║ title       │ varchar(45)  │ NO   │     │         │                ║
╚═════════════╧══════════════╧══════╧═════╧═════════╧════════════════╝

我还有一个存储过程,可以通过这种方式将其参数重新分配给所需的表:

DELIMITER //
    DROP PROCEDURE IF EXISTS addItem //
    CREATE PROCEDURE addItem (
        IN _item__image_url VARCHAR(255),
        IN _item_translations__title VARCHAR(45),
        IN _item_translations__description VARCHAR(255)
    )

    BEGIN
        START TRANSACTION;
            INSERT INTO item (
                image_url
            )
            VALUES (
                _item__image_url
            );


            INSERT INTO item_translations (
                item_id,
                title,
                `description`
            )
            VALUES (
                LAST_INSERT_ID(),
                _item_translations__title,
                _item_translations__description
            );
        COMMIT ;
    END //
DELIMITER ;

如果以这种方式调用此过程:

CALL addBrand(
    "/images/items.png",
    "My Item",
    "An oversimplified item just for this question."
);

我得到了预期的以下结果:

ITEMS:
╔════╤═══════════════════╗
║ ID │ IMAGE_URL         ║
╠════╪═══════════════════╣
║ 19 │ /images/items.png ║
╚════╧═══════════════════╝

ITEM_TRANSLATIONS:
╔════╤═════════╤═════════╤════════════════════════════════════════════════╗
║ ID │ ITEM_ID │ TITLE   │ DESCRIPTION                                    ║
╠════╪═════════╪═════════╪════════════════════════════════════════════════╣
║ 7  │ 19      │ My Item │ An oversimplified item just for this question. ║
╚════╧═════════╧═════════╧════════════════════════════════════════════════╝

我有第三个表,其中包含所有必填字段的N行:

IMPORTED_TABLE
╔════╤══════════════╤══════════════════════════════════╤════════════════════════╗
║ ID │ TITLE        │ DESCRIPTION                      │ IMAGE_URL              ║
╠════╪══════════════╪══════════════════════════════════╪════════════════════════╣
║ 42 │ Another Item │ Yet another oversimplified item. │ /images/items_2.png    ║
╟────┼──────────────┼──────────────────────────────────┼────────────────────────╢
║ 43 │ This Item    │ A nice item                      │ /images/thanks.png     ║
╟────┼──────────────┼──────────────────────────────────┼────────────────────────╢
║ 44 │ Trixie Item  │ The great and powerful item!     │ /images/mlp/trixie.png ║
╚════╧══════════════╧══════════════════════════════════╧════════════════════════╝

如何使用此表内容作为存储过程的参数,以便能够根据需要填充所需的表?为了得到这个:

ITEMS:
╔════╤════════════════════════╗
║ ID │ IMAGE_URL              ║
╠════╪════════════════════════╣
║ 19 │ /images/items.png      ║
╟────┼────────────────────────╢
║ 20 │ /images/items_2.png    ║
╟────┼────────────────────────╢
║ 21 │ /images/thanks.png     ║
╟────┼────────────────────────╢
║ 22 │ /images/mlp/trixie.png ║
╚════╧════════════════════════╝

ITEM_TRANSLATIONS
╔════╤═════════╤══════════════╤════════════════════════════════════════════════╗
║ ID │ ITEM_ID │ TITLE        │ DESCRIPTION                                    ║
╠════╪═════════╪══════════════╪════════════════════════════════════════════════╣
║ 7  │ 19      │ My Item      │ An oversimplified item just for this question. ║
╟────┼─────────┼──────────────┼────────────────────────────────────────────────╢
║ 8  │ 20      │ Another Item │ Yet another oversimplified item.               ║
╟────┼─────────┼──────────────┼────────────────────────────────────────────────╢
║ 9  │ 21      │ This Item    │ A nice item                                    ║
╟────┼─────────┼──────────────┼────────────────────────────────────────────────╢
║ 10 │ 22      │ Trixie Item  │ The great and powerful item!                   ║
╚════╧═════════╧══════════════╧════════════════════════════════════════════════╝

显然,这是一个过于简化的示例。在存储过程中,所有参数都有不同的数据处理方式,因此我不必重新创建存储过程。

比尔·卡温

您的ID是否IMPORTED_TABLE应该用于IDin ITEMS

如果是这样,那么您可以这样做:

START TRANSACTION;

INSERT INTO ITEMS (ID, IMAGE_URL) 
 SELECT ID, IMAGE_URL FROM IMPORTED_TABLE;

INSERT INTO ITEM_TRANSLATIONS (ITEM_ID, TITLE, DESCRIPTION)
 SELECT ID, TITLE, DESCRIPTION FROM IMPORTED_TABLE;

COMMIT;

这将对ID都逐字使用ITEMS.IDITEM_TRANSLATIONS.ITEM_ID

但是,如果要插入URL并忽略ID导入数据中值,并让ITEMS表生成新的ID值,则可以分批处理,并假定该批处理是一组连续的值。

START TRANSACTION;

INSERT INTO ITEMS (IMAGE_URL) 
 SELECT IMAGE_URL FROM IMPORTED_TABLE;

SET @START_ID = LAST_INSERT_ID() - 1;

INSERT INTO ITEM_TRANSLATIONS (ITEM_ID, TITLE, DESCRIPTION)
 SELECT (@START_ID := @START_ID+1), TITLE, DESCRIPTION FROM IMPORTED_TABLE;

COMMIT;

假设值是连续的是否安全?默认情况下,是安全的。例如,当您进行批量插入时,MySQL的JDBC驱动程序会做出此假设,因此它可以返回生成的ID值的集合。

例外是,如果您在具有选项innodb_autoinc_lock_mode=2的MySQL实例上,则不能保证这些值是连续的。这不是默认设置,因此可能不适用于您的情况。

有关详细信息,请阅读https://dev.mysql.com/doc/refman/8.0/en/innodb-auto-increment-handling.html

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章