【问题标题】:Oracle 10g simple query errororacle 10g 简单查询报错
【发布时间】:2011-06-06 15:09:59
【问题描述】:

Oracle SQL Developer 抱怨下一个 SQL,但我似乎找不到原因:

IF to_number(to_char(sysdate, 'HH24')) > 6 THEN
  IF to_number(to_char(sysdate, 'HH24')) < 9 THEN
    SELECT 1 FROM dual;
  ELSE
    SELECT (CASE WHEN result = 'SUCCESS' THEN 1 ELSE 0 END) FROM t_job WHERE to_char(start_time, 'yyyy/mm/dd') = to_char(sysdate, 'yyyy/mm/dd');
  END IF;
ELSE
    SELECT (CASE WHEN result = 'SUCCESS' THEN 1 ELSE 0 END) FROM t_job WHERE to_char(start_time, 'yyyy/mm/dd') = to_char(sysdate, 'yyyy/mm/dd');
END IF;

提供的查询有什么错误?

错误报告:

Error starting at line 7 in command:
ELSE
Error report:
Unknown Command
(CASEWHENRESULT='SUCCESS'THEN1ELSE0END) 
--------------------------------------- 
1                                       


Error starting at line 9 in command:
END IF
Error report:
Unknown Command

【问题讨论】:

  • 它到底是怎么抱怨的? )
  • @be here now,已经添加,只是意识到它不见了:)

标签: plsql oracle10g


【解决方案1】:

您的代码存在一些问题(这是 PL/SQL,而不仅仅是 SQL):

1) 您在街区周围缺少beginend

2) 你的selects 需要一个into 子句

尝试:

DECLARE
  l_result number;
BEGIN
  IF to_number(to_char(sysdate, 'HH24')) > 6 THEN
    IF to_number(to_char(sysdate, 'HH24')) < 9 THEN
      SELECT 1 INTO l_result FROM dual;
    ELSE
      SELECT (CASE WHEN result = 'SUCCESS' THEN 1 ELSE 0 END) 
       INTO l_result 
       FROM t_job WHERE to_char(start_time, 'yyyy/mm/dd') = to_char(sysdate, 'yyyy/mm/dd');
    END IF;
  ELSE
      SELECT (CASE WHEN result = 'SUCCESS' THEN 1 ELSE 0 END) 
       INTO l_result 
       FROM t_job WHERE to_char(start_time, 'yyyy/mm/dd') = to_char(sysdate, 'yyyy/mm/dd');
  END IF;
  dbms_output.put_line('result is '||l_result);
END;

【讨论】:

  • to_char(start_time, 'yyyy/mm/dd') = to_char(sysdate, 'yyyy/mm/dd') 对我来说也是一种不好的做法
  • 另外,我会选择trunc(start_time) = trunc(sysdate),而不是to_char(start_time, 'yyyy/mm/dd') = to_char(sysdate, 'yyyy/mm/dd')
  • @Tonu Andrews,这是原始变体,但它如何影响性能?
  • 我不认为太多,但可能会快一点(它所做的只是删除 3 个字节的数据,而不是相当复杂的格式)并且语义上也更清晰
  • 好的,这可能完美无缺,但是如果 SQL Developer 显示打印下一个字符串怎么办:匿名块已完成?
【解决方案2】:

由于这是一个 PL/SQL 块,您的 SELECT 语句需要将数据选择到某个局部变量中,或者需要在游标中使用它们。您想要哪种方法取决于T_JOB 中有多少行可能与您指定的条件匹配。假设所有三个语句都将返回正好 1 行,您可以执行类似的操作(简化代码以避免重复两次相同的查询)

DECLARE
  l_some_local_variable PLS_INTEGER;
BEGIN
  IF( to_number( to_char( sysdate, 'HH24' ) ) > 6 and
      to_number( to_char( sysdate, 'HH24' ) ) < 9 )
  THEN
    SELECT 1 
      INTO l_some_local_variable 
      FROM dual;
  ELSE
    SELECT (CASE WHEN result = 'SUCCESS' 
                 THEN 1
                 ELSE 0
             END) 
      INTO l_some_local_variable 
      FROM t_job
     WHERE trunc( start_time ) = trunc( sysdate );
  END IF;
END;

当然,一旦将数据填充到局部变量中,您就需要对值进行实际操作。您可能希望创建一个返回局部变量的函数,而不是像我在这里所做的那样使用匿名 PL/SQL 块。

【讨论】:

  • 您的回答效果很好,但 Tony Andrews 是第一个。不过非常感谢。 :)
猜你喜欢
  • 2011-03-11
  • 2013-10-31
  • 1970-01-01
  • 2011-07-14
  • 2013-03-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-22
相关资源
最近更新 更多