What is dynamic SQL?

后端 未结 9 2239
暗喜
暗喜 2020-12-05 02:28

I just asked an SQL related question, and the first answer was: \"This is a situation where dynamic SQL is the way to go.\"

As I had never heard of

相关标签:
9条回答
  • 2020-12-05 02:52

    Dynamic SQL is a SQL built from strings at runtime. It is useful to dynamically set filters or other stuff.

    An example:

    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)
    
    0 讨论(0)
  • 2020-12-05 03:04

    To most databases, every SQL query is "dynamic" meaning that it is a program that is interpreted by the query optimiser given the input SQL string and possibly the parameter bindings ("bind variables").

    Static SQL

    However, most of the time, that SQL string is not constructed dynamically but statically, either in procedural languages like PL/SQL:

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

    Or in client / host languages like Java, using JDBC:

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

    In both cases, the SQL string is "static" in the language that embeds it. Technically, it will still be "dynamic" to the SQL engine, which doesn't know how the SQL string is constructed, nor that it was a static SQL string.

    Dynamic SQL

    Sometimes, the SQL string needs to be constructed dynamically, given some input parameters. E.g. the above query might not need any predicate at all in some cases.

    You might then choose to proceed to constructing the string dynamically, e.g. in 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;
    

    Or in 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)) {
      ..
    }
    

    Or in Java using a SQL builder like jOOQ

    // 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)) {
      ..
    }
    

    Many languages have query builder libraries like the above, which shine most when doing dynamic SQL.

    (Disclaimer: I work for the company behind jOOQ)

    0 讨论(0)
  • 2020-12-05 03:06

    I think what's meant is that you should build the query dynamically before executing it. For your other questions this means that you should select the table name you need first and the use your programming language to build a second query for doing what you want (what you want to do in the other question isn't possible directly like you want).

    0 讨论(0)
提交回复
热议问题