为 IN 子句创建动态字符串

Create dynamic string for IN clause

我们正在使用 Matillion ETL API 将查询参数传递给底层的 Redshift 查询。 States 的查询参数变量是使用下拉列表中的串联创建的,并在 API 中传递,如下所示:

v_state=" & #encodeForURL("''AL'',''CA''")#

此变量应在查询中作为 and state in ('AL','CA') 传递,但由于 , 的存在,它会抛出使用保留字符的错误。我试过转义这个字符,但还是不行。

所以我在变量 v_state=" & #encodeForURL("''AL''|''CA''")# 中使用了 | 而不是 , 并且它确实 运行 API 但基础查询没有 return任意数据。

and state in ('AL','CA')(Returns 数据)

and state in (replace('''AL''|''CA''','|',','))(没有return数据)

问题是:

  1. 在 Matillion API 中,有没有办法在字符串中转义逗号?
  2. 在 Redshift 中为 IN 子句使用竖线分隔字符串的正确方法是什么?

编辑 1:找到了一种将状态字符串转换为行的方法。

    with t as
        (select replace('AL|CO|CA|MN', '|', ',') as state)
   , seq_0_9 as (
    select 0 as num
    union all
    select 1 as num
    union all
    select 2 as num
    union all
    select 3 as num
    union all
    select 4 as num
    union all
    select 5 as num
    union all
    select 6 as num
    union all
    select 7 as num
    union all
    select 8 as num
    union all
    select 9 as num
)
   , seq_0_99 as (
    select a.num + b.num * 10 as num
    from seq_0_9 a,
         seq_0_9 b
)
SELECT split_part(t.state, ',', num) AS state
FROM t
         JOIN seq_0_99 seq
              ON num <= regexp_count(t.state, ',') + 1
WHERE num > 0;

感谢您的确认。我不确定您是如何在 Matillion REST API 中使用变量遇到字符转义问题的,因为变量是通过 POST 主体传入的?

无论如何,这里有一些对我有用的东西:

创建一个名为 EntryPointJob 的编排作业,作业变量设置如下。

在哪里

  • jv_commasep 是 public 输入,预计包含类似 AL,CA
  • 的内容
  • pjv_inlist 是一个私有变量,它被更新为包含 SQL 兼容格式的相同信息,如 'AL','CA'

我使用 Python3 脚本从 jv_commasep 导出 pjv_inlist,代码如下:

context.updateVariable('pjv_inlist', ','.join(["'" + x.strip() + "'" for x in jv_commasep.split(',')]))

现在,在 Matillion 作业中,您可以在 SQL 中使用 pjv_inlist 变量,例如:... WHERE "state" IN (${pjv_inlist})

到 运行 作业并传递一个标量变量,您首先需要创建一个 JSON 文件,如下所示。我将我的命名为 RunVariablesContainer.json

{
  "scalarVariables" : {
    "jv_commasep" : "AL,CA"
  }
}

然后你可以像这样调用 Matillion 自己的 REST API 到 运行 Matillion 作业(带参数):

curl -k -X POST -u un:pw -H "Content-type: application/json" "https://.../rest/v1/group/name/.../project/name/.../version/name/.../job/name/EntryPointJob/run?environmentName=Demo" --data-binary @RunVariablesContainer.json