Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如果需要,请插入或更新MYSQL_Mysql_Sql_Database - Fatal编程技术网

如果需要,请插入或更新MYSQL

如果需要,请插入或更新MYSQL,mysql,sql,database,Mysql,Sql,Database,我已经在网上浏览了一段时间,似乎找不到任何与我想要的相似的东西。我知道这与我写问题的方式有关,但如果有任何帮助,我将不胜感激 我尝试做的基本工作是: 如果表不存在,请将某些项插入表中 如果项目确实存在,则更新该项目 它以以下格式存在: 名称、条形码、项目、数量、位置、价格和日期 名称-可以在多行中使用 条形码-用于特定项目,但可以用作多个位置 项目-与条形码相同,但包含名称 数量-不言自明 位置-可以是不同的位置 价格-附加到特定项目的价格 日期-上次购买该项目的时间 棘手的是,一个“名称”

我已经在网上浏览了一段时间,似乎找不到任何与我想要的相似的东西。我知道这与我写问题的方式有关,但如果有任何帮助,我将不胜感激

我尝试做的基本工作是:

  • 如果表不存在,请将某些项插入表中
  • 如果项目确实存在,则更新该项目
它以以下格式存在:

名称、条形码、项目、数量、位置、价格和日期

名称-可以在多行中使用 条形码-用于特定项目,但可以用作多个位置 项目-与条形码相同,但包含名称 数量-不言自明 位置-可以是不同的位置 价格-附加到特定项目的价格 日期-上次购买该项目的时间

棘手的是,一个“名称”可以在不同的位置以不同的价格包含多个项目(条形码和项目)。这个想法是,客户可以看到他们在一个固定的时间花了多少钱买了一件商品,所以他们知道他们需要卖多少钱

但是,他们购买的价格可能会有所不同,因此如果价格与以前购买的价格不同,他们需要在表中创建另一行

整件事背后的想法是让它记录每个地点每件商品的“名称”有多少,然后记录他们上次购买的价格和时间

希望这是有道理的

在psuedo代码中:

    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示例的开头。虽然使用此示例会遇到一些有趣的问题,但当我使用少量值时,效果很好,但是如果使用大量值,即使日期等于使用的最后一个日期,数量也会更新