Гость
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Временная функция / 6 сообщений из 6, страница 1 из 1
16.10.2021, 17:45
    #40104952
ferzmikk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Временная функция
Здравствуйте!

Есть исходные данные.
SQL. Исходные данные
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
CREATE TABLE #Table1(
	ГруппаSKU VARCHAR(20),
	SKU VARCHAR(10),
	Дата INTEGER,
	Мера1 INTEGER,
	Мера2 INTEGER
);

INSERT INTO #Table1 
	(ГруппаSKU, SKU, Дата, Мера1, Мера2)
VALUES
	('ГруппаSKU 1', 'SKU 1', 202001, 10, 20),
	('ГруппаSKU 1', 'SKU 2', 202001, 20, 20),
	('ГруппаSKU 1', 'SKU 3', 202101, 30, 40),
	('ГруппаSKU 1', 'SKU 4', 202101, 40, 40),
	('ГруппаSKU 2', 'SKU 5', 202001, 10, 20),
	('ГруппаSKU 2', 'SKU 6', 202001, 20, 20),
	('ГруппаSKU 2', 'SKU 7', 202101, 30, 40),
	('ГруппаSKU 2', 'SKU 8', 202101, 40, 40);

Есть SQL-запрос
SQL
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
SELECT
	ГруппаSKU,
	SKU,
	Дата,
	(CASE
		WHEN Мера1 = 10 THEN 'A'
		WHEN Мера1 = 20 THEN 'B'
		WHEN Мера1 = 30 THEN 'C'
		WHEN Мера1 = 40 THEN 'D'
	END) AS Мера1,
	(CASE
		WHEN Мера2 = 10 THEN 'A'
		WHEN Мера2 = 20 THEN 'B'
		WHEN Мера2 = 30 THEN 'C'
		WHEN Мера2 = 40 THEN 'D'
	END) AS Мера2
FROM
	#Table1;

Результат корректный. Но для Мера1 и Мера2 заметно, что расчет одинаковый и приходится повторятся в формулах. А если много полей, да еще и сложные формулы, то запрос получается большим, что можно сделать ошибку как человеческий фактор. Одну формулу приходится накладывать на другую формулу. И такие формулы приходится писать часто.

Для этого можно создать пользовательскую функцию.
SQL
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
GO

CREATE
	FUNCTION dbo.MyFunction (@Мера INT)
	RETURNS VARCHAR(1)
BEGIN
	DECLARE @Result VARCHAR(1)	
		SELECT
			@Result =
			(CASE
				WHEN @Мера = 10 THEN 'A'
				WHEN @Мера = 20 THEN 'B'
				WHEN @Мера = 30 THEN 'C'
				WHEN @Мера = 40 THEN 'D'
			END)

		RETURN @Result
END;

GO

SELECT
	ГруппаSKU,
	SKU,
	Дата,
	dbo.MyFunction(Мера1) AS Мера1,
	dbo.MyFunction(Мера2) AS Мера2
FROM
	#Table1;

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

Временную функцию как
Код: sql
1.
CREATE FUNCTION #MyFunction

не возможно создать.

Скажите, какой есть способ использовать как временную функцию?
...
Рейтинг: 0 / 0
16.10.2021, 18:06
    #40104954
Владислав Колосов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Временная функция
ferzmikk,

у вас возникли проблемы, потому что вы не следуете Информационному правилу Кодда, которое гласит: "Вся информация в реляционной базе данных на логическом уровне должна быть явно представлена единственным способом: значениями в таблицах".

Вместо того, чтобы выписывать условный выбор в каждой отдельно взятой функции, заполните справочники правил и извлекайте данные из справочников.
...
Рейтинг: 0 / 0
17.10.2021, 17:36
    #40105047
ferzmikk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Временная функция
Владислав Колосов
Вместо того, чтобы выписывать условный выбор в каждой отдельно взятой функции, заполните справочники правил и извлекайте данные из справочников.
Вы имеете ввиду заполнять справочники формулами как текст?
...
Рейтинг: 0 / 0
17.10.2021, 18:37
    #40105057
andy st
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Временная функция
ferzmikk,
в понимании sql server временные объекты - это не те, которые меняются со временем, а те которые существуют только во время сессии
если в вашем случае необходимо, чтобы функция в зависимости от какого-то опорной даты производила разные расчёты на основании входных значений, то это будет либо скалярная функция типа MyFunction, только на входе будет еще дата и внутри ветки на обработку разных алгоритмов в зависимости от входной даты. Либо inline табличная функция с теми же входными и немного иначе выводимыми выходными данными, отличающаяся внутренней реализацией, но более приятная для оптимизатора запросов.
"CASE WHEN @Мера = 10 THEN 'A'" очень неплохо укладывается на справочник с двумя полями: значение и значение-замена. Если алгоритм не меняется, а меняются только варианты замен, то такой справочник join к основной таблице и case when делается уже на основе полей базовой таблицы и справочника замен.
...
Рейтинг: 0 / 0
17.10.2021, 20:00
    #40105063
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Временная функция
ferzmikk
Владислав Колосов
Вместо того, чтобы выписывать условный выбор в каждой отдельно взятой функции, заполните справочники правил и извлекайте данные из справочников.
Вы имеете ввиду заполнять справочники формулами как текст?
В данном случае сделать справочник MeraNum int, MeraCode varchar

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

Но надо постараться, по возможности, а если не получится, то, во первых, почему именно временные? Формулы же у вас не рождаются от генератора случайных чисел, сделайте постоянные функции :-)
Во вторых, функции очень непроизводительны, так что изучите этот вопрос перед принятием такого ответственного архитектурного решения.
Функции есть табличные скалярные, инлайн, поизучайте всё это месяцок, потрейсите, почитайте планы, сделайте замеры, сведите замеры в отчёт.
А то переделывать всё с нуля после запуска в прод будет обидно, и грозит последствиями.
...
Рейтинг: 0 / 0
17.10.2021, 20:01
    #40105064
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Временная функция
ferzmikk
Владислав Колосов
Вместо того, чтобы выписывать условный выбор в каждой отдельно взятой функции, заполните справочники правил и извлекайте данные из справочников.
Вы имеете ввиду заполнять справочники формулами как текст?
Хотя и так тоже делают, потом используют эти формулы в динамическом SQL, или с клиента.
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Временная функция / 6 сообщений из 6, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]