繁体   English   中英

使用 JSON 数组作为值时 MySQL 语法错误

[英]MySQL Syntax Error when using JSON array as value

我的表:

  • customer_id INT(主键)
  • 购买_产品 JSON
  • 已退款产品 = JSON

预期值

  • 12345
  • ["32","33","34"]
  • ["31","38","39"]

以下 SQL 按预期工作。 伟大的!

 -- Insert a new row into the purchased products table
INSERT INTO dc_purchased_products (
    user_id, -- INT
    purchased_products -- JSON
)

-- 1) The user ID (primary key)
-- 2) Formatted json array with the first purchased product ID
VALUES ( 12345, '["36"]' )

-- If the user id already exists, append the existing array with the product ID
ON DUPLICATE KEY UPDATE 

-- JSON_ARRAY_INSERT(existing purchases array, index, product_id)
purchased_products = JSON_ARRAY_INSERT(purchased_products, '$[0]', "36") 

但是,我的应用程序中的 PDO 语句并不是那么好。

$item = [
  'statement' => "INSERT INTO purchased_products 
                        (customer_id, purchased_products) 
                  VALUES(:customer_id, [:purchased_products]) 
                    ON DUPLICATE KEY 
                    UPDATE purchased_products = JSON_ARRAY_INSERT(purchased_products, '$[0]',:purchased_products)",
  'data' => [
    ['customer_id' => 12345, 'purchased_products' => '"36"'],
    ['customer_id' => 12345, 'purchased_products' => '"37"']
  ]
]


我的连接

$this->connection = new PDO("mysql:host=$servername;dbname=$database", $u, $p, [
  PDO::MYSQL_ATTR_SSL_KEY                => $ck,
  PDO::MYSQL_ATTR_SSL_CERT               => $cc,
  PDO::MYSQL_ATTR_SSL_CA                 => $sc,
  PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false,
]);

$this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);


$statement = $this->connection->prepare($item['statement']);
foreach ($item['data'] as $rowData) {

    foreach ($rowData as $key => $param) {
        $statement->bindValue(':' . $key, $param);
    }

    try {
        $success = $statement->execute();
    }

    catch (PDOException $e) {
        pre($e->getMessage());        
    }

}

错误信息

SQLSTATE[42000]:语法错误或访问冲突:1064 您的 SQL 语法有错误; 检查与您的 MySQL 服务器版本相对应的手册,了解在 '['3784835']) 附近使用的正确语法 ON DUPLICATE KEY UPDATE purchase_products = JSON_ARRAY_INSERT(purc' 在第 1 行

这应该可以解决问题:

$item = [
  'statement' => "INSERT INTO purchased_products 
                        (customer_id, purchased_products) 
                  VALUES(:customer_id, :purchased_products) 
                    ON DUPLICATE KEY 
                    UPDATE purchased_products = JSON_ARRAY_INSERT(purchased_products, '$[0]',:purchased_products_json)",
  'data' => [
    ['customer_id' => 12345, 'purchased_products' => '["36"]', 'purchased_products_json' => '36'],
    ['customer_id' => 12345, 'purchased_products' => '["37"]', 'purchased_products_json' => '37'],
  ]
];

变更说明:

[ ] VALUES(:customer_id, [:purchased_products])中的 [ 和 ]

现在看起来像这样:

VALUES(:customer_id, :purchased_products)

此更改将避免execute()期间的错误。

JSON_ARRAY_INSERT 中的新参数:购买的_products_json

现在看起来像这样:

JSON_ARRAY_INSERT(purchased_products, '$[0]',:purchased_products_json)

为了避免错误,现在我们需要两个差异很小的参数。 一个用于插入( purchased_products的产品)和另一个用于更新( purchased_produtcs_json的产品json),因为尽管值相同,但它们具有不同的格式。

data数组中,更改了'purchased_products' => '"36"'

现在看起来像这样:

'purchased_products' => '["36"]'

因为我们将在 INSERT 语句中使用它,我们需要将其设置为新的 JSON 数组值,格式正确,因为我们已经删除了前面 INSERT 语句中的[]

data数组中,添加了新参数: 'purchased_products_json'

为了更新字段,值格式应该不同,所以我们需要这个新参数。 它看起来像这样:

'purchased_products_json' => '36'

避免使用[] 您可以在mariadb 文档中看到有关 JSON_ARRAY_INSERT 的一些信息

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM