TL; DR : 절의 문자 만이 아니라 모든 리터럴 을 제한 해야WHERE
합니다. 그렇지 않은 이유 때문에 데이터베이스가 다른 시스템과 분리되어있을 수 있습니다.
첫째, 전제에 결함이 있습니다. WHERE
절만 제한하고 싶지만 사용자 입력이 가능한 유일한 장소는 아닙니다. 예를 들어
SELECT
COUNT(CASE WHEN item_type = 'blender' THEN 1 END) as type1_count,
COUNT(CASE WHEN item_type = 'television' THEN 1 END) AS type2_count)
FROM item
이것은 SQL 주입에 동일하게 취약합니다.
SELECT
COUNT(CASE WHEN item_type = 'blender' THEN 1 END) FROM item; DROP TABLE user_info; SELECT CASE(WHEN item_type = 'blender' THEN 1 END) as type1_count,
COUNT(CASE WHEN item_type = 'television' THEN 1 END) AS type2_count)
FROM item
따라서 WHERE
절 에서 리터럴을 제한 할 수는 없습니다 . 모든 리터럴 을 제한해야합니다 .
이제 "왜 리터럴을 허용합니까?"라는 질문이 남았습니다. 명심하십시오. 관계형 데이터베이스는 다른 언어로 작성된 응용 프로그램 아래에서 많은 시간 을 사용하지만 데이터베이스를 사용하기 위해 응용 프로그램 코드를 사용해야 할 필요 는 없습니다 . 그리고 여기에 답이 있습니다 : 코드를 작성하려면 리터럴이 필요합니다. 다른 대안은 모든 코드를 데이터베이스와 독립적으로 어떤 언어로 작성하도록하는 것입니다. 따라서이를 사용하면 데이터베이스에 직접 "코드"(SQL)를 작성할 수 있습니다. 이것은 귀중한 디커플링이며 리터럴이 없으면 불가능합니다. (언제나 좋아하는 언어로 문자를 쓰십시오. 얼마나 어려운지 상상할 수있을 것입니다.)
일반적인 예로, 리터럴은 종종 값 목록 / 조회 테이블 채우기에 사용됩니다.
CREATE TABLE user_roles (role_id INTEGER, role_name VARCHAR(50));
INSERT INTO user_roles (1, 'normal');
INSERT INTO user_roles (2, 'admin');
INSERT INTO user_roles (3, 'banned');
그것들이 없으면 이 테이블을 채우기 위해 다른 프로그래밍 언어로 코드를 작성해야 합니다. SQL에서 직접 수행 할 수있는 기능은 매우 중요 합니다.
그렇다면 우리는 또 하나의 질문을 남길 것입니다 : 프로그래밍 언어 클라이언트 라이브러리는 왜 그렇게하지 않습니까? 그리고 여기에 우리는 매우 간단한 답변을 제공 합니다 . 지원되는 각 버전의 데이터베이스에 대해 전체 데이터베이스 파서 를 다시 구현 했을 것 입니다. 왜? 모든 리터럴을 찾도록 보장 할 수있는 다른 방법이 없기 때문입니다. 정규 표현식으로는 충분하지 않습니다. 예를 들어 PostgreSQL에는 4 개의 별도 리터럴이 포함되어 있습니다.
SELECT $lit1$I'm a literal$lit1$||$lit2$I'm another literal $$ with nested string delimiters$$ $lit2$||'I''m ANOTHER literal'||$$I'm the last literal$$;
유효한 구문은 종종 주요 데이터베이스 릴리스 사이에서 변경되므로 유지 관리의 악몽이 될 것입니다.
bad_ideas_sql = 'SELECT title FROM idea WHERE idea.status == "bad" AND idea.user == :mwheeler'
단일 쿼리에서 하드 코딩 된 값과 매개 변수화 된 값을 모두 가질 수 있습니다. 그런 혼합 쿼리에 유효한 사용 사례가 있다고 생각합니다.