Нам нужно обновить различные столбцы в 3 разных таблицах через форму ввода. большая часть этого работает, однако, когда мы пытаемся обновить две другие таблицы, которые были объединены (издатель и категория), он обновляет эту запись и все остальные записи с тем же вводом.
(например, если мы изменим жанр с металла на джаз, то все металлические диски также изменятся на джаз)
Ниже приведен код для обновления.
$sql = "UPDATE nmc_cd, nmc_category, nmc_publisher
SET CDTitle ='$title', CDYear = '$year', nmc_publisher.pubID = '$publisherID', nmc_category.catID = '$categoryID', CDPrice = '$price', pubName ='$pubName', catDesc='$catDesc'
WHERE CDID = $id
AND nmc_category.catID = nmc_cd.catID
AND nmc_publisher.pubID = nmc_cd.pubID";
Я относительно новичок в этом сайте, поэтому, пожалуйста, если что-то, например, код, имена переменных / функций и т. Д. Необходимо, пожалуйста, скажите, и я отредактирую свой пост или ответ.
Заранее спасибо!
Пара рекомендаций.
1) квалифицировать все ссылки на столбцы в операторе SQL, которые ссылаются на несколько таблиц, даже если ссылки на столбцы не являются неоднозначными для MySQL. (Также рассмотрите возможность присвоения короткого псевдонима каждой таблице.) Несколько причин для этого, но одна большая из них заключается в том, что он позволяет читателю узнать, в какой таблице находится каждый столбец, на который ссылаются.
2) отказаться от оператора запятой старой школы для операций соединения и использовать JOIN
ключевое слово. Также переместите предикаты соединения из WHERE
пункт к соответствующему ON
пункт.
3) для множественного обновления, сначала напишите SELECT
утверждение, получить, что работает и проверено, а затем преобразовать это в UPDATE
заявление
4) избегать уязвимостей SQL-инъекций. Предпочтительным шаблоном является использование подготовленных операторов с заполнителями связывания. Или (менее оптимально) как минимум, все потенциально небезопасные значения, включенные в текст SQL, должны быть должным образом экранированы.
Игнорирование уязвимостей SQL-инъекций (при условии, что содержимое переменных уже правильно экранировано) …
Сначала я написал бы инструкцию SELECT, которая возвращает текущие значения столбцов, которые мы планируем обновить, а также новые значения, которые мы планируем назначить этим столбцам. Например:
SELECT cd.cdtitle AS old_cd_cdtitle
, '$title' AS new_cd_cdtitle
, cd.cdyear AS old_cdyear
, '$year' AS new_cdyear
, pub.pubid AS old_pub_pubid
, '$publisherID' AS new_pub_pubid
, cat.catid AS old_cat_catid
, '$categoryID' AS new_cat_catid
, cd.cdprice AS old_cd_cdprice
, '$price' AS new_cd_cdprice
, pub.pubName AS old_pub_pubname
, '$pubName' AS new_pub_pubname
, cat.catDesc AS old_cat_catdesc
, '$catDesc' AS new_cat_catdesc
FROM nmc_cd cd
JOIN nmc_category cat
ON cat.catID = cd.catid
JOIN nmc_publisher pub
ON pub.pubID = cd.pubid
WHERE cd.cdid = $id
(Это всего лишь предположение, я не уверен, чего вы на самом деле пытаетесь достичь.)
Кажется действительно странным присвоить новое значение catid
столбец, на который ссылается предикат соединения. Чтобы сохранить отношения между строками в cd
а также cat
, catid
в столбце в обеих таблицах нужно будет обновить, если мы не зависим от ON UPDATE CASCADE
Правило распространять изменения.
Без понимания того, чего пытается достичь это утверждение, невозможно рекомендовать какое-либо конкретное утверждение.
С точки зрения преобразования SELECT
в UPDATE
заявление, заменить SELECT ... FROM
с ключевым словом UPDATE
,
И до WHERE
пункт, добавить SET
заявление. Взяв выражения для old_cd_cdyear и new_cd_cdyear из списка SELECT, преобразуйте это в предложение SET следующим образом:
SET cd.cdyear = '$year'
При последующих назначениях вместо ключевого слова SET используйте запятую, например,
, cd.cdprice = '$price'
Других решений пока нет …