Можно ли использовать именованные заполнители в DBI selectcol_arrayref & Co.? - PullRequest
3 голосов
/ 25 декабря 2011

Возможно ли как-то использовать именованные заполнители, где DBI позволяет @bind_values? Например, я хотел бы сделать заявления как:

my $s = $DB->selectcol_arrayref ("SELECT a FROM b
                                  WHERE c = ? OR d = ? OR e = ?;",
                                  {},
                                  $par1, $par2, $par1) or
        die ($DB->errstr ());

менее подвержен ошибкам. Я использую DBD :: Pg и DBD :: SQLite.

1 Ответ

6 голосов
/ 25 декабря 2011

Какие типы заполнителей (если они есть) поддерживаются зависит от драйвера :

Заполнители и значения связывания

Некоторые драйверы поддерживают заполнители и значения привязки.
[...]
Некоторые драйверы также позволяют заполнители, такие как : имя и : N (например, : 1 , : 2 и т. Д.) В дополнение до ? , но их использование не переносимо.

Но вам повезло, драйвер PostgreSQL поддерживает именованные или пронумерованные параметры:

В DBD :: Pg можно использовать три типа заполнителей. Первым является тип «вопросительный знак», в котором каждый заполнитель представлен одним символом вопросительного знака.
[...]
Метод второго типа заполнителя - «цифры знака доллара».
[...]
Последний тип заполнителя - «именованные параметры» в формате «: foo».

И драйвер SQLite также поддерживает их:

SQLite поддерживает несколько выражений-заполнителей, в том числе? и: AAAA.

Недостатком является то, что вы в конечном итоге будете использовать bind_param с указанными параметрами, поэтому вы не сможете использовать такие удобства, как selectcol_arrayref и $sth->execute(1,2,3) ( Примечание: Если кто-нибудь знает, как использовать именованные заполнители с execute Я был бы признателен за некоторые указатели в комментарии, я так и не понял, как это сделать). Однако вы можете использовать различные формы заполнителей чисел (например, select c from t where x = $1 для PostgreSQL или select c from t where x = ?1 для SQLite).

Также следует помнить, что PostgreSQL использует двоеточия для фрагментов массива и вопросительные знаки для некоторых операторов, поэтому иногда стандартные ? заполнители и : name именованные заполнители могут вызывать проблемы. У меня никогда не было проблем с ? , но я также никогда не использовал геометрические операторы ; Я подозреваю, что разумное использование пробелов позволит избежать любых проблем с ? . Если вы не используете массивы PostgreSQL, то вам, вероятно, не нужно беспокоиться о кусочках массива , сражающихся с вашими :name именованными заполнителями.


Резюме : Нельзя использовать именованные заполнители с selectcol_arrayref или аналогичные методы, которые работают с @bind_params. Однако в SQLite и Postgresql вы можете использовать пронумерованные заполнители ($1, $2, ... для Postgresql или ?1, ?2, ... для SQLite) с методами, которые работают с @bind_params или вы можете использовать именованные заполнители (:name для PostgreSQL и SQLite), если вы счастливы, используя более длинную последовательность prepare / bind_param / execute / fetch, и вам нужно быть осторожным если вы используете массивы PostgreSQL в своих запросах.

...