Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 [2]      все
 Re: Шаблон SP для определения переданных параметров  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1909
Tketano,

вы же сами указывали на проблему
"пропихнуть" NULL как реальное значение"


в вашем решение в случае
exec dbo.usp_update
		@id	= @id,
		@val1	= @val1,
		@val2	= null,
		@val3	= @val3


вы значение @val2 потеряете


aleks222
Универсальные лисапеды всегда громоздки...


в процедуре 1000 параметров, добавите еще 1000?

Сообщение было отредактировано: 15 ноя 21, 14:41
15 ноя 21, 14:39    [22396210]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон SP для определения переданных параметров  [new]
Tketano
Member

Откуда:
Сообщений: 109
felix_ff,

Да, в базовой процедуре update 100+ параметров, значит придется и в обертке объявить 100+ параметров и поставить 100+ case. Сейчас без обертки то не лучше - начитай недостающие 100 параметров c case из таблицы и потом сделай EXEC базовой процедуры. Тут же не стоит вопрос уменьшения кода (хотя этот вариант в любом случае короче), вопрос скорее в понятности и дальнейшей поддержке. Например, в базовую процедуру достаточно часто вводятся новые параметры.

в вашем решение в случае
exec dbo.usp_update
		@id	= @id,
		@val1	= @val1,
		@val2	= null,
		@val3	= @val3


вы значение @val2 потеряете


При таком вызове да. Но я же буду вызывать обертку и значение сохранится:
exec dbo.usp_update_some_rekv
		@id	= @id,
		@val1	= @val1,
		@val2	= null,
		@val3	= @val3


А при передачи @val2 = '' значение будет сброшено в null.

Сообщение было отредактировано: 15 ноя 21, 15:00
15 ноя 21, 14:59    [22396220]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон SP для определения переданных параметров  [new]
Ролг Хупин
Member

Откуда: Чебаркуль
Сообщений: 4434
Tketano
Всем спасибо за мнения! Динамический SQL явно мимо; финальные контроли осуществляются на сервере. Может изначально плохо пояснил задачу. Смысл в том, что есть много входных точек для изменения данных (api), реализующих разные форматы и разный набор полей. Соответственно вопрос был в обновлении информации в базе данных (после приема входящего запроса).
Пока остановились на следующем варианте:
create or alter procedure [usp_update_some_rekv]
	@id	int,
	@val1	int		= null,	-- -1 = сбросить в null (значение -1 не допускается бизнес-логикой)
	@val2	varchar(255)	= null,	-- '' = сбросить в null (пустая строка не допускается бизнес-логикой)
	@val3	date		= null	-- '' = сбросить в null (1900 год не допускается бизнес-логикой)
as

select	@val1 = case when @val1 = -1 then null else isnull(@val1, val1) end,
	@val2 = case when @val2 = '' then null else isnull(@val2, val2) end,
	@val3 = case when @val3 = '' then null else isnull(@val3, val3) end
from	[dbo].[tbl]
where	[id] = @id;

-- базовая процедура для записи параметров "как есть"
exec dbo.usp_update
		@id	= @id,
		@val1	= @val1,
		@val2	= @val2,
		@val3	= @val3
go


Хотя итоговое решение не понравилось (вызов такой ХП выглядит "неестественным"). Пока будет использоваться исключительно локально (для решения конкретной задачи). Возможно, часть контролей будет перенесена + прямой UPDATE таблицы + прочая логика процедуры usp_update.


итоговое решение выглядит "нетрадиционным" в понятном смысле этого слова
15 ноя 21, 17:50    [22396321]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон SP для определения переданных параметров  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 32173
Tketano
Пока остановились на следующем варианте:

Ой, а сначала сказали, что так точно не подходит :-)
Tketano
Смысл в том, что есть много входных точек для изменения данных (api), реализующих разные форматы и разный набор полей.
Так и делайте несколько входных точек (api).
Вы хотите сделать одну входную точку для всего приложения? Поверьте, нехорошо получится
Впрочем большинство учится только на своих ошибках, вы же (и никто из ваших коллег) ещё не сделали проект, который люди сейчас называют легаси? :-) Судя по стремлению к "универсальному коду"

Сообщение было отредактировано: 15 ноя 21, 19:04
15 ноя 21, 19:03    [22396367]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон SP для определения переданных параметров  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 32173
Ролг Хупин
итоговое решение выглядит "нетрадиционным" в понятном смысле этого слова
Да, понятность кода поражает.

