IT박스

MySQL의 빈 IN 절 매개 변수 목록

itboxs 2020. 12. 31. 08:06
반응형

MySQL의 빈 IN 절 매개 변수 목록


IN절이 비어 있는 SQL 쿼리를 수행하면 어떻게됩니까 ?

예를 들면 :

SELECT user WHERE id IN ();

MySQL은 이것을 예상대로 처리 IN합니까 (즉, 항상 false), 그렇지 않은 경우 절을 동적으로 빌드 할 때 내 애플리케이션이이 경우를 어떻게 처리 할 수 있습니까?


IN목록을 동적으로 작성 하는 응용 프로그램이 있고 결국 비어있을 수있는 경우 때로는 불가능한 값으로 목록을 초기화하고 추가합니다. 예를 들어 사용자 이름 목록 인 경우 가능한 사용자 이름이 아니므로 빈 문자열로 시작하겠습니다. auto_increment ID 인 경우 실제 값은 항상 양수이므로 -1을 사용합니다.

불가능한 값이 없기 때문에 이것이 가능하지 않은 경우 조건을 사용 AND column IN ($values)하여 WHERE절에 을 포함할지 여부를 결정해야합니다 .


유효한 구문을 사용한 쿼리의 가장 가까운 근사값은 다음과 같습니다.

SELECT user FROM tbl1 WHERE id IN (SELECT id FROM tbl1 WHERE FALSE);

무조건 빈 결과 집합을 반환합니다. 대괄호 안의 하위 쿼리는 항상 빈 집합을 반환하며 앞서 언급했듯이 빈 집합에는 값이 포함되어 있지 않으므로 빈 집합에서는 값을 찾을 수 없습니다.


이것은 나에게 0 결과를 제공합니다.

SELECT id FROM User
WHERE id IN (NULL);

MYSQL 5.6에서 시도


ID (1,2,3, ..)에 AUTO_INCREMENT를 사용하고 array가 비어 있으면 [0] 항목을 하나 추가 할 수 있습니다. 그래서 그것은 될 것입니다

if (empty($arr)) {
   $arr[] = 0;
}

SELECT user WHERE id IN (0);

그리고 mysql 구문 분석 오류가 없습니다. 이 경우는 기본 쿼리가 하위 쿼리 결과에 종속되지 않는 경우 하위 쿼리에서 매우 유용합니다.


더 나은 방법-배열이 비어 있으면 쿼리를 호출하지 마십시오.

$data = null;
if (!empty($arr)) {
    $data = ... call query
}

항상 거짓 진술 사용

SQL을 생성하기 전에 어레이 크기를 확인하십시오. 크기가 0이면 다음과 같이 where 문을으로 생성합니다 1 = 2.

SELECT * FROM USERS WHERE name in () 

된다

SELECT * FROM USERS WHERE 1 = 2 

빈 배열의 "not in"에 대해 다음과 같이 항상 true 문을 생성합니다.

SELECT * FROM USERS WHERE name not in () 

된다

SELECT * FROM USERS WHERE 1 = 1

이것은 다음과 같이 더 복잡한 쿼리에 대해 작동합니다.

SELECT * FROM USERS WHERE (name in () OR name = 'Alice') 

된다

SELECT * FROM USERS WHERE (1 = 2 OR name = 'Alice') 

IN비어 있을 때 쿼리를 실행해야한다고 가정합니다 . 예를 들어 LEFT JOIN ... ON ... AND IN ().

이미 IN응용 프로그램 계층에서 동적으로 빌드 하고 있으므로 여기서 빈 케이스를 처리합니다.

다음은 PHP의 기본 예제입니다.

$condition = 'FALSE' // Could feasibly want TRUE under different circumstances
if($values){
   $inParams = **dynamically generated IN parameters from $values**;
   $condition = 'IN (' . $inParams . ')';
}

$sql = 'SELECT * FROM `user` WHERE '.$condition;

빈으로 쿼리를 실행할 필요가 IN없다면하지 마십시오. 데이터베이스에 대한 여행을 저장하십시오!

N.B. In case you aren't already, I'd build/use a function that goes the long way round and binds in your IN parameters properly, rather than just concatting them raw into the SQL. This will give you some protection against SQL injection if it's used on raw data.


Here is another variation of always false statement for empty lists that preserves both logic and the notion of actual column in the query.

Incorrect id in () can be rewritten into:

where id <> id;

Similarly incorrect negative condition id not in () can be transformed by custom query building code into:

where id = id;

This approach is safer than id not in (NULL) as it doesn't evaluate to NULL.

But beware that this would filter out of the result the rows where id is null. This may be considered a feature in some cases.

Espesially useful with complex stacked query building logic where nested builder is not aware how the resulting subquery could be used above.

ReferenceURL : https://stackoverflow.com/questions/13210233/empty-in-clause-parameter-list-in-mysql

반응형