가능하다면 이렇게하지 마십시오.
그것이 답입니다. 그것은 반 패턴입니다. 클라이언트가 데이터를 원하는 테이블을 알고 있으면 SELECT FROM ThatTable
. 데이터베이스가 이것이 필요한 방식으로 설계 되었다면 차선책으로 설계된 것 같습니다. 데이터 액세스 계층이 테이블에 값이 있는지 여부를 알아야하는 경우 해당 코드에서 SQL을 작성하기 쉽고이 코드를 데이터베이스로 푸시하는 것은 좋지 않습니다.
나에게 이것은 원하는 층의 번호를 입력 할 수있는 엘리베이터 내부에 장치를 설치하는 것처럼 보입니다. Go 버튼을 누른 후 원하는 층의 올바른 버튼으로 기계식 손을 이동하고 누릅니다. 이로 인해 많은 잠재적 인 문제가 발생합니다.
참고 : 여기에는 조롱 할 의도가 없습니다. 저의 어리석은 엘리베이터의 예는이 기술의 문제를 간결하게 지적 할 수있는 * 내가 상상할 수있는 최고의 장치 *였습니다. 쓸모없는 간접 계층을 추가하여 호출자 공간 (튼튼하고 잘 이해 된 DSL, SQL 사용)에서 테이블 이름 선택을 모호하고 기괴한 서버 측 SQL 코드를 사용하여 하이브리드로 이동합니다.
쿼리 구성 논리를 동적 SQL로 이동하여 책임을 분할하면 코드를 이해하기가 더 어려워집니다. 오류 가능성이있는 사용자 지정 코드의 이름에서 표준적이고 신뢰할 수있는 규칙 (SQL 쿼리가 선택할 항목을 선택하는 방법)을 위반합니다.
다음은이 접근 방식의 몇 가지 잠재적 인 문제에 대한 자세한 내용입니다.
동적 SQL은 프런트 엔드 코드 또는 백 엔드 코드만으로 인식하기 어려운 SQL 삽입 가능성을 제공합니다 (이를 확인하려면 함께 검사해야합니다).
저장 프로 시저 및 함수는 SP / 함수 소유자가 권한을 가지고 있지만 호출자는 권한이없는 리소스에 액세스 할 수 있습니다. 내가 이해하는 한, 특별한주의없이 기본적으로 동적 SQL을 생성하고 실행하는 코드를 사용할 때 데이터베이스는 호출자의 권한에 따라 동적 SQL을 실행합니다. 즉, 권한있는 개체를 전혀 사용할 수 없거나 모든 클라이언트에 공개해야하므로 권한있는 데이터에 대한 잠재적 공격의 표면 영역이 증가합니다. 생성시 SP / 함수를 항상 특정 사용자 (SQL Server에서 EXECUTE AS
) 로 실행하도록 설정하면 이 문제를 해결할 수 있지만 상황이 더 복잡해집니다. 이는 동적 SQL을 매우 매력적인 공격 벡터로 만들어 이전 지점에서 언급 한 SQL 주입의 위험을 악화시킵니다.
개발자가 애플리케이션 코드를 수정하거나 버그를 수정하기 위해 수행하는 작업을 이해해야 할 때 실행되는 정확한 SQL 쿼리를 얻는 것이 매우 어렵습니다. SQL 프로파일 러를 사용할 수 있지만 이는 특별한 권한을 필요로하며 프로덕션 시스템에 부정적인 성능 영향을 미칠 수 있습니다. 실행 된 쿼리는 SP에 의해 기록 될 수 있지만 이로 인해 의심스러운 이점 (새 테이블 수용, 오래된 데이터 제거 등)에 대한 복잡성이 증가하고 명확하지 않습니다. 실제로 일부 응용 프로그램은 개발자가 데이터베이스 자격 증명을 갖지 않도록 설계되었으므로 실제로 제출되는 쿼리를 보는 것이 거의 불가능합니다.
존재하지 않는 테이블을 선택하려고 할 때와 같이 오류가 발생하면 데이터베이스에서 "잘못된 개체 이름"줄을 따라 메시지가 표시됩니다. 백엔드에서 SQL을 작성하든 데이터베이스에서 SQL을 작성하든 똑같은 일이 발생하지만, 시스템 문제를 해결하려는 일부 가난한 개발자는 한 단계 더 깊은 곳에서 또 다른 동굴에 들어가야합니다. 문제가 무엇인지 알아 내기 위해 모든 일을하는 경이로운 절차를 파헤 치기 위해 문제가 존재합니다. 로그에는 "GetWidget의 오류"가 표시되지 않고 "OneProcedureToRuleThemAllRunner의 오류"가 표시됩니다. 이 추상화는 일반적으로 시스템을 악화 시킵니다.
매개 변수를 기반으로 테이블 이름을 전환하는 의사 C #의 예 :
string sql = $"SELECT * FROM {EscapeSqlIdentifier(tableName)};"
results = connection.Execute(sql);
이것이 상상할 수있는 모든 가능한 문제를 제거하는 것은 아니지만, 다른 기술로 설명했던 결함은이 예제에 없습니다.