在 OpenSQL 的动态 WHERE 中引用参数

Quoting arguments in dynamic WHERE in OpenSQL

我找到了这个如何创建动态 WHERE 的示例:

REPORT ZII_RKP_TEST1.

DATA: cond(72) TYPE c,
      itab LIKE TABLE OF cond.

PARAMETERS: source(10) TYPE c, dest(10) TYPE c.

DATA wa TYPE spfli-cityfrom.

CONCATENATE 'CITYFROM = ''' source '''' INTO cond.
APPEND cond TO itab.

CONCATENATE 'OR CITYFROM = ''' dest '''' INTO cond.
APPEND cond TO itab.

CONCATENATE 'OR CITYFROM = ''' 'BAYERN' '''' INTO cond.
APPEND cond TO itab.

LOOP AT itab INTO cond.
  WRITE cond.
ENDLOOP.

SKIP.

SELECT cityfrom
  INTO wa
  FROM spfli
 WHERE (itab).
   WRITE / wa.
ENDSELECT.

来源:https://wiki.scn.sap.com/wiki/display/ABAP/Dynamic%2Bwhere%2Bclause

上面的例子使用了像 "BAYERN" 这样的静态值,但是如果我使用任意值,那么我想事情可能会因为像 ''' 这样的特殊值而中断。

是否有必要做一些引用以使动态 WHERE 牢不可破?如果是,该怎么做?

您可以在添加它们之前在 perform 中转义撇号,如下所示

PERFORM escape CHANGING source.
PERFORM escape CHANGING dest.

CONCATENATE 'CITYFROM = ''' source '''' INTO cond.
APPEND cond TO itab.

...

FORM escape CHANGING value TYPE c.
  REPLACE ALL OCCURRENCES OF '''' IN value WITH ''''''.
ENDFORM.

包含转义函数详细信息的最新 ABAP 版本为 here。但它不包括引号转义。我们可以在 class cl_abap_dyn_prg 上使用静态 escape_quotes 方法,如下所示。

CALL METHOD cl_abap_dyn_prg=>escape_quotes
  EXPORTING
    val    = source
  receiving
    out    = output. 

制作方法如上所示。

我想知道为什么那个例子是这样写的,也许它是一段旧代码。

1st:如果您可以在您的系统中访问 "new" 字符串语法,您可以只使用类似

的东西
WHERE = |CITYFROM = '| && source && |'|.

第二:关于字符串 WHERE 子句的好处是你可以只使用变量作为字符串的一部分,我的意思是,如果你只写类似

WHERE = 'CITYFROM = source'.

ABAP 会将其转换为正确的 SQL,就像您正确编写 SQL 一样。

(我希望我能解释清楚,如果你有任何疑问,请随时询问)

应该使用方法 cl_abap_dyn_prg=>quote( name )

示例:

DATA(cond) = `country = 'DE' AND name = ` &&
             cl_abap_dyn_prg=>quote( name ).

来源:SQL Injections Using Dynamic Tokens

感谢 Sandra Rossi 为我指明了正确的方向。