我有下面的PHP代码,它可以完美地工作 ($qry_str实际上是在PHP中生成的):
$qry_str = <<<'QRY'
FIND_IN_SET('6-47', attributes)
AND FIND_IN_SET('4-176', attributes)
AND FIND_IN_SET('9-218', attributes)
QRY;
$pdo->query('DROP TEMPORARY TABLE IF EXISTS `temp_attr`');
$temp_sql = <<<"TEMP"
CREATE TEMPORARY TABLE IF NOT EXISTS `temp_attr` (
SELECT product_id, GROUP_CONCAT(CONCAT(group_id, '-', IF (custom_value != '', custom_value, value_id)) SEPARATOR ',') AS attributes
FROM `products_attributes`
GROUP BY `product_id`
HAVING $qry_str
);
TEMP;
$pdo->query($temp_sql);
$sql = "SELECT
m.recommended_price AS msrp,
m.purchase_price AS cost,
pp.USD AS regular_price,
pc.USD AS special_price,
pc.start_date AS start_date,
pc.end_date AS end_date,
pl.permalink AS permalink,
pi.name AS description,
m.sku AS sku,
m.default_category_id AS cat,
m.id AS prod_id
FROM `products` AS m
LEFT JOIN `products_prices` AS pp ON m.id = pp.product_id
LEFT JOIN `products_campaigns` AS pc ON m.id = pc.product_id
LEFT JOIN `permalinks` AS pl ON (m.id = pl.resource_id AND pl.resource = 'product')
LEFT JOIN `products_info` AS pi ON (m.id = pi.product_id)
LEFT JOIN `products_to_categories` AS ptc ON (m.id = ptc.product_id)
INNER JOIN `temp_attr` AS pa
WHERE ptc.category_id = :cat
AND m.status = 1
AND m.id = pa.product_id
LIMIT 55;
";
$data = $pdo->prepare($sql)
->bindValue('cat', 100)
->execute()
->fetchAll();
但是,当我在临时表代码中使用占位符(即
$temp_sql = <<<"TEMP"
CREATE TEMPORARY TABLE IF NOT EXISTS `temp_attr` (
SELECT product_id, GROUP_CONCAT(CONCAT(group_id, '-', IF (custom_value != '', custom_value, value_id)) SEPARATOR ',') AS attributes
FROM `products_attributes`
GROUP BY `product_id`
HAVING :qry_str
);
TEMP;
$sth = $pdo->prepare($temp_sql);
$sth->bindValue('qry_str', $qry_str, PDO::PARAM_STR);
$sth->execute();
出现以下错误:
PHP致命错误:未捕获的PDO异常:SQLSTATE[22007年]:无效的日期时间格式:1292截断了不正确的DOUBLE值:“查找输入集(”6 - 47“,属性)AND查找输入集(”4 - 176“,属性)AND查找输入集(”9 - 218“,属性)AND查找输入集(...”
此表中没有日期时间列。group_id
和value_id
是整数列
由于没有占位符代码也能正常工作,我不明白为什么使用占位符会破坏代码。主SQL中的占位符工作正常。
PHP 8.0语言
1条答案
按热度按时间eit6fx6z1#
https://dev.mysql.com/doc/refman/8.0/en/prepare.html说明:
参数标记只能用于数据值应该出现的位置,而不能用于SQL关键字、标识符等。
在您的例子中,您显然是在尝试将表达式与
FIND_IN_SET()
函数绑定。您不能这样做。在准备查询时,必须在查询中固定所有表达式和其他SQL语法。您只能在使用标量文字值的地方使用参数。即,带引号的字符串或数字文字。