Доктор, понимаете, мой муж работает программистом, и он последний год стал часто смотреть индусский код.
А иногда, по ночам, когда думает, что я его не вижу, он его себе вставляет. И это ему нравится!
15 ноя 21, 19:09    [22396369]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон SP для определения переданных параметров  [new]
Ролг Хупин
Member

Откуда: Чебаркуль
Сообщений: 4434
alexeyvg
Ролг Хупин
итоговое решение выглядит "нетрадиционным" в понятном смысле этого слова
Да, понятность кода поражает.

Доктор, понимаете, мой муж работает программистом, и он последний год стал часто смотреть индусский код.
А иногда, по ночам, когда думает, что я его не вижу, он его себе вставляет. И это ему нравится!


(Y)
15 ноя 21, 20:33    [22396394]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон SP для определения переданных параметров  [new]
Tketano
Member

Откуда:
Сообщений: 109
alexeyvg,

автор
Ой, а сначала сказали, что так точно не подходит :-)
Нет, я такое не писал, Вы меня с кем-то перепутали =) Я сразу озвучил эту идею под вторым вариантом.
И в серверной части итак хватает старого легаси-кода, в основном связанного с динамическим sql))) Хламить не хочется, даже для решения небольшой задачи.

автор
Так и делайте несколько входных точек (api).
Вы хотите сделать одну входную точку для всего приложения? Поверьте, нехорошо получится
Нет. Немного love story.
Есть базовая процедура для изменения сущности БД (usp_update в примере выше). На вход принимается полный перечень параметров и записывается в БД "как есть". При этом в процедуре реализуется прочая логика по проверкам, записи в логи и пр. Основная система в основном и дергает данную процедуру, т.к. почти всегда обладает информацией о полном состоянии объекта.
Однако есть и другие точки входа (различные api) для коррекции информации (включая xml/json форматы). Там перечень параметров гораздо уже. Общий подход следующий:
- если параметр не определен форматом, то оставляем текущее значение БД;
- если значение параметра/тега указано, то записываем в БД (включая пустое значение => NULL);
- если параметр/тег отсутствует, то оставляем текущее значение БД.
И проблема как раз в том, что код в этих точках входа (api) уже весьма сложный и неочевидный, с большими свистоплясками, чтобы вызвать базовую процедуру или выполнить прямой UPDATE. В первом случае это начитка большого числа параметров (текущее состояние в БД), а во втором это вынесенные контроли + запись в логи и пр. логика (хотя сам UPDATE таблицы смотрится конечно максимально читабельно). Делать свой вариант usp_update под каждый API выглядит трудозатратным (тем более там небольшая разница от api к api). Какая-нибудь обертка поверх базовой usp_update, которую можно было бы дергать из каждой точки входа (api), значительно бы упростила логику. Вопрос открыт :-)
15 ноя 21, 22:48    [22396413]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон SP для определения переданных параметров  [new]
invm
Member

Откуда: Москва
Сообщений: 9913
Tketano,

В качестве идеи
declare @t table (id int primary key, f1 int, f2 int, f3 int, f4 int);
insert into @t
values
 (1, 1, 2, 3, 4);

select * from @t;

declare @id int = 1, @f1 int, @f2 int, @f3 int, @f4 int;
declare @params xml = '<params f1 = "10" f4 = ""/>';

select
 @f1 = case when @params.exist('/params[1][@f1]') = 1 then @params.value('xs:integer(/params[1]/@f1)', 'int') else f1 end,
 @f2 = case when @params.exist('/params[1][@f2]') = 1 then @params.value('xs:integer(/params[1]/@f2)', 'int') else f2 end,
 @f3 = case when @params.exist('/params[1][@f3]') = 1 then @params.value('xs:integer(/params[1]/@f3)', 'int') else f3 end,
 @f4 = case when @params.exist('/params[1][@f4]') = 1 then @params.value('xs:integer(/params[1]/@f4)', 'int') else f4 end
from
 @t
where
 id = @id;

update @t
 set
  f1 = @f1, f2 = @f2, f3 = @f3, f4 = @f4
where
 id = @id;

select * from @t;
16 ноя 21, 09:50    [22396468]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон SP для определения переданных параметров  [new]
Tketano
Member

Откуда:
Сообщений: 109
invm,

Спасибо за мысль. XML собирать в некоторых случаях может быть чуть труднее, но безусловно логика процедуры становится более прозрачной. На самом деле в некоторые точки (api) на вход и прилетают такие xml :)
19 ноя 21, 16:34    [22398032]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 [2]      все
Все форумы / Microsoft SQL Server Ответить