在多个 "NOT IN" 子句中使用变量

Using variables in multiple "NOT IN" clauses

我就是做错了。作为爱好程序员做一个爱好项目。这是我在 php 网页上使用的 MySQL 语句:

$stmt = $mysqli->prepare("SELECT t1.* FROM laptimes t1
JOIN (
SELECT gamertag, track, vehicle, vehicleclass, platform, controller, setup, 
MIN(laptime) AS min_laptime
FROM laptimes 
WHERE track LIKE ? AND vehicle LIKE ? AND vehicleclass LIKE ? AND platform 
NOT IN ('PS4','XB1') AND controller NOT IN ('Gamepad','Keyboard') AND setup 
NOT IN ('Custom') 
GROUP BY gamertag, vehicle, vehicleclass
) AS t2 ON t1.gamertag = t2.gamertag AND t1.laptime = t2.min_laptime AND 
t1.track = t2.track AND t1.vehicle = t2.vehicle AND t1.vehicleclass = 
t2.vehicleclass AND t1.platform = t2.platform AND t1.controller = 
t2.controller AND t1.setup = t2.setup
ORDER BY laptime ASC LIMIT ? OFFSET ?");
$stmt->bind_param("sssii", $trackselect, $carselect ,$classelect, $limit, $offset); 
$stmt->execute();

以上代码,带有一些硬编码值,工作正常。它为排行榜的每个玩家获得最佳单圈时间。它排除了平台值 'PS4' 或 'XB1'、控制器值 'Gamepad' 或 'Keyboard' 以及设置值 'Custom' 的结果。但我想做的是用变量替换 WHERE 子句中的硬编码值。我可以用 ?对于轨道、车辆、车辆类别以及限制和偏移,使用绑定参数,没问题。但是对于平台、控制器和设置,我不能使用变量,尽管代码可以很好地处理硬编码值。

三个 NOT IN 子句正在排除具有这些值的记录。在该示例中,platform NOT IN ('PS4',XB1') 排除了 'platform' 列中具有 PC 或 PS4 值的结果。我想使用 $platform、$controller、$setup 而不是硬编码值。我已经尝试了大括号、圆括号、反引号、撇号、双引号的所有组合;似乎没有任何效果。

如果我在例如 $platform 上打印值,它会显示:'PS4','XB1'(只是一个例子,值是由复选框设置的。所以它看起来等于我的硬编码值。

如果我将硬编码值替换为 ? (相应地调整 bind_param),结果不会排除任何内容,即使我勾选了复选框(我打印了 $platform、$controller、$setup 的值,它看起来是正确的)。

如果我改为这样做:platform NOT IN ($platform) 那么它就可以工作。但是,如果我对控制器和设置执行相同的操作,controller NOT IN ($controller) AND setup NOT IN ($setup) 我会收到此错误消息: Fatal error: Call to a member function bind_param() on a non-object 指向带有 bind_param 的行。我已经调整了 bind_param 行以更正 "sss" 和 $variables.

的数量

那么如何使用变量而不是硬编码值呢?

我在这边太离谱了,我无法理解。打印的变量值与硬编码示例完全一样。我需要一种特殊的括号,还是某种魔术酱?我不知道。 希望我已经很好地解释了这个问题。如果没有,请告诉我,我会再试一次。

如果字符串中有一个逗号分隔的值列表,您可以使用 FIND_IN_SET() 来匹配其中一个值。您使用绑定参数作为列表中的字符串。

所以使用:

$controller = 'Gamepad,Keyboard';
$platform = 'PS4,XB1';
$setup = 'Custom';

然后让您的查询使用:

AND NOT FIND_IN_SET(platform, ?) 
AND NOT FIND_IN_SET(controller, ?) 
AND NOT FIND_IN_SET(setup, ?)

并将这些参数绑定到上述变量。

您正试图将 IN() 中的多个值与一个变量绑定。参数化需要文字值与绑定值的一对一匹配。因此,您的以下尝试:

$platform = "'PS4','XB1'"
...

WHERE ... platform NOT IN (?)

应替换为:

$platform1 = 'PS4'
$platform2 = 'XB1'
...

WHERE ... platform NOT IN (?, ?)

您可能希望在 IN() 中动态放置 qmark 并动态绑定需要使用数组操作的多个变量。 SO:

上的 PHP 中多次询问并回答了此类问题