mysql - 使用表字段作为存储过程参数(将给定的表字段重新分配到其他表中)
问题描述
我有下表的结构:
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
应该用于ID
in 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.ID
和的值ITEM_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了解详情)
推荐阅读
- xamarin.forms - 尝试购买产品时出现 InAppBillingPurchaseException
- reactjs - 如何克隆状态变量以用作反应中的参考?
- ios - Xcode:XCTest 不能比较两个 NSArray 的数字
- python - 将整个数据帧(不仅是数据和标签)传递给 Tensorflow 的 model.fit 的工作原理 - 即如何使用未显式调用的类函数
- scala - Spark从json字符串和字符串scala创建DF
- amazon-web-services - 尝试创建一个使用 aws 市场软件创建 ec2 的 python 函数
- android - Firebase 真实数据库值与检索到的不同
- karate - Karate: test count using failsafe + parallel runner
- reactjs - 如果 create-react-app 自动添加它们,为什么需要使用 Webpack 和 Babel 从头开始创建 React 应用程序?
- python - 如何使用不在第一维中的占位符展平张量?