Я создал оператор обновления в PHP, используя PDO, однако я продолжаю получать эту ошибку.

ERROR: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens

Я считал и пересчитывал (25) и потратил некоторое время на то, чтобы убедиться, что мой синтаксис верен, и я не могу понять, что я делаю неправильно.

Вот код:

$sql = "UPDATE :tablename
        SET entryName = :entryname,
        entryAdd1 = : add1,
        entryAdd2 = :add2,
        entryCity = :city,
        entryCounty = :county,
        entryCountry = :country,
        entryPC = :postcode,
        entryPhone = :phone,
        entryEmail = :email,
        entryURL = :entryurl,
        entryDesc = :entryDesc,
        entryImg = :entryimg,
        entryStar  = :star,
        entryCuststar = :custstar,
        chains = :chains,
        cafe = :cafe,
        fishandchips = :fishandchips,
        indian = :indian,
        itallian = :italian,
        pizzeria = :pizzeria,
        tapas = :tapas,
        tearooms = :tearooms
        WHERE :colname = :entryid";

        $statement = $conn->prepare($sql);

        $statement->bindParam(":tablename", $tablename, PDO::PARAM_STR);

        $statement->bindParam(":entryname", $entryname, PDO::PARAM_STR);
        $statement->bindParam(":add1", $add1, PDO::PARAM_STR);
        $statement->bindParam(":add2", $add2, PDO::PARAM_STR);
        $statement->bindParam(":city", $entrytown, PDO::PARAM_STR);
        $statement->bindParam(":county", $entrycounty, PDO::PARAM_STR);
        $statement->bindParam(":country", $entrycountry, PDO::PARAM_STR);
        $statement->bindParam(":postcode", $entrypostcode, PDO::PARAM_STR);
        $statement->bindParam(":phone", $entryphone, PDO::PARAM_STR);
        $statement->bindParam(":email", $entryemail, PDO::PARAM_STR);
        $statement->bindParam(":entryurl", $entryurl, PDO::PARAM_STR);
        $statement->bindParam(":entryDesc", $entrydesc, PDO::PARAM_STR);
        $statement->bindParam(":entryimg", $entryicon, PDO::PARAM_STR);
        $statement->bindParam(":star", $star, PDO::PARAM_STR);
        $statement->bindParam(":custstar", $custstar, PDO::PARAM_STR);
        $statement->bindParam(":chains", $chains, PDO::PARAM_INT);
        $statement->bindParam(":cafe", $cafe, PDO::PARAM_INT);
        $statement->bindParam(":fishandchips", $fishchips, PDO::PARAM_INT);
        $statement->bindParam(":indian", $indian, PDO::PARAM_INT);
        $statement->bindParam(":italian", $italian, PDO::PARAM_INT);
        $statement->bindParam(":pizzeria", $pizzeria, PDO::PARAM_INT);
        $statement->bindParam(":tapas", $tapas, PDO::PARAM_INT);
        $statement->bindParam(":tearooms", $tearooms, PDO::PARAM_INT);

        $statement->bindParam(":colname", $colname, PDO::PARAM_STR);
        $statement->bindParam(":entryid", $entryid, PDO::PARAM_INT);

        $count = $statement->execute();

Я указываю переменную $conn выше, это просто каталог для практики, который я создавал. Если бы кто-нибудь мог указать мне в правильном направлении, я был бы признателен.

0
AltTab 8 Дек 2014 в 19:19
2
Вы не можете параметризовать имена таблиц/столбцов, результирующий запрос будет содержать кавычки UPDATE 'table_name' ...!
 – 
andrew
8 Дек 2014 в 19:24
1
И я не знаю, имеет ли это значение, но у вас есть лишнее место здесь entryAdd1 = : add1,
 – 
vaso123
8 Дек 2014 в 19:25
Если я жестко закодирую имя таблицы и имя столбца, я получаю ту же ошибку, я не оспариваю вашу правоту, просто кажется, что это не имеет значения для этой ошибки. Но спасибо за объяснение, я только что сделал что-то подобное раньше.
 – 
AltTab
8 Дек 2014 в 19:30
Я думаю, что @lolka_bolka заметил, почему количество параметров не совпадает
 – 
