Разница между CHAR и VARCHAR2 в параметрах функции PL / SQL - PullRequest
0 голосов
/ 24 октября 2018

Давайте рассмотрим четыре функции с этими сигнатурами:

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, по крайней мере, имеет более короткое имя).

Пожалуйста, опустите объяснение основных различий типов charater в константах или объявлениях переменных - и сосредоточьтесь нарегистр параметров функции и возвращаемых типов.

1 Ответ

0 голосов
/ 24 октября 2018

Вы могли бы запустить собственный тестовый пример, чтобы продемонстрировать это, это не сложно.Однако, поскольку вы этого не сделали, вот тот, который показывает разницу:

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.

Вы говорите, что заботитесь только о том, чтобы узнать о параметре функции и возвращаемых типах, а не о переменных, но это одно и то же!

...