0

我正在使用带有 cratedb 的 JDBC(它几乎使用 PSQL 协议)。碰巧当我尝试执行这样的查询时

String query = "select * from test where col1='dhruv\'";

它给了我解析器异常。

Caused by: io.crate.shade.org.postgresql.util.PSQLException: Unterminated string literal started at position 39 in SQL select * from test where col1='dhruv\'. Expected  char
    at io.crate.shade.org.postgresql.core.Parser.checkParsePosition(Parser.java:1310)
    at io.crate.shade.org.postgresql.core.Parser.parseSql(Parser.java:1217)

然后在调试时我发现jdbc的Parser.java中的这段代码

 else if (c == '\'') {
                    i0 = i;
                    i = parseSingleQuotes(p_sql, i, stdStrings);
                    checkParsePosition(i, len, i0, p_sql, "Unterminated string literal started at position {0} in SQL {1}. Expected ' char");
                    newsql.append(p_sql, i0, i - i0 + 1);
                }

正在引起问题。根据我的理解,他们破坏了 char 数组中的值,并且在语句的末尾'\''与我的冲突。\

我知道或尝试过的

  • 我读到人们要求使用,prepared statement因为插入发生了同样的问题,但我的查询是动态的,所以我不能使用它

  • 我们不能说不可能像dhruv\在数据库中那样插入值。我们可以通过控制台或json文件直接插入(顺便说一句,java很难,因为我们需要转义单个\并且db\不是转义字符)

  • 最新版本的 Cratedb 具有带有 C-Style Escape 的 String Literals ,但只是为了使用此功能,我无法更新我的整个数据库

那么有没有办法解决它?

++更新

还发现了类似的查询

select * from test where col1='dh\''ruv'

由于同样的原因也不会工作。

++更多更新

  • 所以据我了解select * from workkards where w_number='dhruv\\',在运行时将其视为select * from workkards where w_number='dhruv\'
    • 'dhruv\',现在反斜杠正在转义引号,所以引号被转义
    • 所以 crate jdbc parser 说 unterminated string since 'is escaped

我正在工作的方式

  • 我用反斜杠和空格替换\java代码,用户看不到任何区别,因为空格不可见\
if(value.contains("\\") ){
            return value.replace("\\", "\\ ");
        }
  • 有点像上面,似乎可以找到,因为我可以插入值,但是有一个问题
  • 该值存储在带有尾随空格的数据库中,因此在搜索该值时存在问题
  • 我们可以将相同的逻辑应用于搜索查询,这样它就可以工作了
  • 仍然存在的一个问题是,如果用户输入类似的值怎么办'dh\''ruv'
4

1 回答 1

1

您至少需要转义单引号。据我所知,“\”反斜杠不需要转义。

问题在于单引号,crate.io 使用它们来明确表示列值,如此处所述

SELECT "field" FROM "doc"."test" where field = '''dhruv\' limit 100;

上面将返回一个结果(我在本地机器上运行的示例)。

因此,您的查询将因此需要如下所示(注意用单引号正确终止):

String query = "select * from test where col1='''dhruv\'";

更新:

然后我建议如果你必须这样做,只转义“escapedValue”变量并添加它

String query = "select * from test where col1=" + "'" + escapedValue + "'";
于 2019-03-18T22:46:12.823 回答