2014-04-11 4 views
0

5.0MySQL에서 저장 프로 시저의 준비된 문에 정수 목록을 전달하는 방법은 무엇입니까?

CREATE TABLE `locationcodes` (
    `id` int, 
    `customer` varchar(100), 
    `locationcode` varchar(50), 
    `parentid` int 
); 

insert into locationcodes values (1, 'Test, Inc.', 'California', NULL); 
insert into locationcodes values (2, 'Test, Inc.', 'Los Angeles', 1); 
insert into locationcodes values (3, 'Test, Inc.', 'San Francisco', 1); 
insert into locationcodes values (4, 'Test, Inc.', 'Sacramento', 1); 

저장 프로 시저 :

CREATE PROCEDURE test (_location VARCHAR(100)) 
BEGIN 

SET @location = _location; 

SET @select=' 
    SELECT id, locationcode 
    FROM locationcodes 
    WHERE customer="Test, Inc." 
    AND id in (?) 
    '; 

PREPARE stmt FROM @select; 
EXECUTE stmt USING @location; 
DEALLOCATE PREPARE stmt; 

END 

통화 절차 :

call test('2, 3') 

결과 :

2, Los Angeles 

결과는 한 행,하지만 난 올릴 때 두 줄이 좋아. 문제는 준비된 문이 인수가 varchar임을 확인하고 따라서 값을 따옴표로 묶습니다. IN 문을 만들 수 있도록 따옴표를 사용하지 않는 것이 좋습니다. 어떻게 수행 할 수 있습니까? 이상적으로 MySQL은 ints 데이터 유형 목록을 가지고 있으므로 varchar를 사용할 필요는 없지만 존재하지 않습니다.

SQL 주입 공격을 막기 위해 준비된 문구를 유지해야합니다.

답변

1

IN()과 함께 준비된 문을 사용하고 단일 값을 바인딩 할 수없는 것처럼 보입니다.

어떤 이유로 MySQL의 API는 해당 비교에서 바인드 할 하나의 단일 값이있을 때 IN()을 = (같음)로 대체합니다.

나는 우리의 절차에 따라 몇 가지 테스트를 실행한다. MySQL이 생성 무엇 원래 절차와

가 (테스트 내 기본 데이터베이스입니다) : id 필드는 정수와 MySQL의 비교 2 '2,3'로 변환이 경우에

((`test`.`locationcodes`.`customer` = 'Test, Inc.') and 
(`test`.`locationcodes`.`id` = '2,3')) 

, 그건 로스 앤젤레스가 돌아온 이유는 '3,2'가 '샌프란시스코'를 분명히 반환한다는 것입니다.

필드 유형 (id는 정수)과 관련이 없도록하기 위해 값을 locationcode (varchar)와 비교하려고 시도했지만 결과는 동일합니다.

프로 시저를 하나가 아닌 두 개의 값을 바인딩하도록 변경했습니다.

... 
SET @select=' 
    SELECT id, locationcode 
    FROM locationcodes 
    WHERE customer="Test, Inc." 
    AND id in (?,?) 
    '; 

PREPARE stmt FROM @select; 
EXECUTE stmt USING @location,@location2; 
... 

이 경우 문을 올바르게 만듭니다.

((`test`.`locationcodes`.`customer` = 'Test, Inc.') and 
(`test`.`locationcodes`.`id` in ('2','3'))) 

즉, 나는 준비된 진술로이를 달성하기 위해 다른 접근법을 사용해야한다고 말할 수 있습니다.

http://bugs.mysql.com/bug.php?id=16564이 Valeriy에 따르면, 값을 임시 테이블을 생성하고 가입 사용

내 테스트 후 나는이 버그 보고서을 발견했다. 그것은 작동해야합니다.