programing

동적 SQL이란 무엇입니까?

cafebook 2023. 9. 5. 20:47
반응형

동적 SQL이란 무엇입니까?

방금 SQL 관련 질문을 던졌는데, 첫 번째 답변은 "Dynamic SQL이 가장 적합한 상황입니다."였습니다.

동적 SQL에 대해 들어본 적이 없었기 때문에 저는 즉시 이 사이트와 웹을 검색했습니다.위키백과에는 이 제목의 기사가 없습니다.첫 번째 Google 결과는 모두 사람들이 다소 관련된 질문을 하는 사용자 포럼을 가리킵니다.

하지만, 저는 '동적 SQL'이 무엇인지에 대한 명확한 정의를 찾지 못했습니다.공급업체별로 다른 입니까?MySQL과 함께 작업하고 있지만 MySQL 핸드북에서 참조를 찾지 못했습니다(MySQL 사용자 포럼에서 대부분 답변되지 않은 질문만 있음).

반면에 저장 프로시저에 대한 많은 참조를 발견했습니다.저장 프로시저를 사용한 적은 없지만 저장 프로시저가 무엇인지 조금 더 잘 알고 있습니다.두 개념은 어떻게 연관되어 있습니까?그것들은 같은 것입니까 아니면 하나가 다른 것을 사용합니까?

기본적으로 필요한 것은 개념을 처음 접하는 사람을 위해 동적 SQL을 간단하게 소개하는 것입니다.

추신: 마음이 내키면, 이런 질문을 하게 된 제 이전 질문에 대답해 보세요: SQL: 어떻게 하면 표 1의 필드에 표 1을 표 2에 가입시킬 수 있을까요?

Dynamic SQL은 쿼리가 즉시 작성된 곳일 뿐입니다. 일부 공급업체에서는 하나의 저장 프로시저 내에서 동적 쿼리의 텍스트를 작성한 다음 생성된 SQL을 실행할 수 있습니다.다른 경우에, 이 용어는 단지 클라이언트의 코드에 의해 결정된 것을 의미합니다(이것은 적어도 공급업체 중립적입니다).

다른 답변에서는 동적 SQL이 무엇인지 정의했지만, 가끔 사용해야 하는 이유를 설명하는 다른 답변은 보지 못했습니다. (내 경험은 SQL Server이지만 다른 제품들도 이 점에서 대체로 비슷하다고 생각합니다.)

동적 SQL은 다른 방법으로 바꿀 수 없는 쿼리의 일부를 바꿀 때 유용합니다.

예를 들어, 다음과 같은 쿼리를 호출할 때마다

SELECT OrderID, OrderDate, TotalPrice FROM Orders WHERE CustomerID = ?? 

고객에게 다른 값을 전달하게 됩니다.ID. 이것은 가장 간단한 경우로, 매개 변수화된 쿼리를 사용하거나 매개 변수를 받아들이는 저장 프로시저 등을 사용하여 해결할 수 있습니다.

일반적으로 동적 SQL은 성능 및 보안상의 이유로 매개 변수화된 쿼리를 사용하지 않도록 해야 합니다. (성능 차이는 공급업체 간, 제품 버전 간, 심지어 서버 구성 간에도 상당한 차이가 있을 수 있습니다.

매개 변수를 사용하여 수행할 수 있는 다른 쿼리는 동적 SQL보다 간단할 수 있습니다.

SELECT OrderID, OrderDate, TotalPrice FROM Orders 
WHERE CustomerID IN (??,??,??)

항상 3개의 값을 가지고 있었다면 이것은 첫 번째 값만큼 쉽습니다.하지만 이것이 가변 길이 목록이라면 어떨까요?매개 변수를 사용하는 것은 가능하지만 매우 어려울 수 있습니다.어때요?

SELECT OrderID, OrderDate, TotalPrice FROM Orders WHERE CustomerID = ??
ORDER BY ??

이는 직접 대체할 수 없습니다. 정렬할 수 있는 필드 수에 따라 실용적이거나 실용적이지 않을 수 있는 모든 필드를 명시적으로 나열하여 복잡한 대/소문자 문장을 순서대로 사용할 수 있습니다.

마지막으로 일부 쿼리는 다른 방법으로는 수행할 수 없습니다.

예를 들어, 여러 주문 테이블이 있다고 가정해 보겠습니다(이것이 훌륭한 디자인이라고는 할 수 없음). 하지만 다음과 같은 작업을 수행할 수 있기를 바랄 수도 있습니다.

SELECT OrderID, OrderDate, TotalPrice FROM ?? WHERE CustomerID = ??

이 작업은 다른 방법으로는 수행할 수 없습니다.환경에서 다음과 같은 질문을 자주 받습니다.

SELECT (programatically built list of fields)
FROM table1 INNER JOIN table2
(Optional INNER JOIN to table3)
WHERE (condition1)
AND (long list of other optional WHERE clauses)

다시 말씀드리지만, 이것이 반드시 훌륭한 설계라고는 할 수 없지만 동적 SQL은 이러한 유형의 쿼리에 거의 필요합니다.

이게 도움이 되길 바랍니다.

동적 SQL은 실행되기 전에 즉시 구성되는 SQL 문입니다.예를 들어, 다음 C#(매개 변수화된 쿼리 사용)이 있습니다.

var command = new SqlCommand("select * from myTable where id = @someId");
command.Parameters.Add(new SqlParameter("@someId", idValue));

dynamic sql을 사용하여 다음과 같이 다시 작성할 수 있습니다.

var command = new SqlCommand("select * from myTable where id = " + idValue);

그러나 Dynamic SQL은 SQL Injection 공격을 쉽게 허용하므로 위험합니다.

동적 SQL은 런타임에 문자열로 구성된 SQL입니다.필터나 다른 것들을 동적으로 설정하는 것은 유용합니다.

예:

declare @sql_clause varchar(1000)  
declare @sql varchar(5000)   


set @sql_clause = ' and '    
set @sql = ' insert into #tmp  
 select   
   *
from Table 
where propA = 1 '    

if @param1 <> ''    
begin    
   set @sql = @sql + @sql_clause + ' prop1 in (' + @param1 + ')'    
end    
if @param2 <> ''    
begin    
   set @sql = @sql + @sql_clause + ' prop2 in (' + @param2 + ')'    
end 

exec(@sql)

그것이 바로 롤랜드가 언급한 것입니다.이에 대해 자세히 설명하려면 다음 SQL을 참조하십시오.

Select * from table1 where id = 1

데이터베이스에 연결하기 위해 어떤 언어를 사용하고 있는지 잘 모르겠지만 C#을 사용한다면 동적 SQL 쿼리의 예는 다음과 같습니다.

string sqlCmd = "Select * from table1 where id = " + userid;

쿼리가 너무 커질 경우 코드 무결성을 유지하는 것이 다소 번거롭기 때문에 동적 SQL 사용을 피하려고 합니다.또한 동적 SQL은 SQL 주입 공격에 취약합니다.

SQL Server를 사용하는 경우 매개 변수를 사용하는 것이 위 문을 작성하는 더 좋은 방법입니다.

Rowland는 정확하며, 추가적으로 매개 변수를 적절하게 사용하지 않는 한(제공된 텍스트에서 매개 변수 값을 인라인으로 조정하는 것과 비교하여) 보안 위험이 될 수도 있습니다.디버깅 등을 하는 것도 곰입니다.

마지막으로 동적 SQL을 잘못 사용할 때마다 모든 것이 실행되고 아이들이 잡아먹힙니다.

대부분의 데이터베이스에서 모든 SQL 쿼리는 입력 SQL 문자열과 매개 변수 바인딩("바인딩 변수")이 지정된 쿼리 옵티마이저에 의해 해석되는 프로그램임을 의미합니다.

정적 SQL

그러나 대부분의 경우 해당 SQL 문자열은 동적으로 구성되지 않고 정적으로 구성됩니다. PL/SQL과 같은 절차적 언어로 구성됩니다.

FOR rec IN (SELECT * FROM foo WHERE x = 1) LOOP
  --        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ "static SQL"
  ..
END LOOP;

또는 Java와 같은 클라이언트/호스트 언어에서는 JDBC를 사용합니다.

try (ResultSet rs = stmt.executeQuery("SELECT * FROM foo WHERE x = 1")) {
  // "static SQL"                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  ..
}

두 경우 모두 SQL 문자열이 포함된 언어에서 "static"입니다.기술적으로, SQL 문자열이 어떻게 구성되는지 또는 정적 SQL 문자열이었다는 것을 알지 못하는 SQL 엔진에 대해 여전히 "동적"일 것입니다.

동적 SQL

일부 입력 매개 변수가 주어지면 SQL 문자열을 동적으로 구성해야 하는 경우가 있습니다.예를 들어, 어떤 경우에는 위의 쿼리에 술어가 전혀 필요하지 않을 수 있습니다.

그런 다음 PL/SQL과 같이 문자열을 동적으로 구성하도록 선택할 수 있습니다.

DECLARE
  TYPE foo_c IS REF CURSOR;
  v_foo_c foo_c;
  v_foo foo%ROWTYPE;
  sql VARCHAR2(1000);
BEGIN
  sql := 'SELECT * FROM foo';

  IF something THEN
    sql := sql || ' WHERE x = 1'; -- Beware of syntax errors and SQL injection!
  END IF;

  OPEN v_foo_c FOR sql;
  LOOP
    FETCH v_foo_c INTO v_foo;
    EXIT WHEN v_foo_c%NOTFOUND;
  END LOOP;
END;

또는 Java/JDBC에서:

String sql = "SELECT * FROM foo";
if (something)
    sql += " WHERE x = 1"; // Beware of syntax errors and SQL injection!
try (ResultSet rs = stmt.executeQuery(sql)) {
  ..
}

또는 jOOQ와 같은 SQL 빌더를 사용하는 Java에서

// No syntax error / SQL injection risk here
Condition condition = something ? FOO.X.eq(1) : DSL.trueCondition();
for (FooRecord foo : DSL.using(configuration)
   .selectFrom(FOO)
   .where(condition)) {
  ..
}

많은 언어에는 위와 같은 쿼리 작성기 라이브러리가 있으며 동적 SQL을 수행할 때 가장 빛납니다.

(거부자:저는 jOOQ 뒤에 있는 회사에서 일합니다.)

공급업체별로 다른 것입니까?

SQL-92 Standard에는 동적 SQL에 대한 전체 장(17장)이 있지만 전체 SQL-92에만 적용되며 이를 구현한 벤더는 없습니다.

쿼리를 실행하기 전에 동적으로 쿼리를 작성해야 한다는 의미라고 생각합니다.다른 질문의 경우 먼저 필요한 테이블 이름을 선택하고 프로그래밍 언어를 사용하여 원하는 작업을 수행하기 위한 두 번째 쿼리를 작성해야 합니다(다른 질문에서 원하는 작업은 원하는 대로 직접 수행할 수 없음을 의미합니다.

언급URL : https://stackoverflow.com/questions/4165020/what-is-dynamic-sql

반응형