Создайте функцию с необязательными аргументами в MySQL

Я хочу создать функцию с необязательными аргументами в MySQL. Например, я хочу создать функцию, которая вычисляет среднее значение своих аргументов. Я создаю функцию из пяти аргументов, но когда пользователь передает только два аргумента функции, он должен все еще запускать и возвращать среднее из двух аргументов.

Ответы

Ответ 1

Вы не можете установить дополнительные параметры в хранимых процедурах MySQL.
Однако вы можете установить необязательные параметры в MySQL UDF.

Вы знаете, что MySQL имеет функцию агрегации AVG?

Обход Если вы можете столкнуться с уродством этого обходного пути здесь samplecode, который использует строку с разделителями-запятыми со значениями в качестве входных данных и возвращает среднее значение.

DELIMITER $$

CREATE FUNCTION MyAvg(valuestr varchar) RETURNS float
BEGIN
  DECLARE output float;
  DECLARE arg_count integer;
  DECLARE str_length integer;
  DECLARE arg float;
  DECLARE i integer;

  SET output = NULL;

  SET i = LENGTH(valuestr);
  IF i > 0 THEN BEGIN 

    SET arg_count = 1;
    WHILE i > 0 DO BEGIN
      IF MID(valuestr, i, 1)
      SET i = i - 1;
    END; END WHILE;

    /* calculate average */
    SET output = 0;
    SET i = arg_count;
    WHILE i > 0 DO BEGIN
      SET arg = SUBSTRING_INDEX( 
                  SUBSTRING_INDEX(valuestr, ',' , i)
                  , ',', -1 );
      SET output = output + arg;
      SET i = i - 1; 
    END; END WHILE;       
    SET output = output / arg_count;

  END; END IF;    
  RETURN output;
END $$

DELIMITER ;

Используйте compat_ws для подачи функции.

SELECT MyAvg(CONCAT_WS(',',100,200,300,500)) AS test;

Вы также можете записать UDF в C (++) или Delphi/Lazarus

Ответ 2

В то время как далеко не идеальное решение, здесь, как я решил использовать дополнительные параметры для функции concat, которая мне нужна:

delimiter ||
create function safeConcat2(arg1 longtext, arg2 varchar(1023))
 returns longtext
 return safeConcat3(arg1, arg2, '');
||

create function safeConcat3(arg1 longtext, arg2 varchar(1023), arg3 varchar(1023))
 returns longtext
 return safeConcat4(arg1, arg2, arg3, '');
||

create function safeConcat4(arg1 longtext, arg2 varchar(1023), arg3 varchar(1023), arg4 varchar(1023))
returns longtext
  begin
      declare result longText;
      set result = concat(arg1, arg2, arg3, arg4);
      if( result is null) then
          set result=arg1;
      end if;
      return result;
  end
||

Примечание. Это означает, что вы должны вызвать метод, соответствующий числу аргументов.

Ответ 3

Другой подход состоит в том, чтобы передать только один параметр "супер", который представляет собой строку с запятыми в ней, разделяющую реальные параметры. Затем процедура mysql может анализировать параметр "супер" в отдельных реальных параметрах. Пример:

create procedure procWithOneSuperParam(param1 varchar(500))
declare param2 varchar(100);
begin
 if LOCATE(',',param1) > 0 then
  .. param2=<extract the string after the ',' from param1> ..