T-SQL Определяемая пользователем перегрузка функции? - PullRequest
24 голосов
/ 26 июня 2009

Я понимаю, что T-SQL не является объектно-ориентированным. Мне нужно написать набор функций, которые имитируют перегрузку метода в C #.

Перегрузка функций поддерживается в T-SQL каким-либо образом? Если для этого есть хак, рекомендуется ли это?

Ответы [ 7 ]

11 голосов
/ 27 июня 2009

Нет, нет способа сделать это.

Я рекомендую вам пересмотреть это требование, так как "сделать яблоки похожими на апельсины" часто трудно и имеет сомнительную ценность.

6 голосов
/ 07 января 2011

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

Пример:

create function ActiveUsers
(
    @departmentId int,
    @programId int
)
returns int
as
begin
    declare @count int

    select @count = count(*)
    from users
    where
        departmentId = isnull(@departmentId, departmentId)
        and programId = isnull(@programId, programId)

    return @count
end
go

Использование:

select ActiveUsers(1,3) -- users in department 1 and program 3
select ActiveUsers(null,3) -- all users in program 3, regardless of department
select ActiveUsers(null,null) -- all users
5 голосов
/ 26 июня 2009

Вы можете передать sql_variant , но это сопровождается всевозможными опасностями; Вы не можете использовать строгую типизацию, как в случае с ОО-языками и перегрузками.

Если вам нужно найти базовый тип в вашей функции, вы можете использовать функцию SQL_VARIANT_PROPERTY.

1 голос
/ 27 июня 2009

Вы можете передать массив значений в одной строке и разобрать их , используя эту технику Эрланда Соммарскога .

Создайте функцию с параметром varchar(max) или несколькими, если необходимо, затем укажите значения параметров в этой строке, например:

param1;param2;parma3;param4

или

param1:type;param2:type;param3:type

или

calltype|param1;param2;param3

и т. Д., Вы ограничены только вашим воображением ...

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

0 голосов
/ 06 июня 2018

Решение, с которым мне посчастливилось немного удачи, заключается либо в создании ряда функций, каждый из которых принимает различный тип данных, либо в преобразовании всех входных данных в NVARCHAR (MAX).

1. создание ряда функций, каждая из которых принимает свой тип данных

CREATE FUNCTION [dbo].[FunctionNameDatetime2]
CREATE FUNCTION [dbo].[FunctionNameInt]
CREATE FUNCTION [dbo].[FunctionNameString] --(this is not a typo)
CREATE FUNCTION [dbo].[FunctionNameUniqueidentifier]
...

Проблема: Дублирование кода и множество функций

2. Приведите все данные к NVARCHAR (MAX)

CREATE FUNCTION [dbo].[IntToNvarchar]
(
    @Key INT
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
    RETURN ISNULL(CAST(@Key AS NVARCHAR), '');
END

CREATE FUNCTION [dbo].[FunctionName]
(
    @Key NVARCHAR(MAX)
)
RETURNS CHAR(32)
AS
BEGIN
    DECLARE @something CHAR(32)

    do stuff ...

    RETURN @something;
END

SELECT [dbo].[FunctionName]([dbo].[IntToNvarchar](25))

Проблема: менее элегантный код, чем перегрузка

0 голосов
/ 08 марта 2018

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

create function dbo.Greater(
@val1 sql_variant
,@val2 sql_variant
) returns sql_variant
as
begin
declare @rV sql_variant

set @rV = case when @val1 >= @val2 then @val1
               else @val2 end

return @rV
end
go
0 голосов
/ 06 мая 2010

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

В нашей системе DB2 я обычно перегружаюсь следующим образом:

CREATE Функция Schema1.F1 (дата создания) дата возвращения дата возвращения + 1 месяц;

Функция CREATE Schema1.F1 (временная метка parm) дата возвращения дата возвращения (отметка времени) + 1 месяц;

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

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

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