具有多个条件的MYSQL条件插入

时间:2014-10-04 18:41:31

标签: php mysql sql

我试图创建一个包含多个条件的INSERT语句作为PHP函数的一部分 - 到目前为止,这是我的代码:

public function insertData($data)
    {
        try
        {
            $stmt = $this->con->prepare('
            INSERT IGNORE INTO tblProductData(
            strProductCode, 
            strProductName, 
            strProductDesc,  
            smintStockLevel, 
            dblPrice, 
            dtmDiscontinued, 
            dtmAdded)
           SELECT :strProductCode, 
                  :strProductName, 
                  :strProductDesc, 
                  :smintStockLevel, 
                  :dblPrice,
           (CASE WHEN :dtmDiscontinued  = "yes" then NOW();
           ELSE SET dtmlDiscontinued = "NULL";
           END CASE),
            NOW()
            FROM dual
            WHERE not (:dblPrice < 5.0 and :smintStockLevel < 10) 
            and not (:dblPrice > 1000.0) ');

            $length = count($data);
            for ($x=0; $x < $length; $x++) {
            $params = array(':strProductCode' => $data[$x][0], 
                            ':strProductName' => $data[$x][1], 
                            ':strProductDesc' => $data[$x][2],
                            ':smintStockLevel' => $data[$x][3], 
                            ':dblPrice' => $data[$x][4] );

            $stmt->execute($params);
            }

            return $stmt;
            } catch(PDOException $e) {
                echo 'ERROR: ' . $e->getMessage();
            }
        }
    }

条件如下

  • 如果dblPrice的值小于5且smintStockLevel的值小于10,则不会插入该行。
  • 如果dblPrice的值大于1000 - 请勿插入该行
  • dtmDiscontinued =&#39; yes&#39; NOW()函数将被调用,在该单元格中插入当前日期/时间。否则请输入NULL

此查询作为PHP预处理语句的一部分执行,迭代包含所有值的多维数组。

我是否需要创建多个CASE?有人可以就解决这个问题的最佳方法提供建议。

需要进一步的信息,请告诉我。

更新

输入上面的代码是为了显示完整的背景,并包含了戈登的建议。但是,我目前在执行时收到错误ERROR: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens

有人能看出原因吗?谢谢

解决方案

:dtmlDiscontinued需要添加到$params以解决错误:

示例

 $params = array(':strProductCode' => $data[$x][0], ':strProductName' => $data[$x][1], ':strProductDesc' => $data[$x][2],
                            ':smintStockLevel' => $data[$x][3], ':dblPrice' => $data[$x][4], ':dtmDiscontinued' => $data[$x][5] );  

2 个答案:

答案 0 :(得分:1)

您不能将where子句与values一起使用。您可以在SQL中实现逻辑,如下所示:

INSERT INTO tblProductData(strProductCode, strProductName, strProductDesc,  smintStockLevel,
                           dblPrice, dtmDiscontinued, dtmAdded
                          )
    SELECT :strProductCode, :strProductName, :strProductDesc, :smintStockLevel, 
           :dblPrice,
           (case when :dtmDiscontinued  = 'Yes' then NOW() end),
           NOW()
    FROM dual
    WHERE not (:dblPrice < 5.0 and :smintStockLevel < 10) and
          not (:dblPrice > 1000.0);

(注意from dual实际上并没有做任何事情,但有些数据库在使用from时需要where子句。)

我不知道dtmDiscontinued = 'yes'是什么意思。但是像上面这样的东西应该有效。

也就是说,您可能会发现将逻辑放在应用程序层而不是数据库中更容易。如果您总是想检查这些条件,请考虑触发器。

答案 1 :(得分:0)

Mysql没有检查约束,因此您必须在触发器中实现它们。 为了让ypu成为一个先机:

DELIMITER $$
CREATE TRIGGER product_cond BEFORE INSERT ON tblProductData
FOR EACH ROW
BEGIN
    declare message VARCHAR(255);
    declare hasError BIT;
    IF new.dblPrice < 5 AND new.smintStockLevel < 10 THEN
        SET hasError := 1;
        SET message := 'If price is less then 5 stock has to be more then 10';
    END IF;
    IF new.dblPrice > 1000 THEN
        SET hasError := 1;
        SET message := 'Price can not be over 1000';
    END IF;
    /* create the other ckecks in the same way
    If check failed signal an error */
    IF hasError = 1 THEN
        SIGNAL SQLSTATE '45000'
            SET MESSAGE_TEXT = message;
    END IF;
END$$

DELIMITER ;

请注意,使用SIGNAL

需要MYSQL 5.5+

当然,您也可以在应用程序层进行这些检查