PHP/MariaDB 使用嵌套 JSON 数组进行重复键更新
PHP/MariaDB On Duplicate Key Update with nested JSON array
所以这个很有趣。我正在将第 3 方 POS 集成到我之前为该客户制作的自定义库存管理软件中。
我的系统是基本的PHP/HTML/JS后台。
我有来自第 3 方系统的 webhooks 向我的站点 JSON 发送有关产品信息和库存详细信息的信息。
我遇到的问题是,当我们在第 3 方系统中更新产品时,我需要将准备好的插入语句设置为在重复密钥上更新。需要检查的KEY是数据库中的第3列,也是table中唯一的Unique Key。
Primary Key 是另一个 ID,不是由 3rd 方系统提供的。
我似乎无法在我的一生中正确地“构建”这个 ON DUPLICATE KEY UPDATE 功能。
这里有一些代码可以让事情变得有意义:
产品信息来自 hook.php,其中包含以下内容:
HOOK.php
<?php
header('Content-Type: application/json');
$request3 = file_get_contents('php://input');
req_dump1 = print_r( $request3, true );
fp = file_put_contents( 'req.json', $req_dump1 );
?>
这给了我以下 JSON:
{
"Id": 8919892,
"Name": "Final",
"Description": "Final",
"CostPrice": 0.95000,
"SalePrice": 756.00000,
"CategoryId": 278333,
"Barcode": "2020202020",
"BrandId": 151102,
"SupplierId": 44815,
"OrderCode": "LKJ-8376594",
"ProductType": 0,
"TareWeight": null,
"ArticleCode": "44-jhaqerkhu",
"Supplier": {
"Id": 44815,
"Name": "House",
"Description": "House",
},
}
然后库存信息的其余部分来自 Stock Detail(为什么他们[第 3 方]将它与 IDK 分开,我没有构建它)点击 hook4.php:
<?php
header('Content-Type: application/json');
$request = file_get_contents('php://input');
$request1=str_replace('[', '', $request);
$request2=str_replace(']', '', $request1);
$req_dump = print_r( $request2, true );
$fp = file_put_contents( 'req4.json', $req_dump );
include('ai.php');
?>
这给了我以下 JSON
REQ4.json
{
"Id": 2553369,
"ProductId": 8919892,
"MinStock": 300,
"ProductStockBatches": {
"Id": 3656516,
"StockId": 2553369,
"CreatedDate": "2021-08-08T03:41:24.153",
"CurrentStock": 225,
"CurrentVolume": 0,
"CostPrice": 0.95000,
}
}
所有这些都很好,问题在于 ai.php:
<?php
$servername = "localhost";
$username = "terblah";
$password = "blah";
$dbname = "blah";
try
{
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $conn->prepare("INSERT INTO blah (name, prod_id, cost, price, brand, vendor_sku, upc, code, on_hand, par, upd_date) VALUES (:name, :prod_id, :cost, :price, :brand, :vendor_sku, :upc, :code, :currentstock, :parstock, :upd_date) ON DUPLICATE KEY UPDATE prod_id = :prod_id");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':prod_id', $prod_id);
$stmt->bindParam(':cost', $cost);
$stmt->bindParam(':price', $price);
$stmt->bindParam(':brand', $brand);
$stmt->bindParam(':vendor_sku', $ven_sku);
$stmt->bindParam(':upc', $upc);
$stmt->bindParam(':code', $code);
$stmt->bindParam(':currentstock', $on_hand);
$stmt->bindParam(':parstock', $par);
$stmt->bindParam(':upd_date', $upd);
$js = file_get_contents('req.json');
$js0 = file_get_contents('req4.json');
$dt = json_decode($js, true);
$dt0 = json_decode($js0, true);
$name = $dt['Name'];
$prod_id = $dt0['ProductId'];
$cost = $dt['CostPrice'];
$price = $dt['SalePrice'];
$brand = $dt['Supplier']['Name'];
$ven_sku = $dt['OrderCode'];
$code = $dt['ArticleCode'];
$upc = $dt['Barcode'];
$on_hand = $dt0['ProductStockBatches']['CurrentStock'];
$par = $dt0['MinStock'];
$upd = $dt0['ProductStockBatches']['CreatedDate'];
$stmt->execute();
}
catch(PDOException $e)
{
echo "Error: " . $e->getMessage();
}
$conn = null;
?>
问题是prod_id = :prod_id
。
我无法将其定义为 $prod_id
,我得到以下结果:
Error: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1
保持原样告诉我:
Error: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'prod_id' cannot be null
我的理解是因为我要求它搜索尚未定义的变量。当我移动定义时,我遇到了绑定错误,因为尚未调用要准备的语句,但我首先需要定义的键....所以我想知道我是否只是在某处遗漏了一个技巧。
我还没有尝试过,但是我想到了在ai.php中调用req4.json2x,首先只是为了定义在重复键情况下要搜索的变量。但是如何在 SQL 语句中间调用一个 '$' 变量呢?
我知道如何调用已定义的变量,但如何从 JSON 中提取该定义,然后将其用作 SQL 语句中的变量?
我可以
$ts = file_get_contents('req4.json');
$js1 = json_decode($ts, true);
$var = $js1['ProductId'];
然后在我的重复密钥更新中
ON DUPLICATE KEY UPDATE (prod_id = ?)
最后
$stmt->execute($var);
我试过了,我得到了
Error: SQLSTATE[HY093]: Invalid parameter number: mixed named and positional parameters
这让我留在这里。
我什至正确地问这个问题吗?
有没有大脑目前无法正常工作的人可以帮帮我吗?
您需要分配给 ON DUPLICATE KEY UPDATE
中的所有 other 列。 prod_id
列是检查重复项的列。
您可以使用 VALUES(colname)
获取本应插入的值。
$stmt = $conn->prepare("
INSERT INTO blah (name, prod_id, cost, price, brand, vendor_sku, upc, code, on_hand, par, upd_date)
VALUES (:name, :prod_id, :cost, :price, :brand, :vendor_sku, :upc, :code, :currentstock, :parstock, :upd_date)
ON DUPLICATE KEY UPDATE
name = VALUES(name), cost = VALUES(cost), price = VALUES(price), brand = VALUES(brand), vendor = VALUES(vendor)_sku = VALUES(sku), upc = VALUES(upc), code = VALUES(code), on = VALUES(on)_hand = VALUES(hand), par = VALUES(par), upd = VALUES(upd)_date = VALUES(date)");
所以这个很有趣。我正在将第 3 方 POS 集成到我之前为该客户制作的自定义库存管理软件中。 我的系统是基本的PHP/HTML/JS后台。 我有来自第 3 方系统的 webhooks 向我的站点 JSON 发送有关产品信息和库存详细信息的信息。 我遇到的问题是,当我们在第 3 方系统中更新产品时,我需要将准备好的插入语句设置为在重复密钥上更新。需要检查的KEY是数据库中的第3列,也是table中唯一的Unique Key。 Primary Key 是另一个 ID,不是由 3rd 方系统提供的。 我似乎无法在我的一生中正确地“构建”这个 ON DUPLICATE KEY UPDATE 功能。
这里有一些代码可以让事情变得有意义: 产品信息来自 hook.php,其中包含以下内容:
HOOK.php
<?php
header('Content-Type: application/json');
$request3 = file_get_contents('php://input');
req_dump1 = print_r( $request3, true );
fp = file_put_contents( 'req.json', $req_dump1 );
?>
这给了我以下 JSON:
{
"Id": 8919892,
"Name": "Final",
"Description": "Final",
"CostPrice": 0.95000,
"SalePrice": 756.00000,
"CategoryId": 278333,
"Barcode": "2020202020",
"BrandId": 151102,
"SupplierId": 44815,
"OrderCode": "LKJ-8376594",
"ProductType": 0,
"TareWeight": null,
"ArticleCode": "44-jhaqerkhu",
"Supplier": {
"Id": 44815,
"Name": "House",
"Description": "House",
},
}
然后库存信息的其余部分来自 Stock Detail(为什么他们[第 3 方]将它与 IDK 分开,我没有构建它)点击 hook4.php:
<?php
header('Content-Type: application/json');
$request = file_get_contents('php://input');
$request1=str_replace('[', '', $request);
$request2=str_replace(']', '', $request1);
$req_dump = print_r( $request2, true );
$fp = file_put_contents( 'req4.json', $req_dump );
include('ai.php');
?>
这给了我以下 JSON
REQ4.json
{
"Id": 2553369,
"ProductId": 8919892,
"MinStock": 300,
"ProductStockBatches": {
"Id": 3656516,
"StockId": 2553369,
"CreatedDate": "2021-08-08T03:41:24.153",
"CurrentStock": 225,
"CurrentVolume": 0,
"CostPrice": 0.95000,
}
}
所有这些都很好,问题在于 ai.php:
<?php
$servername = "localhost";
$username = "terblah";
$password = "blah";
$dbname = "blah";
try
{
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $conn->prepare("INSERT INTO blah (name, prod_id, cost, price, brand, vendor_sku, upc, code, on_hand, par, upd_date) VALUES (:name, :prod_id, :cost, :price, :brand, :vendor_sku, :upc, :code, :currentstock, :parstock, :upd_date) ON DUPLICATE KEY UPDATE prod_id = :prod_id");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':prod_id', $prod_id);
$stmt->bindParam(':cost', $cost);
$stmt->bindParam(':price', $price);
$stmt->bindParam(':brand', $brand);
$stmt->bindParam(':vendor_sku', $ven_sku);
$stmt->bindParam(':upc', $upc);
$stmt->bindParam(':code', $code);
$stmt->bindParam(':currentstock', $on_hand);
$stmt->bindParam(':parstock', $par);
$stmt->bindParam(':upd_date', $upd);
$js = file_get_contents('req.json');
$js0 = file_get_contents('req4.json');
$dt = json_decode($js, true);
$dt0 = json_decode($js0, true);
$name = $dt['Name'];
$prod_id = $dt0['ProductId'];
$cost = $dt['CostPrice'];
$price = $dt['SalePrice'];
$brand = $dt['Supplier']['Name'];
$ven_sku = $dt['OrderCode'];
$code = $dt['ArticleCode'];
$upc = $dt['Barcode'];
$on_hand = $dt0['ProductStockBatches']['CurrentStock'];
$par = $dt0['MinStock'];
$upd = $dt0['ProductStockBatches']['CreatedDate'];
$stmt->execute();
}
catch(PDOException $e)
{
echo "Error: " . $e->getMessage();
}
$conn = null;
?>
问题是prod_id = :prod_id
。
我无法将其定义为 $prod_id
,我得到以下结果:
Error: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1
保持原样告诉我:
Error: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'prod_id' cannot be null
我的理解是因为我要求它搜索尚未定义的变量。当我移动定义时,我遇到了绑定错误,因为尚未调用要准备的语句,但我首先需要定义的键....所以我想知道我是否只是在某处遗漏了一个技巧。
我还没有尝试过,但是我想到了在ai.php中调用req4.json2x,首先只是为了定义在重复键情况下要搜索的变量。但是如何在 SQL 语句中间调用一个 '$' 变量呢? 我知道如何调用已定义的变量,但如何从 JSON 中提取该定义,然后将其用作 SQL 语句中的变量?
我可以
$ts = file_get_contents('req4.json');
$js1 = json_decode($ts, true);
$var = $js1['ProductId'];
然后在我的重复密钥更新中
ON DUPLICATE KEY UPDATE (prod_id = ?)
最后
$stmt->execute($var);
我试过了,我得到了
Error: SQLSTATE[HY093]: Invalid parameter number: mixed named and positional parameters
这让我留在这里。 我什至正确地问这个问题吗? 有没有大脑目前无法正常工作的人可以帮帮我吗?
您需要分配给 ON DUPLICATE KEY UPDATE
中的所有 other 列。 prod_id
列是检查重复项的列。
您可以使用 VALUES(colname)
获取本应插入的值。
$stmt = $conn->prepare("
INSERT INTO blah (name, prod_id, cost, price, brand, vendor_sku, upc, code, on_hand, par, upd_date)
VALUES (:name, :prod_id, :cost, :price, :brand, :vendor_sku, :upc, :code, :currentstock, :parstock, :upd_date)
ON DUPLICATE KEY UPDATE
name = VALUES(name), cost = VALUES(cost), price = VALUES(price), brand = VALUES(brand), vendor = VALUES(vendor)_sku = VALUES(sku), upc = VALUES(upc), code = VALUES(code), on = VALUES(on)_hand = VALUES(hand), par = VALUES(par), upd = VALUES(upd)_date = VALUES(date)");