andrew
8 Дек 2014 в 19:31
Когда вы жестко запрограммировали имя таблицы и имя столбца, обязательно ли вы удалили эти два оператора bindParam?
 – 
versalle88
8 Дек 2014 в 19:33

2 ответа

Имена таблиц и столбцов не могут быть заменены параметрами в PDO. Вам придется заменить их реальными именами, конечно, вы можете отфильтровать нежелательные данные, если хотите, но не с помощью подготовленных операторов.

Не получится:

$sth = $dbh->prepare('SELECT name, colour, calories FROM ?  WHERE calories < ?');

ЭТО РАБОТАЕТ!

$sth = $dbh->prepare('SELECT name, colour, calories FROM fruit WHERE calories < ?');
1
Jordy 8 Дек 2014 в 19:29
Просто для уточнения: это относится к частям UPDATE :tablename и WHERE :colname запроса.
 – 
VolkerK
8 Дек 2014 в 19:31

Вы не можете параметризовать имена таблиц/столбцов. Попробуйте это, если вам нужно, чтобы они были динамическими:

$sql = "UPDATE " . $tablename . "
    SET entryName   = :entryname,
    entryAdd1       = :add1,
    entryAdd2       = :add2,
    entryCity       = :city,
    entryCounty     = :county,
    entryCountry    = :country,
    entryPC         = :postcode,
    entryPhone      = :phone,
    entryEmail      = :email,
    entryURL        = :entryurl,
    entryDesc       = :entryDesc,
    entryImg        = :entryimg,
    entryStar       = :star,
    entryCuststar   = :custstar,
    chains          = :chains,
    cafe            = :cafe,
    fishandchips    = :fishandchips,
    indian          = :indian,
    itallian        = :italian,
    pizzeria        = :pizzeria,
    tapas           = :tapas,
    tearooms        = :tearooms
    WHERE " . $colname . " = :entryid";

    $statement = $conn->prepare($sql);

    $statement->bindParam(":entryname", $entryname, PDO::PARAM_STR);
    $statement->bindParam(":add1", $add1, PDO::PARAM_STR);
    $statement->bindParam(":add2", $add2, PDO::PARAM_STR);
    $statement->bindParam(":city", $entrytown, PDO::PARAM_STR);
    $statement->bindParam(":county", $entrycounty, PDO::PARAM_STR);
    $statement->bindParam(":country", $entrycountry, PDO::PARAM_STR);
    $statement->bindParam(":postcode", $entrypostcode, PDO::PARAM_STR);
    $statement->bindParam(":phone", $entryphone, PDO::PARAM_STR);
    $statement->bindParam(":email", $entryemail, PDO::PARAM_STR);
    $statement->bindParam(":entryurl", $entryurl, PDO::PARAM_STR);
    $statement->bindParam(":entryDesc", $entrydesc, PDO::PARAM_STR);
    $statement->bindParam(":entryimg", $entryicon, PDO::PARAM_STR);
    $statement->bindParam(":star", $star, PDO::PARAM_STR);
    $statement->bindParam(":custstar", $custstar, PDO::PARAM_STR);
    $statement->bindParam(":chains", $chains, PDO::PARAM_INT);
    $statement->bindParam(":cafe", $cafe, PDO::PARAM_INT);
    $statement->bindParam(":fishandchips", $fishchips, PDO::PARAM_INT);
    $statement->bindParam(":indian", $indian, PDO::PARAM_INT);
    $statement->bindParam(":italian", $italian, PDO::PARAM_INT);
    $statement->bindParam(":pizzeria", $pizzeria, PDO::PARAM_INT);
    $statement->bindParam(":tapas", $tapas, PDO::PARAM_INT);
    $statement->bindParam(":tearooms", $tearooms, PDO::PARAM_INT);

    $statement->bindParam(":entryid", $entryid, PDO::PARAM_INT);

    $count = $statement->execute();

Благодарность,

Андрей

0
versalle88 8 Дек 2014 в 19:42
Будьте осторожны с тем, откуда берется $tablename, вы не хотите вводить уязвимости внедрения
 – 
andrew
8 Дек 2014 в 20:03