带有“case”的sql语句的奇怪行为

Posted

技术标签:

【中文标题】带有“case”的sql语句的奇怪行为【英文标题】:Strange behaviour of a sql statement with 'case' 【发布时间】:2013-01-14 13:56:19 【问题描述】:

我正在尝试创建 SQL 报告。这是选择语句:

  select
  -- ticket id
  '<tr align=left valign=top><td width=95>'||maspid||'</td>'||

  -- priority
  case when instr(masfld017, '<|lang' ) = 0 then
        '<td width=90>'||masfld017
  else
        '<td width=90>'||substr( masfld017, 1 , instrb(masfld017, '<|lang') - 1)
  end||'</td>'||

  -- customer
  '<td width=150>'||masfld007||'</td>'||

  -- status
    '<td width=100>'||decode(masfld104, '0', 'Collected',
          '1', 'Postponed',
          '2', 'Accepted',
          '3', 'in Progress',
          '5', 'Work Around',
          '7', 'Solved',
          '8', 'Closed')||'</td>'||

  -- subject
  '<td width=400>'||masfld001||'</td>'||

  -- full name
  '<td width=100>' || replace(replace(masfld037, '<||>'), '</||>')||'</td>'||

  -- creation date
  '<td width=150>'||to_char(to_date(masfld022, 'YYYYMMDDHH24MI'), 'DD.MM.YYYY HH24:MM')||'</td>'||

  -- target date
  '<td width=150>'||to_char(to_date(masfld023, 'YYYYMMDDHH24MI'), 'DD.MM.YYYY HH24:MM')||'</td>'||

  -- ticket type
  '<td width=180>'||decode(masfld040, '9', 'HUS',
        '8', 'Project',
        '7', 'Enhancement',
        '6', 'Complaint',
        '5', 'Change Request',
        '4', 'Bug (Do not use)',
        '3', 'Support',
        '2', 'Service Request',
        '1', 'Incident (Problem)',
        null, 'N/A')||'</td></tr>'
from
        k2h.tmaster01 tm inner join k2h.tprofile tp on replace(replace(tm.masfld035, '<||>'), '</||>') = tp.propid
where
        masfld024 is null and
        masfld082 = '&REGION' 

order by case masfld017
        when 'Emergency'         then 1 
        when 'Critical'          then 2
        when 'High'              then 3
        when 'Major Problem'     then 4
        when 'Major defect'      then 5
        when 'Semi-major defect' then 6
        when 'Medium'            then 7
        when 'Minor Problem'     then 8
        when 'Low'               then 9
        end;

如果我直接用 sqldeveloper 运行它,我会得到一个结果列表。如果报告是由 crontab 启动的,则会失败并显示以下错误消息:

SP2-0734: unknown command beginning "case when ..." - rest of line ignored. SP2-0734: unknown command beginning "'

好像command的情况无法识别,但为什么呢?

【问题讨论】:

请发布所有的sql语句。 @DanielHilgarth 这不在最初发布的代码中,仅包含order by case... 我包含了整个声明。但为什么它与 sqldeveloper 一起工作?是的,执行的是同一条语句。 您运行的是什么版本的 Oracle? $ORACLE_HOME : /opt/oracle/10.2.0 【参考方案1】:

是否有可能在 crontab 中直接在 shell 中运行 SQL 例如

sqlplus...<<ESQL
select..
...
order by case end;

? 如果是这样,请删除空白行。

否则你会得到类似的东西:

SQL> select
  2    -- ticket id
  3    '<tr align=left valign=top><td width=95>'||maspid||'</td>'||
  4
SQL>   -- priority
SQL>   case when instr(masfld017, '<|lang' ) = 0 then
SP2-0734: unknown command beginning "case when ..." - rest of line ignored.

【讨论】:

非常感谢,删除空行有效。非常感谢! 我遇到了同样的问题。一切都在 SQL Developer 中运行,但在 sqlplus 中失败。删除空行和缩进解决了这个问题。我的代码看起来不漂亮,但它现在可以运行了。【参考方案2】:

我建议从您的 SQL 命令中删除空格,甚至可能是 cmets,然后尝试一下。 SQL*Plus 对嵌入在命令中的空格很挑剔。我什至遇到过双破折号 cmets 和 SQL*Plus 脚本的问题。我认为是空格,但如果是 cmets,请使用 /* ... */ 样式的评论。

【讨论】:

正确答案,但@DanzzaL 更快。【参考方案3】:

由于某种原因,解析器似乎将case 语句解释为PLSQL case 语句,而不是SELECT case 语句。也就是说,它没有将表达式视为列的一部分,而是将其视为 PLSQL 语句的一部分。 “SP”错误消息是指 SQL-Plus 而不是语言本身。

我的猜测是,select 语句上方的某些内容会混淆脚本。

【讨论】:

以上是关于带有“case”的sql语句的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章

PYSPARK:如何将带有多个 case 语句的 SQL 查询转换为 Pyspark/Pyspark-SQL?

Oracle SQL - 带有迭代的 Case 语句

C# 将带有 Case 语句的 SQL 查询转换为 LINQ

带有条件 CASE 语句的 SQL LEFT JOIN

使用 CASE [String] 时 SELECT CASE 语句的奇怪行为

天蓝色专用 sql 池 (sqldw) 可序列化表提示语句奇怪的行为