Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Как сделать апдейт в таком случае?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
Если делаю так, то поле banner апдейтиться только один раз, а хотелось бы, чтобы N раз, по количеству записей с тем же id.

update n_ex9 set banner= [dbo].[fnSet3](banner, t.role_id)
from n_ex9 n inner join #t1 t on t.id=n.id;


Как написать такой запрос?
10 июн 14, 19:11    [16151009]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать апдейт в таком случае?  [new]
invm
Member

Откуда: Москва
Сообщений: 9400
Winnipuh
Как написать такой запрос?
Никак.
10 июн 14, 19:40    [16151122]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать апдейт в таком случае?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
invm
Winnipuh
Как написать такой запрос?
Никак.


спасибо!
10 июн 14, 20:15    [16151251]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать апдейт в таком случае?  [new]
iiyama
Member

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

INSTEAD OF UPDATE ?
10 июн 14, 20:21    [16151275]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать апдейт в таком случае?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Winnipuh
update n_ex9 set banner= dbo.fnSet3(banner, t.role_id)
from n_ex9 n inner join #t1 t on t.id=n.id;
Как написать такой запрос?
Вы не понимаете язык SQL. И встроенную некрасивость оператора UPDATE.

Кстати и синтаксис тоже не усвоили, после UPDATE пишется алиас, а не имя таблицы. Всегда.
И писать схему таблиц (объектов) тоже надо всегда. Под страхом смерти.

Если вы посмотрите план там будет подсказка - агрегация.
Как мы знаем, результат реляционного перемножение может выдавать несколько кортежей на один базовый. Но синтаксис указывает именно алиас таблицы, хотя природа обновления явно однозначная.
Скулевцы подставили костыль - неявную агрегацию, которая видна в плане как агрегирущий оператор ANY, который кстати не доступен для явного использования (что тоже считаю нелепостью).
Можете пинать за это самого Д. Чемберлина, кстати на это сам Эдгар Кодд плевался.
А вот в операторе MERGE сделали ровно наоборот - пресекли такую возможность, и это намного правильней.
Но уже всё, пресловутая обратная совместимость багов будет ипать нас всех до конца дней. Только сменой платформы и языка это может спасти.
Кстати как продолжение развития реляционных систем создаётся язык D.

Вам остаётся только исправить запрос, чтобы агрегация была явно написана, и именно правильно по логике.
Как с-агрегировать роли и проставить нужные биты вы думаю догадаетесь. Или нет?

А нормальным пацанам, можно расширить контроль системы путём поиска в планах оператора ANY, ибо это зло и скорее ошибка. Я бы сказал однозначно, ибо ничего не должно быть скрыто, а чётко формализовано.
10 июн 14, 21:49    [16151568]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать апдейт в таком случае?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
2 Mnior

Каков слог!

Пушкенд в углу лежыт
10 июн 14, 23:08    [16151774]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать апдейт в таком случае?  [new]
juwdoks
Member

Откуда:
Сообщений: 144
Mnior, а почему так жестко насчет написания схемы? Если хранимка в дефолтной схеме использует, например, вьюху, построенную для каждого пользователя (схемы) отдельно - это архитектура страдает?
11 июн 14, 02:56    [16152102]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать апдейт в таком случае?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
iiyama
Winnipuh,

INSTEAD OF UPDATE ?


получается что-то типа такого

create table t (id int, b binary(128))

insert into t(id, b) values (1, 0x010000)
insert into t(id, b) values (1, 0x000204)
insert into t(id, b) values (2, 0x000004)
insert into t(id, b) values (2, 0x010004)
insert into t(id, b) values (2, 0x010000)


А результат должен сожержать две записи с ид 1 и 2 и с binary полями, содержащими OR-нутые биты поля b,
то есть типа
1 0x010204
2 0x010004

Похоже на это:
select id, fun(b) from t group by id


Вопрос: нужно писать SQLCLR аггрегатную функцию или есть варианты?
11 июн 14, 08:54    [16152291]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать апдейт в таком случае?  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7868
Можно cross apply присандалить.
11 июн 14, 10:50    [16152929]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать апдейт в таком случае?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
Владислав Колосов
Можно cross apply присандалить.


как это сделать например хотя бы в простом случае (см. предыдущее сообщение)?
11 июн 14, 11:14    [16153135]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать апдейт в таком случае?  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7868
Бинари не агрегируется и не обрабатывается битовыми операциями, как выяснилось. Я бы применил CLR и курсор.
11 июн 14, 11:30    [16153283]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать апдейт в таком случае?  [new]
iap
Member

Откуда: Москва
Сообщений: 47000
SUBSTRINGом можно выбрать нужный байт, преобразовать его в INT, после этого применить битовые операторы
11 июн 14, 11:49    [16153476]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать апдейт в таком случае?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
Владислав Колосов
Бинари не агрегируется и не обрабатывается битовыми операциями, как выяснилось. Я бы применил CLR и курсор.



Похоже так должно неплохо получиться:

1. без курсора
2. написать свою aggregate функцию, которая будет "суммировать" (OR-ить) массив байтов
11 июн 14, 16:46    [16156032]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать апдейт в таком случае?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
juwdoks
а почему так жестко насчет написания схемы?
15958064
Mnior
Как с-агрегировать роли и проставить нужные биты вы думаю догадаетесь. Или нет?
Winnipuh
Вопрос: нужно писать SQLCLR аггрегатную функцию или есть варианты?
Не догадались. А всё так просто.
iap
SUBSTRINGом можно выбрать нужный байт, преобразовать его в INT, после этого применить битовые операторы
А вот сказать какой же реально будет этот "битовый" оператор было слабо?

Winnipuh, берёте код 16159789 и:
DECLARE	@Test TABLE (ID Int, [Role] Binary(3))
INSERT	@Test VALUES
 (1, 0x010000)
,(1, 0x000200)
,(1, 0x000004)
,(2, 0x010000)
,(2, 0x000004)

SELECT	G.ID
,	A.[Binary]	AS Roles
FROM (	SELECT	T.ID,Sum(L1),Sum(L2),Sum(L3),Sum(L4),Sum(L5),Sum(L6),Sum(L7),Sum(L8)
	FROM	@Test	T CROSS
	APPLY	dbo.fnBinaryToLong(T.[Role]) L
	GROUP BY T.ID	)	G (ID,L1,L2,L3,L4,L5,L6,L7,L8)
CROSS	APPLY dbo.fnLongToBinary  ( 3,L1,L2,L3,L4,L5,L6,L7,L8) A
IDRoles
10x010204
20x010004
Winnipuh
 (1,0x010000)
,(1,0x000204)
,(2,0x000004)
,(2,0x010004)
,(2,0x010000)
Это как у вас роль может иметь несколько установленных битов одновременно?!
В этом то и прикол, что у разных ролей биты не пересекаются, поэтому и можно применить обычный Sum.
12 июн 14, 22:37    [16159814]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить