복붙노트

[SQL] 동적 SQL은 무엇인가?

SQL

동적 SQL은 무엇인가?

난 그냥 SQL과 관련된 질문을하고, 첫 번째 대답했다 : "이것은 동적 SQL이 길을 가야하는 것입니다 상황입니다."

내가 전에 동적 SQL 들어 본 적이 없었다, 나는 바로이 사이트가 무엇인지에 대한 웹 검색. 위키 백과는이 제목에는 글이 없습니다. 첫 번째 구글은 사람들이 더 많거나 적은 관련된 질문을 사용자 포럼에 대한 모든 지점을 발생합니다.

그러나, 나는 '동적 SQL'이 무엇인지에 대한 명확한 정의를 찾지 못했습니다. 그것은 뭔가 공급 업체 특정 있습니까? 나는 MySQL과 일을하고 난 (MySQL의 사용자 포럼에서 대부분 답이없는 질문 만,) MySQL의 수첩에 대한 참조를 찾을 수 없습니다.

반면에, 내가 저장 프로 시저에 대한 많은 참조를 발견했다. 내가 어떤을 사용한 적이 있지만 나는, 저장 프로 시저가 무엇인지 조금 더 나은 이해를 가지고있다. 두 개념은 어떻게 관련이? 그들은 같은 일을하거나 다른 일을 사용 하는가?

기본적으로 필요한 것은 개념에 새로운 사람에 대한 동적 SQL에 대한 간단한 소개합니다.

P.S : 당신이 기분 경우,이 하나의 메시지가 내 앞의 질문에 대답에서 이동 할 수 있습니다 : SQL을 어떻게 우리가 표는 표 1의 필드에 주어진 테이블에 표 2를 가입 할 수 있습니까?

