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

UPPER function used in initialisation of an IN parameter not working as expected

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!"

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

The UPPER() function 执行 return 传递给它的任何内容的大写版本,但在您的默认子句中,您传递的是文字 ' ',这是一个 [=34] =]. Whitespace 没有大小写,所以小写 space 和大写 space 之间没有区别——这个概念真的没有意义。您没有将过程的参数值传递给该函数。

如果调用者不提供默认值,

The defaut clause 会提供一个默认值。因此,如果您执行了 execute appraisal;,那么在该过程调用中,p_grade 变量将具有一个值(如果是单个 space),这没有帮助,也不是您想要的。您根本不需要默认值。

正如@DavidFaber 所说,您需要在计算参数值时获得大写等效的参数值,因此您可以这样做:

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;
/

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

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

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