如果需要,请插入或更新MYSQL
我已经在网上浏览了一段时间,似乎找不到任何与我想要的相似的东西。我知道这与我写问题的方式有关,但如果有任何帮助,我将不胜感激 我尝试做的基本工作是:如果需要,请插入或更新MYSQL,mysql,sql,database,Mysql,Sql,Database,我已经在网上浏览了一段时间,似乎找不到任何与我想要的相似的东西。我知道这与我写问题的方式有关,但如果有任何帮助,我将不胜感激 我尝试做的基本工作是: 如果表不存在,请将某些项插入表中 如果项目确实存在,则更新该项目 它以以下格式存在: 名称、条形码、项目、数量、位置、价格和日期 名称-可以在多行中使用 条形码-用于特定项目,但可以用作多个位置 项目-与条形码相同,但包含名称 数量-不言自明 位置-可以是不同的位置 价格-附加到特定项目的价格 日期-上次购买该项目的时间 棘手的是,一个“名称”
- 如果表不存在,请将某些项插入表中
- 如果项目确实存在,则更新该项目
Insert into table if does not exist
- name, barcode, item, quantity, location, price and date
If name, barcode, item, location and price are the same
- Update quantity and date (if more recent)
首先,在名称、条形码、项目、位置和价格上添加一个
唯一的约束
ALTER TABLE tableX
ADD CONSTRAINT tableX_UQ
UNIQUE (name, barcode, item, location, price) ;
然后您可以使用插入到。。。在重复密钥更新时
:
INSERT INTO tableX
(name, barcode, item, location, price, quantity, date)
VALUES
(?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
quantity = CASE WHEN VALUES(date) > date
THEN quantity + VALUES(quantity) -- add quantity
ELSE quantity -- or leave as it is
END
, date = CASE WHEN VALUES(date) > date
THEN VALUES(date) ; -- set date to new date
ELSE date -- or leave as it is
END
REPLACE
也可以使用,但在行为上存在差异(如果您有外键,这一点尤其重要)。有关详细信息,请参阅此问题和@Bill Kawin的答案,其中讨论了INSERT IGNORE
,INSERT。。。在重复键上
和替换
可以使用mysql中的语法
但这只适用于一个唯一的索引。。。字段需要是唯一的
因此,您必须创建一个唯一的索引,如下所示:
alter <yourtable> add unique index(name, barcode, item, location, price);
alter添加唯一索引(名称、条形码、项目、位置、价格);
然后插入/更新语法将变为
replace into <yourtable> (name, barcode, item, quantity, location, price, date)
VALUES('name1', 'barcode1', 2, 'location1', 12.0, '25/12/2012');
替换为(名称、条形码、项目、数量、位置、价格、日期)
值(“名称1”、“条形码1”、“位置1”、“12.0”、“2012年12月25日”);
编辑
存储过程示例(简化且未经测试):
DELIMITER &&
DROP PROCEDURE IF EXISTS MyBase.UpdateOrInsert $$
CREATE PROCEDURE MyBase.UpdateOrInsert
(
IN _name VARCHAR(10),
IN _barcode VARCHAR(50),
IN _quantity INTEGER
IN _date DATE
)
DECLARE existingDate DATE default NULL;
BEGIN
SELECT date
INTO existingDate
FROM <yourTable> where name = _name and barcode = _barcode;
if (existingDate IS NULL) then
insert into <yourtable> (name, barcode, quantity, date) VALUES(_name, _barcode, _qantity, _date);
else
if (existingDate < _date) then
update <yourtable>
set quantity = _quantity,
date = _date
where name = _name
and barcode = _barcode;
end if;
end if;
END &&
分隔符&&
如果存在MyBase.UpdateOrInsert,则删除过程$$
创建过程MyBase.UpdateOrInsert
(
以VARCHAR(10)的名义,
IN_条形码VARCHAR(50),
单位数量整数
输入日期
)
声明existingDate默认为空;
开始
选择日期
进入现有日期
其中名称=\名称和条形码=\条形码;
如果(existingDate为空),则
插入(名称、条形码、数量、日期)值(\u名称、条形码、数量、日期);
其他的
如果(现有日期<\u日期),则
更新
设置数量=_数量,
日期=\u日期
其中name=\u name
和条形码=_条形码;
如果结束;
如果结束;
结束&&
多亏了上面这些人的帮助,我最终找到的解决方案非常接近于两者。请在下面找到:
INSERT INTO `stock`
(name, barcode, item, quantity, location, price, date)
VALUES
(?,?,?,?,?,?,?)
ON DUPLICATE KEY UPDATE
quantity = CASE WHEN
VALUES(date) < $date
THEN quantity + $quantity
ELSE quantity
END,
date = CASE WHEN
VALUES(date) < $date
THEN VALUES(date)
ELSE $date
END
插入到'stock'中`
(名称、条形码、项目、数量、位置、价格、日期)
价值观
(?,?,?,?,?,?,?)
关于重复密钥更新
数量=发生时的情况
值(日期)<$date
然后数量+数量$
其他数量
完,,
日期=发生时的情况
值(日期)<$date
然后是值(日期)
ELSE$日期
结束
太棒了,我成功地实现了这一点。但是,如果我只想在日期比现有日期新时更新它,那么需要添加什么?如果日期不新,请保持原样?只改变数量?或者两个都保持不变(所以在这种情况下什么都不做)?Hi ypercude,是的,如果日期没有更新,那么两个都保持不变,那么这个(编辑的)版本应该可以工作。我不确定您是否要添加数量(然后数量+值(数量)
),或者在日期较新时只添加然后值(数量)
,但您可以处理。使用此选项时出现了另一个问题。我遇到了一些有趣的事情,当我使用少量的值时,效果很好,但是在大量使用时,即使日期等于上次使用的日期,数量也会更新感谢回复,这是另一个有用的答案,但是,如果我想补充一点,只有当日期比表中的当前日期新时,才更新数量?当我解析一个XML文件时,一些数据被重新处理-read@roadkill247我想你不能用ypercube和我的答案来做这件事。。。我想说的是,您必须使用存储过程。或者在解析xml文件时管理它,然后再转到数据库。。。原因唯一索引(这是两个答案的基础)可以管理唯一性,而不是“更大”/“更低”的条件。感谢您的快速回复。我无法更改XML,因为它是由第三方提供的,所以当你说存储过程时,你到底是什么意思?@roadkill247我不是说你需要更改XML,而是使用XML的“序列化”结果。无论如何,存储过程是。。。您可以在类似mysql的数据库中实现和调用的过程(方法)。谷歌“存储过程mysql”启动;)@Roadkill 247我添加了一个SP示例的开头。虽然使用此示例会遇到一些有趣的问题,但当我使用少量值时,效果很好,但是如果使用大量值,即使日期等于使用的最后一个日期,数量也会更新