PDO, используя кавычки в подготовленных операторах для вызова mysql процедуры? - PullRequest
0 голосов
/ 12 апреля 2020

мне нужно выполнить следующий MYSQL вызов процедуры в следующем формате

CALL inTable(table_name,'<csv of columns>','csv of values');

пример для запуска с подготовленным оператором в php

CALL inTable(users,'name,email',' ? , ? ');

процедура подготавливает mysql запрос, который используется для проверки наличия набора значений, разделенных запятыми в 3-м аргументе, в соответствующих именах столбцов, разделенных запятыми, во 2-м аргументе.

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

это то, что готовит моя процедура, которая получает? заполнители как есть;

SELECT COUNT(*) AS take FROM `users` WHERE (`username`,`email') IN (('?','?'));

с использованием следующего php кода

$s = self::$handle->prepare("CALL inTable('users','phone,email',' ?,? );");
$s->bindParam(1,$phone, PDO::PARAM_STR);
$s->bindParam(2,$email, PDO::PARAM_STR);
$s->execute();
$s->fetchAll();

Должен ли я опубликовать код для mysql процедуры, которую я использую?

tableExists проверяет, существует ли имя таблицы в db. isCommand проверяет через regexp, существуют ли команды изменения в аргументе, у которого выше указано «r» в качестве аргумента OUT.

DELIMITER $$
DROP PROCEDURE IF EXISTS inTable $$
CREATE PROCEDURE inTable(t VARCHAR(64),col VARCHAR(1024), val VARCHAR(1024))
BEGIN
    DECLARE r INT DEFAULT NULL;
    DECLARE c VARCHAR(256) DEFAULT NULL;
    DECLARE v VARCHAR(256) DEFAULT NULL;
    DECLARE cl VARCHAR(1024) DEFAULT '';
    DECLARE vl VARCHAR(1024) DEFAULT '';
    DECLARE s TEXT DEFAULT 'SELECT COUNT(*) AS take FROM ';

    CALL tableExists(t,r);

    SET col = TRIM(col);
    SET val = TRIM(val);

    IF r = 1 THEN
        SET r = 0;
        colmn: LOOP
            IF LENGTH(col) = 0 OR col IS NULL OR LENGTH(val) = 0 OR val IS NULL THEN
                LEAVE colmn;
            END IF;

            SET c = SUBSTRING_INDEX(col,',',1);
            SET v = SUBSTRING_INDEX(val,',',1);

            CALL isCommand(c,r);
            IF r = 1 THEN
                LEAVE colmn;
            END IF;
            CALL isCommand(v,r);
            IF r = 1 THEN
                LEAVE colmn;
            END IF;

            IF r = 0 THEN
                SET cl = CONCAT(cl,'`',REPLACE(c,' ',''),'`,');
                SET vl = CONCAT(vl,'\'',TRIM(v),'\',');
                SET col = INSERT(col,1,LENGTH(c) + 1,'');
                SET val = INSERT(val,1,LENGTH(v) + 1,'');               
            END IF;
        END LOOP;
    END IF;

    IF r = 0 THEN
        SET cl = CONCAT('(',INSERT(cl,LENGTH(cl),1,''),')');
        SET vl = CONCAT('((',INSERT(vl,LENGTH(vl),1,''),'))');
        SET @s = CONCAT(s,'`',t,'` WHERE ',cl,' IN ',vl,';');
        SELECT @s;
        PREPARE s FROM @s;
        EXECUTE s;
        DEALLOCATE PREPARE s;
    END IF;
END $$
DELIMITER ; 

1 Ответ

0 голосов
/ 12 апреля 2020

Вы не можете привязать несколько параметров к одному параметру. Это нарушит уровень привязки параметров защиты. Таким образом, в вашей процедуре доступен только один параметр, но вы говорите своему оператору подготовки о принятии еще двух параметров с ?, ?.

Вам не нужны отдельные переменные для привязки. Просто сложите их вместе как запятые в PHP:

$binding = "$phone,$email";
$s = self::$handle->prepare("CALL inTable('users','phone,email', ?);");
$s->bindParam(1, $binding, PDO::PARAM_STR);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...