代码之家  ›  专栏  ›  技术社区  ›  diziaq

PL/SQL函数参数中CHAR和VARCHAR2之间的差异

  •  0
  • diziaq  · 技术社区  · 7 年前

    让我们考虑一下这些签名的四个功能:

    FUNCTION my_func_1(pi_param CHAR) RETURN CHAR ...
    FUNCTION my_func_2(pi_param CHAR) RETURN VARCHAR2 ...
    FUNCTION my_func_3(pi_param VARCHAR2) RETURN VARCHAR2 ...
    FUNCTION my_func_4(pi_param VARCHAR2) RETURN CHAR ...
    

    假设他们都有你选择的同一个身体。

    你能举一个涉及这些函数的例子来说明使用其中一个函数在行为或优点上有什么不同吗?

    请不要解释常量或变量声明中字符类型的基本区别,而要关注函数参数和返回类型的情况。

    1 回复  |  直到 7 年前
        1
  •  0
  •   Boneist    7 年前

    您可以构建自己的测试用例来演示这一点,这并不难。但是,由于您没有这样做,这里有一个可以显示出区别:

    DECLARE
      v_input_str VARCHAR2(4) := 'abcd';
      v_p_char CHAR(10);
      v_p_vchar VARCHAR2(10);
      v_ret_char CHAR(20);
      v_ret_vchar VARCHAR2(20);
    
      FUNCTION my_func_1(pi_param CHAR) RETURN CHAR
      IS
        v_var CHAR(10);
      BEGIN
        v_var := pi_param;
        dbms_output.put_line('  my_func_1: length(pi_param) = '||LENGTH(pi_param));
        dbms_output.put_line('  my_func_1: length(v_var) = '||LENGTH(v_var));
        RETURN v_var;
      END my_func_1;
    
      FUNCTION my_func_2(pi_param CHAR) RETURN VARCHAR2
      IS
        v_var VARCHAR2(10);
      BEGIN
        v_var := pi_param;
        dbms_output.put_line('  my_func_2: length(pi_param) = '||LENGTH(pi_param));
        dbms_output.put_line('  my_func_2: length(v_var) = '||LENGTH(v_var));
        RETURN v_var;
      END my_func_2;
    
      FUNCTION my_func_3(pi_param VARCHAR2) RETURN VARCHAR2
      IS
        v_var VARCHAR2(10);
      BEGIN
        v_var := pi_param;
        dbms_output.put_line('  my_func_3: length(pi_param) = '||LENGTH(pi_param));
        dbms_output.put_line('  my_func_3: length(v_var) = '||LENGTH(v_var));
        RETURN v_var;
      END my_func_3;
    
      FUNCTION my_func_4(pi_param VARCHAR2) RETURN CHAR
      IS
        v_var CHAR(10);
      BEGIN
        v_var := pi_param;
        dbms_output.put_line('  my_func_4: length(pi_param) = '||LENGTH(pi_param));
        dbms_output.put_line('  my_func_4: length(v_var) = '||LENGTH(v_var));
        RETURN v_var;
      END my_func_4;
    BEGIN
      v_p_char := v_input_str;
      v_p_vchar := v_input_str;
    
      dbms_output.put_line('length(v_p_char) = '||length(v_p_char));
      dbms_output.put_line('length(v_p_vchar) = '||length(v_p_vchar));
    
      v_ret_char := my_func_1(v_p_char);
      dbms_output.put_line('my_func_1, v_p_char input, char output: length(v_ret_char) = '||length(v_ret_char));
      v_ret_vchar := my_func_1(v_p_char);
      dbms_output.put_line('my_func_1, v_p_char input, char output: length(v_ret_vchar) = '||length(v_ret_vchar));
    
      v_ret_char := my_func_1(v_p_vchar);
      dbms_output.put_line('my_func_1, v_p_vchar input, char output: length(v_ret_char) = '||length(v_ret_char));
      v_ret_vchar := my_func_1(v_p_vchar);
      dbms_output.put_line('my_func_1, v_p_vchar input, char output: length(v_ret_vchar) = '||length(v_ret_vchar));
    
      v_ret_char := my_func_2(v_p_char);
      dbms_output.put_line('my_func_2, v_p_char input, varchar output: length(v_ret_char) = '||length(v_ret_char));
      v_ret_vchar := my_func_2(v_p_char);
      dbms_output.put_line('my_func_2, v_p_char input, varchar output: length(v_ret_vchar) = '||length(v_ret_vchar));
    
      v_ret_char := my_func_2(v_p_vchar);
      dbms_output.put_line('my_func_2, v_p_vchar input, varchar output: length(v_ret_char) = '||length(v_ret_char));
      v_ret_vchar := my_func_2(v_p_vchar);
      dbms_output.put_line('my_func_2, v_p_vchar input, varchar output: length(v_ret_vchar) = '||length(v_ret_vchar));
    
      v_ret_char := my_func_3(v_p_char);
      dbms_output.put_line('my_func_3, v_p_char input, varchar output: length(v_ret_char) = '||length(v_ret_char));
      v_ret_vchar := my_func_3(v_p_char);
      dbms_output.put_line('my_func_3, v_p_char input, varchar output: length(v_ret_vchar) = '||length(v_ret_vchar));
    
      v_ret_char := my_func_3(v_p_vchar);
      dbms_output.put_line('my_func_3, v_p_vchar input, varchar output: length(v_ret_char) = '||length(v_ret_char));
      v_ret_vchar := my_func_3(v_p_vchar);
      dbms_output.put_line('my_func_3, v_p_vchar input, varchar output: length(v_ret_vchar) = '||length(v_ret_vchar));
    
      v_ret_char := my_func_4(v_p_char);
      dbms_output.put_line('my_func_4, v_p_char input, char output: length(v_ret_char) = '||length(v_ret_char));
      v_ret_vchar := my_func_4(v_p_char);
      dbms_output.put_line('my_func_4, v_p_char input, char output: length(v_ret_vchar) = '||length(v_ret_vchar));
    
      v_ret_char := my_func_4(v_p_vchar);
      dbms_output.put_line('my_func_4, v_p_vchar input, char output: length(v_ret_char) = '||length(v_ret_char));
      v_ret_vchar := my_func_4(v_p_vchar);
      dbms_output.put_line('my_func_4, v_p_vchar input, char output: length(v_ret_vchar) = '||length(v_ret_vchar));
    
    END;
    /
    

    输出为:

    length(v_p_char) = 10
    length(v_p_vchar) = 4
      my_func_1: length(pi_param) = 10
      my_func_1: length(v_var) = 10
    my_func_1, v_p_char input, char output: length(v_ret_char) = 20
      my_func_1: length(pi_param) = 10
      my_func_1: length(v_var) = 10
    my_func_1, v_p_char input, char output: length(v_ret_vchar) = 10
      my_func_1: length(pi_param) = 4
      my_func_1: length(v_var) = 10
    my_func_1, v_p_vchar input, char output: length(v_ret_char) = 20
      my_func_1: length(pi_param) = 4
      my_func_1: length(v_var) = 10
    my_func_1, v_p_vchar input, char output: length(v_ret_vchar) = 10
      my_func_2: length(pi_param) = 10
      my_func_2: length(v_var) = 10
    my_func_2, v_p_char input, varchar output: length(v_ret_char) = 20
      my_func_2: length(pi_param) = 10
      my_func_2: length(v_var) = 10
    my_func_2, v_p_char input, varchar output: length(v_ret_vchar) = 10
      my_func_2: length(pi_param) = 4
      my_func_2: length(v_var) = 4
    my_func_2, v_p_vchar input, varchar output: length(v_ret_char) = 20
      my_func_2: length(pi_param) = 4
      my_func_2: length(v_var) = 4
    my_func_2, v_p_vchar input, varchar output: length(v_ret_vchar) = 4
      my_func_3: length(pi_param) = 10
      my_func_3: length(v_var) = 10
    my_func_3, v_p_char input, varchar output: length(v_ret_char) = 20
      my_func_3: length(pi_param) = 10
      my_func_3: length(v_var) = 10
    my_func_3, v_p_char input, varchar output: length(v_ret_vchar) = 10
      my_func_3: length(pi_param) = 4
      my_func_3: length(v_var) = 4
    my_func_3, v_p_vchar input, varchar output: length(v_ret_char) = 20
      my_func_3: length(pi_param) = 4
      my_func_3: length(v_var) = 4
    my_func_3, v_p_vchar input, varchar output: length(v_ret_vchar) = 4
      my_func_4: length(pi_param) = 10
      my_func_4: length(v_var) = 10
    my_func_4, v_p_char input, char output: length(v_ret_char) = 20
      my_func_4: length(pi_param) = 10
      my_func_4: length(v_var) = 10
    my_func_4, v_p_char input, char output: length(v_ret_vchar) = 10
      my_func_4: length(pi_param) = 4
      my_func_4: length(v_var) = 10
    my_func_4, v_p_vchar input, char output: length(v_ret_char) = 20
      my_func_4: length(pi_param) = 4
      my_func_4: length(v_var) = 10
    my_func_4, v_p_vchar input, char output: length(v_ret_vchar) = 10
    

    CHAR和VARCHAR之间的区别在于,CHAR将填充字符串分隔为变量/列的全宽。这可能对报告有用,但一般来说,这意味着存储所有额外空间是在浪费内存。

    从上面的输出可以看出,当您在CHAR(20)变量中存储一个四个字符的字符串时,变量的长度是20—您原来的四个字符加上16个空格。VARCHAR2(20)变量中对应的字符串的长度为4。

    我创建的函数将输入字符串(CHAR(10)或VARCHAR2(10))放入变量(CHAR(10)或VARCHAR2(10)),然后将其传递给变量(CHAR(20)或VARCHAR2(20))。

    您可以看到,在从函数返回变量时,长度为4或10,但当保存返回值的变量的长度为4、10或20时。

    您可以看到,VARCHAR2变量不会更改变量的长度,但只要将CHAR变量添加到混合中,长度就会增加。

    简而言之,只有在没有其他选项时才使用CHAR。否则,请使用VARCHAR2。

    你说你只关心函数参数和返回类型,而不是变量,但它们是一回事!

    推荐文章