使用带有分号字符的 STRPOS 时出现语法错误或访问冲突

Posted

技术标签:

【中文标题】使用带有分号字符的 STRPOS 时出现语法错误或访问冲突【英文标题】:Syntax error or access violation when using STRPOS with semicolon character 【发布时间】:2018-02-16 11:19:40 【问题描述】:

我有一张表table1 有以下数据

+----------------+
|     model      |
+----------------+
| a45/ a45m;aa45 |
| b34/b34m       |
| c23;c23m/ cc23 |
+----------------+

我正在尝试使用某些规则清理model 字段,例如

    获取第一个;之前的所有字符 来自1,获取第一个/之前的所有字符

所以我在netezza 中为步骤 1 执行以下操作

SELECT
    SUBSTR(model, 1, STRPOS(model, ';')-1) AS model_clean
FROM table1
;

这会引发错误ERROR [42000] Syntax error or access violation。任何想法为什么会发生这种情况,字符 ; 是否需要转义?

需要注意的是,当我查找space 字符如下时,没有错误。

SELECT
    SUBSTR(model, 1, STRPOS(model, ' ')-1) AS model_clean
FROM table1
;

还有没有办法在同样的select 语句中完成第 2 步?

预期输出

+----------------+
|  model_clean   |
+----------------+
| a45            |
| b34            |
| c23            |
+----------------+ 

【问题讨论】:

如果您使用的是 Netezza,请不要使用 postgresql 标记您的问题。这是两种不同的数据库产品 您在帖子中提供的 SQL 引用了“模型”列,但没有引用表。如果按照您在此处显示的方式运行,它将返回此错误:“错误:找不到属性‘模型’。”您在帖子中给出的错误声称是语法错误,这可能与 STRPOS 没有任何关系。对于语法错误,最好发布完整的 SQL。 另外,包含预期输出的样本会很有帮助。 @ScottMcG - 添加了表格参考和预期输出。 【参考方案1】:

失败是因为不是所有的列都有分号,所以strpos()返回0。你可以通过添加分号来解决这个问题:

SELECT SUBSTR(model, 1, STRPOS(model || ';', ';') - 1) AS model_clean

【讨论】:

试过这个,但是继续收到错误ERROR [42000] Syntax error or access violation 一件事让我觉得这不仅仅是一些没有 ; 的行,尽管并非所有行都有空格,但声明 SELECT SUBSTR(model, 1, STRPOS(model, ' ')-1) AS model_clean ; 没有错误地通过 我认为 Gordon 的解决方案非常接近可行的解决方案。尝试连接一个;对于所有出现的“模型”,更具体地说是第一个逗号之前的那个: SELECT SUBSTR(model||';', 1, STRPOS(model||';', ';')-1) AS model_clean ;跨度> @user3206440 。 . .其中一个值可以以分号开头吗? @GordonLinoff - 在花了一些时间之后,问题被确定为我用来连接 Netezza 的接口的 SQL 解析器。它显然将; 视为语句的结尾。目前的解决方法是使用chr(59) 而不是;【参考方案2】:

当您尝试使用无效位置执行子字符串时,您的查询失败,strpos 的结果没有找到分号。

可以使用case语句来避免计算无效位置

这里是一个 SQLServer 语法示例(charindexstrpos 有颠倒的参数顺序,由你来减少查询)http://sqlfiddle.com/#!18/55a6e/25

WITH step1
     AS ( SELECT CASE
                   WHEN CHARINDEX(';', model) > 0 THEN SUBSTRING(model, 1, CHARINDEX(';', model) - 1)
                   ELSE model
                 END AS model
            FROM table1 ),
     step2
     AS ( SELECT CASE
                   WHEN CHARINDEX('/', model) > 0 THEN SUBSTRING(model, 1, CHARINDEX('/', model) - 1)
                   ELSE model
                 END AS model
            FROM step1 )
SELECT *
  FROM step2;

【讨论】:

Kobi:您的答案在 netezza 上不起作用,因为它是一个 MPP 数据库执行,因此您的 CASE 的所有“片段”都将针对所有行进行评估,即使是那些带有空字符串的行...根据我的经验,Gordon Linoffs 解决方案更接近于工作。

以上是关于使用带有分号字符的 STRPOS 时出现语法错误或访问冲突的主要内容,如果未能解决你的问题,请参考以下文章

使用带有 lit-html 的打字稿编写测试时出现“语法错误:无法在模块外使用 import 语句”

创建视图时出现 PhpPgAdmin 语法错误

在 Toad for Sql Server 2016 中使用带有 Union All 的 Order By 子句时出现奇怪的语法错误

将字符串转换为 int 时出现语法错误

更新时出现休眠错误:无法执行语句,在 'index=1' 附近使用正确的语法

尝试迁移 postgreSQL 时出现或接近“WITH ORDINALITY”错误的语法错误