Подтвердить что ты не робот

Есть ли привязка параметров SQL для массивов?

Существует ли стандартный способ привязки массивов (скаляров) в SQL-запросе? Я хочу привязать к предложению IN, например:

SELECT * FROM junk WHERE junk.id IN (?);

Я использую Perl::DBI, который принуждает параметры к скалярам, ​​поэтому я получаю бесполезные запросы, например:

SELECT * FROM junk WHERE junk.id IN ('ARRAY(0xdeadbeef)');

Разъяснение: Я помещаю запрос в свой собственный файл .sql, поэтому строка уже сформирована. В тех случаях, когда в ответах упоминается динамическое создание строки запроса, я бы, скорее всего, выполнил поиск и заменил.

Изменить: Этот вопрос является своего рода дубликатом Параметрирование предложения SQL IN?. Первоначально я думал, что он должен быть закрыт как таковой, но похоже, что он накапливает какую-то хорошую Perl-специфическую информацию.

4b9b3361

Ответ 1

Вы указываете "это SQL для запроса с одним параметром" - это не будет работать, если вам нужно много параметров. Конечно, это боль. Еще два варианта того, что было предложено:

1) Используйте DBI- > quote вместо держателей мест.

my $sql = "select foo from bar where baz in ("
           . join(",", map { $dbh->quote($_) } @bazs)
           . ")";
my $data = $dbh->selectall_arrayref($sql);

2) Используйте ORM, чтобы сделать этот материал низкого уровня для вас. DBIx:: Class или Rose:: DB:: Object, например.

Ответ 2

Если вам не нравится карта, вы можете использовать оператор "x":

my $params = join ', ' => ('?') x @foo;
my $sql    = "SELECT * FROM table WHERE id IN ($params)";
my $sth    = $dbh->prepare( $sql );
$sth->execute( @foo );

Скобки нужны вокруг '?' потому что это означает, что x 'находится в контексте списка.

Прочтите "perldoc perlop" и найдите "Binary" x "для получения дополнительной информации (в разделе" Мультипликативные операторы ").

Ответ 3

Я делаю что-то вроде:

my $dbh = DBI->connect( ... );
my @vals= ( 1,2,3,4,5 );
my $sql = 'SELECT * FROM table WHERE id IN (' . join( ',', map { '?' } @vals ) . ')';
my $sth = $dbh->prepare( $sql );
$sth->execute( @vals );

Ответ 4

И еще один способ создания SQL - использовать что-то вроде SQL:: Abstract....

use SQL::Abstract;
my $sql    = SQL::Abstract->new;
my $values = [ 1..3 ];
my $query  = $sql->select( 'table', '*', { id => { -in => $values } } );

say $query;   # => SELECT * FROM table WHERE ( id IN ( ?, ?, ? ) )

Ответ 5

С обычным DBI вам нужно будет построить SQL самостоятельно, как было предложено выше. DBIx::Simple (обертка для DBI) делает это для вас автоматически, используя '??' Обозначения:

$db->query("select * from foo where bar in (??)", @values);

Ответ 6

В python я всегда делал что-то вроде:

query = 'select * from junk where junk.id in ('
for id in junkids:
  query = query + '?,'
query = query + ')'

cursor.execute(query, junkids)

... который по существу строит запрос с одним '?' для каждого элемента списка.

(и если там есть другие параметры, вам нужно убедиться, что вы правильно выполняете строки при выполнении запроса)

[edit], чтобы сделать код более понятным для людей, не относящихся к python. Есть ошибка, когда запрос будет иметь дополнительную запятую после последнего?, Из которой я уйду, потому что исправление будет просто облако общей идеи]

Ответ 7

Я использую DBIx:: DWIW. Он содержит функцию, называемую InList(). Это создаст ту часть SQL, которая необходима для списка. Однако это работает только в том случае, если у вас есть все ваши SQL в программе, а не снаружи в отдельном файле.

Ответ 8

Используйте

SELECT * FROM junk WHERE junk.id = ANY (?);

вместо