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

时间:2018-10-24 09:17:59

标签: string plsql parameters char varchar2

让我们考虑具有这些签名的四个功能:

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 ...

假设它们具有相同的选择主体。

您能否举一个涉及这些功能的示例,以显示行为或使用这些功能的优势有何不同?

我在PL / SQL代码中几乎到处都看到程序员喜欢将字符串参数声明为VARCHAR2,尽管在文献中没有明显的理由提及该字符串参数并且没有实际的好处(因为CHAR至少具有较短的名称)

请省略说明字符类型在常量或变量声明中的基本区别-并着重介绍函数参数和返回类型的情况。

1 个答案:

答案 0 :(得分:0)

您可以敲响自己的测试用例来证明这一点,这并不难。但是,由于您没有这样做,因此可以看出其中的区别:

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。

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