В SQL Server я могу реализовать функцию avg вручную? проблема с передачей имени столбца для использования - PullRequest
1 голос
/ 16 марта 2019

В SQL Server я хочу создать функцию, аналогичную avg, где я получаю имя столбца в качестве параметра и запрашиваю таблицу, чтобы получить значения для указанного столбца.

Возможно, это невозможноЯ увидел, что не могу использовать exec для общего решения вне функций, то есть для конкатенации строки запроса и ее выполнения.

create function myAvg(@columnName varchar(255))
returns float
as
begin
    declare @queryStr varchar(255) = '(select AVG(cast(' + @columnName + ' as float)) from functionTest)';
    return execute( @queryStr);
end

Я получаю эту ошибку:

RETURN-операторы вСкалярные функции должны содержать аргумент

Другое решение с курсорами:

create function myAvg (@columnName varchar(255))
returns float
as
begin
    declare @MyCursor as cursor;
    declare @value float;
    declare @total float = 0.0;
    declare @nElems int = 0;

    set @MyCursor = cursor for
                       select @columnName from functionTest;

    open @MyCursor;

    fetch next from @MyCursor into @value;

    while @@FETCH_STATUS = 0
    begin
        set @total = @total + @value;
        set @nElems = @nElems + 1;

        fetch next from @MyCursor into @value;
    end

    close @MyCursor;
    deallocate @MyCursor;

    return @total /@nElems
end

При вызове решения для курсора возникает эта ошибка:

Ошибка преобразования данныхвведите varchar to float

Я полагаю, что функции не могут быть настолько универсальными с динамической параметризацией столбцов.

Есть ли альтернатива?

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

Спасибо

Ответы [ 2 ]

2 голосов
/ 16 марта 2019

Вы не можете делать то, что хотите.

Во-первых, вы не можете заменить идентификатор, такой как имя столбца, параметром. Это просто не то, как работают параметры. Они заменяют только постоянные значения.

Во-вторых, функция не может выполнять динамический SQL. Вы можете обойти первую проблему, используя динамический SQL, но это не разрешено в функции.

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

Вместо этого вы можете просто использовать оконную функцию во внешнем запросе:

select . . . ,
       avg(column_name) over ()
from . . .;

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

1 голос
/ 16 марта 2019

вы не можете использовать execute в функциях. Для этого лучше использовать функции CLR. https://docs.microsoft.com/en-us/sql/relational-databases/user-defined-functions/create-clr-functions?view=sql-server-2017

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...