역사적으로 동적 보고서의 가변 그룹 수 작업은 SQL 표준에서 고려되지 않았습니다. SQL은 명확히 정의된 결과 스키마를 갖는 정적으로 설명된 쿼리에 기반합니다. BI 플랫폼과 대시보드의 등장으로 프로그래머들은 사용자의 요청에 따라 복잡한 데이터 조각을 생성하는 SQL 쿼리를 '실시간'으로 구성하는 방법을 찾기 시작했습니다.
문제 — SQL은 SELECT 내부에서 일반적인 if/else 논리로 프로그래밍할 수 없습니다. 열 수, 필드 및 심지어 GROUP BY는 쿼리 컴파일 단계에서만 정의됩니다. 사용자가 여러 임의 필드에 대한 조각을 원할 경우, 쿼리 텍스트를 동적으로 구성하고 EXECUTE/Dynamic SQL을 통해 실행해야 합니다.
해결책:
SQL 코드를 외부 애플리케이션에서 생성하고 EXEC/EXECUTE를 통해 호출합니다. 몇몇 단순한 작업에서는 CASE 및 고정 템플릿을 사용하지만, 유연성을 위해 항상 동적 SQL을 사용합니다:
코드 예시 (Pseudocode):
-- 애플리케이션 측 (예: Python) groups = ['region', 'channel', 'month'] columns = [f'SUM({col}) AS {col}_sum' for col in selected_metrics] group_by = ', '.join(groups) selects = ', '.join(groups + columns) query = f'SELECT {selects} FROM sales GROUP BY {group_by}' -- 그런 다음 이 쿼리를 application/sql 인터페이스를 통해 전송합니다.
EXECUTE를 지원하는 DBMS에서:
DECLARE @sql NVARCHAR(MAX); SET @sql = N'SELECT ' + @selects + ' FROM sales GROUP BY ' + @group_by + ';'; EXEC sp_executesql @sql;
주요 특징:
표준 SELECT만으로 동적으로 열 수를 변경할 수 있나요 (pivot/unpivot)?
아니요 — 사전에 알려진 값만 CASE/DECODE를 통해 '펼칠' 수 있지만, 알고 있는 수의 열은 동적으로만 달성할 수 있습니다.
문자열 연결을 사용한다면 동적 SQL 로직이 인젝션으로부터 보호할 수 있나요?
아니요, 수동 문자열 연결은 SQL 인젝션의 지속적인 위험입니다. 반드시 필드/그룹 목록을 화이트리스트하여 검증하고, 검증 없이 사용자 조각을 피하며, 가능한 경우 매개변수를 사용하는 것이 좋습니다.
GROUP BY는 변수를 통해 열 목록을 받을 수 있나요?
표준 SQL은 GROUP BY에서 변수를 통해 필드 목록을 전달하는 것을 지원하지 않습니다. 쿼리 텍스트를 동적으로 형성해야 합니다 — GROUP BY 목록에서 변수를 사용하는 것은 불가능합니다.
BI 엔지니어가 사용자에게 애플리케이션 인터페이스에서 보고서 필드 이름을 직접 전달하도록 허용하여 화이트리스트를 통한 필터링을 하지 않았습니다. 결과적으로 인젝션 테스트에서 필드 이름에 삽입된 악성 코드로 인해 프로덕션 테이블이 '손상'되었습니다.
장점:
단점:
엔지니어가 이름의 엄격한 검증을 구현하여 사용자가 허용된 열(구성/config에서)만 선택할 수 있었습니다. 동적 SQL은 화이트리스트에 따라 수집되었으며, 인젝션 경로가 없었습니다.
장점:
단점: