배열에 대한 SQL 매개 변수 바인딩이 있습니까?


Answers

"하나의 매개 변수가있는 쿼리의 SQL입니다."라고 지정하면 많은 매개 변수가 필요할 때 작동하지 않습니다. 당연히 다룰 고통입니다. 이미 제안 된 것에 대한 두 가지 다른 변형 :

1) 자리 표시 자 대신 DBI-> 인용 부호를 사용하십시오.

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를 예로들 수 있습니다.

Question

SQL 쿼리에서 배열 (스칼라)을 바인딩하는 표준 방법이 있습니까? IN 절에 바인딩하려면 다음과 같이하십시오.

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

필자는 Perl::DBI 를 사용하여 스칼라에 매개 변수를 강제 변환하므로 쓸모없는 쿼리로 끝납니다.

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

설명 : 자체 .sql 파일에 쿼리를 넣었으므로 문자열이 이미 구성되어 있습니다. 쿼리 문자열을 동적으로 생성하는 것에 대한 대답을 언급 한 곳에서는 검색을 수행하고 대신 대체 할 수 있습니다.

편집 : 이 질문은 SQL IN 절 매개 변수를 복제 종류의 일종 입니까? . 나는 원래 그것이 닫혀 있어야한다고 생각했지만, Perl에 대한 좋은 정보가 축적되어있는 것처럼 보입니다.




나는 DBIx :: DWIW를 사용한다 . InList ()라는 함수가 포함되어 있습니다. 그러면 목록에 필요한 SQL 부분이 작성됩니다. 그러나 이것은 외부 파일이 아닌 별도의 파일에 모든 SQL이있는 경우에만 작동합니다.




용도

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

대신에




파이썬에서는 항상 다음과 같은 일을 끝냈습니다.

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

cursor.execute(query, junkids)

본질적으로 하나의 '?' 목록의 각 요소에 대해

(거기에 다른 매개 변수가있는 경우 쿼리를 실행할 때 올바르게 배치해야합니다)

[Python이 아닌 사람들을 위해 코드를 더 쉽게 이해할 수 있도록 편집하십시오. 버그가 있습니다. 마지막에 쉼표가 추가로 붙는 버그가 있습니다.이 버그를 수정하면 일반적인 아이디어가 흐려질 것이기 때문에 떠날 것입니다.]




지도가 마음에 들지 않으면 '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 " '를 검색하십시오 ("Multiplicative Operators "섹션 참조).




그리고 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 ( ?, ?, ? ) )



나는 다음과 같이 행동한다.

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 );



평범한 DBI 를 사용하면 위에서 제안한 것처럼 SQL을 직접 DBI 합니다. DBIx :: Simple ( DBI 용 래퍼)은 자동으로 '??' 표기법:

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