用于初始化IN参数的UPPER函数未按预期工作

时间:2015-01-25 13:42:50

标签: sql oracle oracle11g

CREATE OR REPLACE PROCEDURE appraisal
  (p_grade IN VARCHAR2 := UPPER(' '))
IS
 v_appraisal VARCHAR2(20) := '';
BEGIN
 v_appraisal := CASE p_grade
     WHEN 'A' THEN 'Excellent'
     WHEN 'B' THEN 'Very good'
     WHEN 'C' THEN 'Bad'
     ELSE 'No such grade!'
     END;
 DBMS_OUTPUT.PUT_LINE('Grade:-'||p_grade ||' Appraisal:-'|| v_appraisal);
END;
/

EXECUTE appraisal('a');

输出:

Grade:-a Appraisal:-No such grade!"

我想知道为什么这不起作用 - 我做错了什么?

1 个答案:

答案 0 :(得分:5)

The UPPER() function确实返回传递给它的任何内容的大写版本,但是在你的默认子句中,你传递了文字' ',这是一个单独的空格。空白没有外壳,所以小写空间和大写空间之间没有区别 - 这个概念确实没有意义。您将过程的参数值传递给该函数。

如果来电者没有提供默认值,那么

The defaut clause会提供默认值。因此,如果您执行了execute appraisal;,那么在该过程调用中p_grade变量将具有一个值,如果只有一个空格,这不是有用的,并且不是您想要的。你根本不想要违约。

正如@DavidFaber所说,在评估它时你需要得到parmeter值的大写等值,所以你可以这样做:

CREATE OR REPLACE PROCEDURE appraisal
  (p_grade IN VARCHAR2)
IS
 v_appraisal VARCHAR2(20);
BEGIN
 v_appraisal := CASE UPPER(p_grade)
     WHEN 'A' THEN 'Excellent'
     WHEN 'B' THEN 'Very good'
     WHEN 'C' THEN 'Bad'
     ELSE 'No such grade!'
     END;
 DBMS_OUTPUT.PUT_LINE('Grade:-'|| UPPER(p_grade)
  ||' Appraisal:-'|| v_appraisal);
END;
/

Alternativley你可以声明一个设置为大写值的局部变量并使用它:

 v_grade varchar2(1) := UPPER(p_grade);

您通常不应该假设调用您的过程的人将显示dbms_output缓冲区。调试或试验你可以控制调用环境的地方,但通常不是真正的代码,这是可以的。例如,您可能实际上需要一个返回v_appraisal值的函数。 Here's an SQL Fiddle demo of a simole function version。或者只是一个包含成绩及其描述的查找表。