Я работаю над этой проблемой в течение 3 дней, и у меня мутные глаза.
У меня есть таблица SQL «клиенты», содержащая имя клиента, адрес, адрес электронной почты и поле с именем «место проведения», содержащее набор разделенных запятыми идентификаторов мест проведения учебных курсов, в которых они заинтересованы. (Например: 18, 22,35,41)
У меня есть второй стол, называемый «место проведения», который содержит места проведения всех курсов.
Каждый курс представляет собой отдельную строку в таблице «место проведения» с идентификатором автоинкремента.
Поле места в таблице «клиенты» представляет собой набор строки «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)";
Пожалуйста, задавайте любые вопросы, спасибо за внимание
Я думаю, что вы должны написать этот код как:
$sqlcp = "SELECT * FROM venue WHERE FIND_IN_SET(id,'$venue')";
Теперь, если я не понимаю вопрос:
поле [input] с именем «place», содержащее набор, разделенный запятыми
Другими словами мы можем сказать $result['venue']
как 1,2,3,4
,
И тогда этот бит:
У меня есть второй стол, называемый «место проведения», который содержит места проведения всех курсов. Каждый курс — это отдельный ряд
Другими словами, мы можем сказать, что id
является первичным ключом места.
Таким образом, кажется, что ваш ввод — это отдельный список, а ваша таблица имеет правильные идентификаторы. для этого мы можем только мы IN
и предоставить список идентификаторов.
Конечно, вы можете просто вставить их в запрос в этом случае (для идентификаторов не нужны кавычки в 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)
Постскриптум внедрение Mutli-запроса, вероятно, не будет работать в любом случае с «современной» версией 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
,
Ура!