我已经在这个问题上工作了3天,并且眼神呆滞。 我有一个SQL“客户”表,其中包含客户名称,地址,电子邮件,以及一个名为“ venue”的字段,其中包含以逗号分隔的一组他们感兴趣的培训地点的“ id”。(例如:18, 22,35,41)
我还有一个名为“ venue”的表,其中包含所有课程的地点。 每个课程在“地点”表中都是单独的行,并带有自动递增的ID。 “客户”表中的场所字段是场所表中客户在注册时选择的“ id”行的集合。
将客户注册并转移到“我的兴趣”页面后,我想通过输出所保存的“场地”表中每个“ id”的行数据来显示他们已注册感兴趣的课程在客户表的“ customer.venue”字段中。
我希望这是有道理的...
我的客户选择
$sqlc = "Select * from customers ORDER BY id DESC LIMIT 1";
我的场地选择
$venue = $result['venue'];
我当前的“场地”选择代码不起作用
sqlcp = "SELECT * FROM venue WHERE FIND_IN_SET('$venue', id)";
请问任何需要的问题,感谢您的关注
答案 0 :(得分:1)
现在,除非我误解了这个问题:
称为“地点”的字段[输入]包含逗号分隔的集合
换句话说,我们可以说$result['venue']
就像1,2,3,4
。
然后这一点:
我还有一个名为“ venue”的表,其中包含所有课程的地点。每门课程都是单独的一行
换句话说,我们可以说id
是场所的主键。
所以看来您的输入是分隔列表,并且您的表具有正确的ID。为此,我们可以只IN
并提供ID列表。
可以肯定的是,在这种情况下,您只需将它们插入查询中即可(id不需要IN中的引号),但这完全没有故障保护。
例如:
//Please don't do this as you can get SQLInjection from the input
$sql = "SELECT * FROM venue WHERE id IN (".$result['venue'].")";
相反,请执行以下操作:
$venue = implode(',',array_map('intval',array_filter(array_map('trim', explode(',',$result['venue'])))));
$sql = "SELECT * FROM venue WHERE id IN (".$venue.")";
通常我不会串联,但是请注意array_map('intval', ..)
会将其转换为整数。
要解释对数组所做的所有操作(按顺序):
,
炸毁,
逗号会留下空白,,
空笔记0
就是其中的一部分int
有几个原因。这似乎有点多余,但是可以清理用户提供的输入。例如,考虑以下内容:
$v="1,,2 , 4); DROP TABLE users --";
echo "Unsafe:\n";
echo "SELECT * FROM venue WHERE id IN ({$v})\n\n";
$venue = implode(',',array_map('intval',array_filter(array_map('trim', explode(',',$v)))));
print_r($venue);
echo "Safer:\n";
echo "SELECT * FROM venue WHERE id IN ({$venue})\n\n";
输出
Unsafe:
SELECT * FROM venue WHERE id IN (1,,2 , 4); DROP TABLE users --)
Safer:
SELECT * FROM venue WHERE id IN (1,2,4)
P.S。 mutli-query注入可能无论如何都不适用于PHP的“现代”版本,但这只是一个示例
在性能方面,这样做会更好,因为它可以正确使用场所中的索引。
我认为您已经使它复杂化了。
@Taha Asgari 是正确的,因为您的论点倒退了。这是一个简单的错误,因为它是要在列表中的数据库中查找内容。并非相反,或者至少这是它的常用方式。
一个例子是这样的:
//this is the correct way
SELECT * FROM venue WHERE FIND_IN_SET(1,'1,2,3,4')
//this is the way you have it
SELECT * FROM venue WHERE FIND_IN_SET('1,2,3,4', 1)
供参考FIND_IN_SET
也就是说,在这种情况下我们不需要使用FIND_IN_SET
,因为我们可以只使用IN,在这种情况下更“合适”。
最后是,如果将这些存储在与客户的关系表中并存储在单独的表中,则可以在MySql中完成所有操作。数据库中的CSV数据通常效果不佳。您只需要一个包含2列的表格。
//table customers_venues
customer_id
venue_id
然后您可以执行以下查询:
Select
cv.venue
from
customers AS c
JOIN
customers_venues AS cv ON cv.customer_id = c.id
JOIN
venues as v ON cv.venue_id = v.id
但是我不知道该怎么说LIMIT 1
。
干杯!
答案 1 :(得分:0)
我认为您应该像这样编写这段代码:
$sqlcp = "SELECT * FROM venue WHERE FIND_IN_SET(id,'$venue')";