为什么要在Oracle中使用动态SQL?我不明白这两种书写方式的区别

wydwbb8l  于 2023-08-04  发布在  Oracle
关注(0)|答案(2)|浏览(92)
sql_1 := 'select count(1)
                 from table_1 a
                 where a.col_id = '''|| v_1 ||''' 
                 and a.col2 like ''%'|| v_2 ||'';
execute immediate sql_1
        into v_new;
-----------------------------------------------      
select count(1)
        into v_new
from table_1 a
where a.col_id = '''|| v_1 ||''' 
and a.col2 like ''%'|| v_2 ||'';

字符串
我认为这两种方法在一个程序中的效果是一样的。为什么第一个更好?

l3zydbqr

l3zydbqr1#

为什么第一个更好
动态SQL不是更好的,除其他原因外,语法错误等。将在运行时而不是编译时引发,因此无法轻松调试问题。
如果你不需要动态SQL,请不要使用它:

select count(1)
into   v_new
from   table_1 a
where  a.col_id = v_1 
and    a.col2  like '%'|| v_2

字符串
如果你必须使用动态SQL(不要),那么使用绑定变量(以防止SQL引擎在你更改变量时重新解析语句,并避免SQL注入问题):

sql_1 := 'select count(1)
          from   table_1 a
          where  a.col_id = :1
          and    a.col2 like ''%'' || :2';

EXECUTE IMMEDIATE sql_1 INTO v_new USING v_1, v_2;


但是,当您必须动态指定标识符(而不是值)时,您应该保留动态SQL,即使在这种情况下,它也应该提示您后退一步,检查您正在做的事情,以及是否可以更改方法以避免使用动态SQL。

t1rydlwq

t1rydlwq2#

好吧,动态SQL通常用于以下情况:您有几个具有或多或少相似结构的表,您在这些表上执行类似的数据处理,并且您不希望为N个相似的表编写类似的代码。然后,您可以使用带有execute immediate或dbms_sql工具的动态SQL。使用动态SQL时的主要问题是它需要插装,以便您可以调试运行时错误,这些错误比编译的非动态SQL中发生的频率要高得多。动态SQL不可能在存储程序、单元或PL/SQL块编译上编译,而是在运行时解析,这经常会由于错误地组合SQL语句而导致错误。因此,最好尽可能避免编写动态SQL。使用动态SQL只是为了避免编写10倍,20倍,100倍的代码行,因为你有10,20,100个具有类似结构的表,需要类似的数据处理。有时,您可以通过不同地设计数据库表来避免使用动态SQL。因此,不是有100个结构相似的表,而是只有一个表有一个额外的列-比如code_case -用于这100种情况,最终由该列分区。

相关问题