如何将带有 in 子句的 sql 查询转换为字符串

How to convert sql query with in clauses into string

您好,我想将 sql 语句转换为字符串以供动态使用。但是我在连接时遇到了问题

select col1, col2 从 表格1 在哪里 Col3 in ( 'cat' , 'dog' );

我不知道怎么加上引号和||对于猫和狗

‘select col1, col2 从 表格1 在哪里 Col3 in ('||''cat''||',''dog''||')'|| Strcond;

一种选择是使用 q-quoting 机制(参见第 6 行),因为它允许您 通常 使用单引号(另外,您的单引号看起来 fancy;如果您打算 copy/paste 从例如 MS Word 到您的 SQL 客户端,那是行不通的)。

这是一个例子:

SQL> declare
  2    l_str varchar2(500);
  3    strcond varchar2(100) := '  and 1 = 1';
  4  begin
  5    l_str := 'select col1, col2 from table1 where col3 in ' ||
  6             q'[('cat', 'dog')]' || strcond;
  7    dbms_output.put_line(l_str);
  8  end;
  9  /
select col1, col2 from table1 where col3 in ('cat', 'dog')  and 1 = 1

PL/SQL procedure successfully completed.

SQL>

一个选项是使用绑定变量并放入与 IN 列表的最大大小一样多的绑定变量:

select col1, col2 from Table1 Where Col3 in ( :a001, :a002, :a003, :a004 )

然后:

  • 您可以重复使用相同的语句,SQL 引擎将不必重新解析它(在第一次之后)。
  • 您不需要在动态 SQL 字符串的列表值中转义引号。
  • 您的代码不易受到 SQL 注入的攻击。

如果您想传递的值少于最大值,那么您可以重复值:

DECLARE
  sql VARCHAR2(2000) := 'select col1, col2 from Table1 Where Col3 in ( :a001, :a002, :a003, :a004 )';
BEGIN
  EXECUTE IMMEDIATE sql USING 'cat', 'dog', 'cat', 'cat';
END;
/

但是,如果您打算这样做,那么您可以考虑是否可以完全消除动态 SQL:

DECLARE
  a001 Table1.Col3%TYPE := 'cat';
  a002 Table1.Col3%TYPE := 'dog';
  a003 Table1.Col3%TYPE := a001;
  a004 Table1.Col3%TYPE := a001;

  col1_values SYS.ODCIVARCHAR2LIST;
  col2_values SYS.ODCIVARCHAR2LIST;
BEGIN
  select col1, col2
  BULK COLLECT INTO col1_values, col2_values
  from   Table1
  Where Col3 in ( a001, a002, a003, a004 );
END;
/