redshift/postgresql 中的 regexp_count 不支持设置模式值的动态参数

Posted

技术标签:

【中文标题】redshift/postgresql 中的 regexp_count 不支持设置模式值的动态参数【英文标题】:regexp_count in redshift/postgresql doesn't supports dynamic parameter for setting pattern value 【发布时间】:2020-05-27 04:48:23 【问题描述】:

以下准备好的语句

String pattern = "[\\w\\-\\.]+@([\\w\\-]+\\.)+[\\w\\-]2,4";
PreparedStatement statement = conn.prepareStatement("SELECT sum(case when regexp_count(email, ?) > 0 then 1 else 0 end) AS email_1 FROM \"testschema\".\"test_table\"")
statement.setObject(1, pattern);

抛出以下异常,

java.sql.SQLException: [Amazon](500310) Invalid operation: The pattern must be a valid UTF-8 literal character expression
Details: 
 -----------------------------------------------
  error:  The pattern must be a valid UTF-8 literal character expression
  code:      8001
  context:   
  query:     1976234
  location:  cg_expr_fn_builder.cpp:3542
  process:   padbmaster [pid=5571]
  -----------------------------------------------;
    at com.amazon.redshift.client.messages.inbound.ErrorResponse.toErrorException(Unknown Source)
    at com.amazon.redshift.client.PGMessagingContext.handleErrorResponse(Unknown Source)
    at com.amazon.redshift.client.PGMessagingContext.handleMessage(Unknown Source)
    at com.amazon.jdbc.communications.InboundMessagesPipeline.getNextMessageOfClass(Unknown Source)
    at com.amazon.redshift.client.PGMessagingContext.doMoveToNextClass(Unknown Source)
    at com.amazon.redshift.client.PGMessagingContext.getErrorResponse(Unknown Source)
    at com.amazon.redshift.client.PGClient.handleErrorsScenario2ForPrepareExecution(Unknown Source)
    at com.amazon.redshift.client.PGClient.handleErrorsPrepareExecute(Unknown Source)
    at com.amazon.redshift.client.PGClient.executePreparedStatement(Unknown Source)
    at com.amazon.redshift.dataengine.PGQueryExecutor.executePreparedStatement(Unknown Source)
    at com.amazon.redshift.dataengine.PGQueryExecutor.execute(Unknown Source)
    at com.amazon.jdbc.common.SPreparedStatement.executeWithParams(Unknown Source)
    at com.amazon.jdbc.common.SPreparedStatement.executeQuery(Unknown Source)
Caused by: com.amazon.support.exceptions.ErrorException: [Amazon](500310) Invalid operation: The pattern must be a valid UTF-8 literal character expression
Details: 
 -----------------------------------------------
  error:  The pattern must be a valid UTF-8 literal character expression
  code:      8001
  context:   
  query:     1976234
  location:  cg_expr_fn_builder.cpp:3542
  process:   padbmaster [pid=5571]
  -----------------------------------------------;
    ... 13 more

我相信它不会用动态参数替换 ?。如何克服这个问题。?我尝试过 (?) 和 $1 作为占位符,但没有运气。我不想更改查询或构造没有动态参数的查询,因为它也用于其他数据库驱动程序。

【问题讨论】:

错误说它必须是文字字符表达式。换句话说,它不能是参数,因为参数不是 literal 字符表达式。我不确定您期望得到什么样的答案,但除了将字符串值连接到查询字符串中之外,您无法解决此问题。 Oracle 等其他数据库中的正则表达式模式匹配功能接受动态参数。为什么不是红移。?感谢您的回答,我们将研究替代方案。 这是一个你应该问亚马逊的问题。也许他们希望能够在语句准备中预编译正则表达式,也许他们没有考虑过,谁知道呢。 【参考方案1】:

尝试将正则表达式文字绑定为字符串:

String pattern = "[\\w\\-\\.]+@([\\w\\-]+\\.)+[\\w\\-]2,4";
PreparedStatement statement = conn.prepareStatement("SELECT SUM(CASE WHEN REGEXP_COUNT(email, ?) > 0 THEN 1 ELSE 0 END) AS email_1 FROM \"testschema\".\"test_table\"");
statement.setString(1, pattern);

【讨论】:

【参考方案2】:

错误表明它必须是文字字符表达式。换句话说,它不能是参数,因为参数不是literal字符表达式。

我建议向亚马逊提交功能请求以进行更改。作为一种解决方法,您可以在查询文本中使用文字。

【讨论】:

以上是关于redshift/postgresql 中的 regexp_count 不支持设置模式值的动态参数的主要内容,如果未能解决你的问题,请参考以下文章

使用 Amazon Redshift / PostgreSQL 进行漏斗查询

如何(以编程方式)知道何时在 PostgreSQL/Amazon Redshift 上完成查询?

RedShift / PostgreSQL 中串行类型的替代方案

psycopg2/python 将数据从 postgresql 复制到 Amazon RedShift(postgresql)

使用 Amazon Redshift / PostgreSQL 进行队列分析

Redshift/PostgreSQL 中子查询的 GroupAggregate