해결법

  1. ==============================

    1.일부 공급 업체와 함께, 당신은 하나의 저장 프로 시저 내에서 동적 쿼리의 텍스트를 구축하고 생성 된 SQL을 실행할 수 있습니다 - 동적 SQL 쿼리가 즉석에서 만들어졌습니다 단지 곳입니다. 다른 경우에서, 용어는 단지 클라이언트 코드에 의해 이루어지는 결정을 의미한다 (이것은 인 적어도 벤더 중립)

    일부 공급 업체와 함께, 당신은 하나의 저장 프로 시저 내에서 동적 쿼리의 텍스트를 구축하고 생성 된 SQL을 실행할 수 있습니다 - 동적 SQL 쿼리가 즉석에서 만들어졌습니다 단지 곳입니다. 다른 경우에서, 용어는 단지 클라이언트 코드에 의해 이루어지는 결정을 의미한다 (이것은 인 적어도 벤더 중립)

  2. ==============================

    2.다른 대답은 무엇인지 동적 SQL 정의, 그러나 나는 우리가 때때로을 사용해야하는 이유에 대해 설명하려고 다른 답변을 보지 못했다. (내 경험 SQL 서버,하지만 난 다른 제품은이 점에서 일반적으로 유사하다 생각합니다.)

    다른 대답은 무엇인지 동적 SQL 정의, 그러나 나는 우리가 때때로을 사용해야하는 이유에 대해 설명하려고 다른 답변을 보지 못했다. (내 경험 SQL 서버,하지만 난 다른 제품은이 점에서 일반적으로 유사하다 생각합니다.)

    다른 방법을 사용하여 대체 할 수없는 쿼리의 부품을 교체 할 때 동적 SQL에 유용합니다.

    예를 들어, 때마다 당신은 쿼리를 같이 전화 :

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

    당신은 CustomerID를 위해 다른 값을 전달한다. 이는 가장 간단한 경우이고, 그 중 하나에 의해 캔 등 쿼리 파라미터 또는 파라미터를 수용하는 프로 시저를 사용하여 해결

    일반적으로, 동적 SQL은 성능과 보안을 이유로 매개 변수화 된 쿼리, 찬성 피해야한다. (성능 차이는 아마 꽤 업체 사이의 비트, 그리고 심지어 제품 버전 사이, 또는 서버 구성을 다양하지만).

    다른 쿼리 매개 변수를 사용하여이 작업을 수행하는 것이 가능하지만, 동적 SQL로 간단 수 있습니다 :

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

    당신은 항상 3 개 값을 가지고 있다면,이 첫 번째 한 쉽게합니다. 그러나이 경우은 가변 길이 목록입니다? 그것의 가능한 매개 변수와 함께 할,하지만 매우 어려울 수 있습니다. 방법에 대해 :

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

    이것은 당신이 명시 적으로 또는, 실용적으로 정렬하는 데 사용할 필드의 수에 따라하지 않을 수도 있습니다 모든 가능한 필드를 나열하여 ORDER에 큰 복잡한 CASE 문으로 그것을 할 수 있습니다, 직접 교체 할 수 없습니다.

    마지막으로, 일부 쿼리는 단순히 다른 방법을 사용하여 수행 할 수 없습니다.

    하자 당신이 (이 훌륭한 디자인이다 말을하지 않음) 주문 테이블의 무리가 있다고,하지만 당신은 당신이 좋아하는 뭔가를 할 수 바라고 자신을 찾을 수 있습니다 :

    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은 거의 이러한 유형의 쿼리가 필요합니다.

    도움이 되었기를 바랍니다.

  3. ==============================

    3.동적 SQL은 단순히 실행되기 전에 즉시 구성되는 SQL 문입니다. 예를 들어, 다음 C # (매개 변수가있는 쿼리를 사용하여) :

    동적 SQL은 단순히 실행되기 전에 즉시 구성되는 SQL 문입니다. 예를 들어, 다음 C # (매개 변수가있는 쿼리를 사용하여) :

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

    같은 동적 SQL을 사용하여 다시 작성할 수 있습니다 :

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

    그것은 쉽게 SQL 주입 공격을 수 있기 때문에 동적 SQL이 위험하다,하지만, 명심하십시오.

  4. ==============================

    4.동적 SQL은 런타임에 문자열에서 내장 SQL이다. 그것은 동적으로 설정 필터 또는 다른 물건에 유용합니다.

    동적 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)
    
  5. ==============================

    5.그것은 롤랜드 언급 정확히 것입니다. 조금, 다음과 같은 SQL을 있음에 자세히 설명합니다 :

    그것은 롤랜드 언급 정확히 것입니다. 조금, 다음과 같은 SQL을 있음에 자세히 설명합니다 :

    Select * from table1 where id = 1
    

    내가 생각하지 않도록하는 데이터베이스에 연결하기 위해 사용,하지만 난 C # .NET을 사용한다면, 동적의 SQL 쿼리의 예는 이런 일이 될 것입니다 언어 :

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

    이 쿼리가 너무 커질 경우 코드의 무결성을 유지하는 비트 성가신되기 때문에 당신은 동적 SQL을 사용하지 않도록합니다. 또한, 매우 중요한, 동적 SQL은 SQL 주입 공격에 취약하다.

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

  6. ==============================

    6.로우 랜드가 정확한지, 그리고 부록으로, 제대로 (단지 등, 인라인 제공하는 텍스트에서 매개 변수 값을 concatonating 대) 매개 변수를 사용하지 않는 그것은 또한 보안 위험이 발생할 수 있습니다. 또한 디버깅 등 곰이다

    로우 랜드가 정확한지, 그리고 부록으로, 제대로 (단지 등, 인라인 제공하는 텍스트에서 매개 변수 값을 concatonating 대) 매개 변수를 사용하지 않는 그것은 또한 보안 위험이 발생할 수 있습니다. 또한 디버깅 등 곰이다

    당신이 어리석게 동적 SQL을 사용할 때마다 마지막으로, 상황은 해방되고, 아이들은 먹을 수 있습니다.

  7. ==============================

    7.대부분의 데이터베이스에 모든 SQL 쿼리가 입력 SQL 문자열과 가능한 매개 변수 바인딩 ( "바인드 변수")을 주어진 쿼리 최적화에 의해 해석되는 프로그램입니다 것을 의미한다 "동적"입니다.

    대부분의 데이터베이스에 모든 SQL 쿼리가 입력 SQL 문자열과 가능한 매개 변수 바인딩 ( "바인드 변수")을 주어진 쿼리 최적화에 의해 해석되는 프로그램입니다 것을 의미한다 "동적"입니다.

    그러나, 대부분의 시간은, 그 SQL 문자열은 어느 PL / SQL과 같은 절차 적 언어로 동적으로하지만, 정적으로 구성되지 않습니다

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

    또는 클라이언트에서 / 자바 같은 호스트 언어는 JDBC를 사용하여 :

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

    두 경우 모두, 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;
    

    또는 자바 / 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)) {
      ..
    }
    

    또는 Java로 jOOQ 같은 SQL 빌더를 사용하여

    // 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 뒤에 회사 I 작업)

  8. ==============================

    8.는 SQL-92 표준은 동적 SQL에 전체 장 (17 장)을 가지고 있지만 그것은 단지 전체 SQL-92에 적용하고 나는 그것을 구현했습니다 어떤 공급 업체로 알고있다.

    는 SQL-92 표준은 동적 SQL에 전체 장 (17 장)을 가지고 있지만 그것은 단지 전체 SQL-92에 적용하고 나는 그것을 구현했습니다 어떤 공급 업체로 알고있다.

  9. ==============================

    9.나는 무엇을 의미하는 것 것은 당신이 그것을 실행하기 전에 동적으로 쿼리를 작성해야한다고 생각합니다. 당신이 먼저 필요 테이블 이름을 선택해야하고, 당신이 원하는 일을위한 두 번째 쿼리를 작성하는 프로그래밍 언어를 사용하는 것이 다른 질문이 수단 (당신이 다른 질문하고 싶은 것은 당신이 원하는 직접처럼 수 없습니다 ).

    나는 무엇을 의미하는 것 것은 당신이 그것을 실행하기 전에 동적으로 쿼리를 작성해야한다고 생각합니다. 당신이 먼저 필요 테이블 이름을 선택해야하고, 당신이 원하는 일을위한 두 번째 쿼리를 작성하는 프로그래밍 언어를 사용하는 것이 다른 질문이 수단 (당신이 다른 질문하고 싶은 것은 당신이 원하는 직접처럼 수 없습니다 ).

  10. from https://stackoverflow.com/questions/4165020/what-is-dynamic-sql by cc-by-sa and MIT license