powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Необходимо изящное решение
14 сообщений из 14, страница 1 из 1
Необходимо изящное решение
    #32052411
kreek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Привет всем!
Никак не могу догнать, как можно наложить Constraint уникальности на один столбец (где NULL допустим), так, чтобы было допустимо множественность NULL значений, а NOT NULL были уникальны.
...
Рейтинг: 0 / 0
Необходимо изящное решение
    #32052413
Фотография Jimmy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С помощью триггеров for insert & for update .
...
Рейтинг: 0 / 0
Необходимо изящное решение
    #32052419
kreek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Check Constraint Expression в этой ситуации можно прикрутить?
...
Рейтинг: 0 / 0
Необходимо изящное решение
    #32052420
Miha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если SQL2000 EE - построить indexed view по этому столбцу
...
Рейтинг: 0 / 0
Необходимо изящное решение
    #32052431
kreek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Может ли Check Constraint Expression выполнить ПРОСТОЙ селект на EXISTS. Да или нет?
...
Рейтинг: 0 / 0
Необходимо изящное решение
    #32052450
Genady
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А что Вы пробовали вставить 2 значения null и у вас констрейнт ругался по этому поводу?
Если да, то см. Set ANSI_Nulls.
...
Рейтинг: 0 / 0
Необходимо изящное решение
    #32052467
Miha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Действительно, unique constraint все решает. что-то я переборщил со view.
...
Рейтинг: 0 / 0
Необходимо изящное решение
    #32052506
Фотография Александр Степанов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
To Genady - Set ANSI_Nulls не поможет

To Miha
Код: plaintext
1.
2.
3.
4.
5.
6.
create table #tmp (a int unique)
insert into #tmp values ( 0 )
insert into #tmp values ( 1 )
insert into #tmp values ( 2 )
insert into #tmp values (null)
insert into #tmp values (null)

Запускаем и получаем:
Код: plaintext
1.
2.
3.
Server: Msg  2627 , Level  14 , State  2 , Line  6 
Violation of UNIQUE KEY constraint 'UQ__#tmp__43D64501'. Cannot insert duplicate key in object '#tmp________________________________________________________________________________________________________________000000000037'.
The statement has been terminated.


Так что Jimmy дело говорит - констрейнт для случая "чтобы было допустимо множественность NULL значений" не поможет.
...
Рейтинг: 0 / 0
Необходимо изящное решение
    #32052507
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вроде как обсуждали уже
...
Рейтинг: 0 / 0
Необходимо изящное решение
    #32052636
Miha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
create table dbo.tbl1 (
	i1	int not null,
	i2	int,
constraint pk_tbl1 primary key clustered (i1)
)
go

create view dbo.v_tbl1_unique with SCHEMABINDING 
as
select i1, i2 from dbo.tbl1 where i2 is not null
go

create unique clustered index idx_v_tbl1_unique on dbo.v_tbl1_unique (i2)
go

insert into dbo.tbl1 values ( 1 , 1 )
insert into dbo.tbl1 values ( 2 ,NULL)
insert into dbo.tbl1 values ( 3 , 2 )
insert into dbo.tbl1 values ( 4 ,NULL)
 --а тут будет ошибка
 
insert into dbo.tbl1 values ( 5 , 2 )
go
...
Рейтинг: 0 / 0
Необходимо изящное решение
    #32056910
kreek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем спасибо!
Поступило несколько предложений:
Использовать INSTEAD OF Trigger как тут .

Использовать unique clustered index on view.

Использовать FUNCTION в CHECK CONSTRAINT (можно сохранять вместо NULL - 0)

Выносить в дочернюю таблицу
Может проголосуем, что лучше, а то я никак не могу определиться, что использовать. Большим плюсом считаю аргументы в пользу гибкости, т.е. если это будет функция, то, есть возможность прикрутить ее в различных таблицах, также скорость немаловажный фактор.
...
Рейтинг: 0 / 0
Необходимо изящное решение
    #32057193
Фотография RatTail
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
From MSKB:
----------------------------

Код: plaintext
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.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
The Calculated Column Solution
The following solution uses a calculated column to prevent
duplicate non-null values.

CREATE TABLE [Table2] (
	[pk] [int] IDENTITY ( 1 ,  1 ) NOT NULL , 
	[Col1] [int] NULL ,
	[Col2] AS ( 	
			CASE 
				WHEN Col1 IS NULL 
THEN pk 
				ELSE  0  
			END
		    )
	CONSTRAINT UNQ_NULLS UNIQUE ( Col1,Col2 )
)
GO

Test the solution with the following insert statements: 
INSERT INTO Table2 ( Col1 ) VALUES(  1  )
INSERT INTO Table2 ( Col1 ) VALUES(  1  ) *
* This insert statement fails with this error: 

Violation of UNIQUE KEY constraint 'UNQ_NULLS'.
Cannot insert duplicate key in object 'Table2'. The statement has been terminated. 
INSERT INTO Table2 ( Col1 ) VALUES(  2  )
INSERT INTO Table2 ( Col1 ) VALUES(  3  )
INSERT INTO Table2 ( Col1 ) VALUES( NULL )
INSERT INTO Table2 ( Col1 ) VALUES( NULL ) 'This INSERT runs without error.
INSERT INTO Table2 ( Col1 ) VALUES( NULL ) 'This INSERT runs without error.
Now, if you query the table, you get these results: 
SELECT * FROM Table2

pk          Col1        Col2        
 ----------- ----------- -----------
 
 1             1             0 
 3             2             0 
 4             3             0 
 5            NULL       5 
 6            NULL       6 
 7            NULL       7 
The calculated column solution provides a clean solution to this problem.
One advantage is that the constraint is applied to the table 
itself, and no extra view or trigger is required. Again, with this 
solution, an error is raised that can notify the calling 
application when the constraint is violated.

...
Рейтинг: 0 / 0
Необходимо изящное решение
    #32057581
Фотография RatTail
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так всё-таки, гуры, подскажите, что лучше?
...
Рейтинг: 0 / 0
Необходимо изящное решение
    #32057592
Фотография akuz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я, конечно не гуру, но по моему скромному мнению, использование 0 вместо NULL во внешнем ключе, решает многие проблемы, но правда пока я не понял, какие новые проблемы это порождает.

Зато вместо left join вы всегда сможете писать inner join. Что вроде бы оптимизирует запрос.
А если надо исключить нулевые значения просто пишете в условии inner join table on table.fkey = ftable.id and table.fkey <> 0
Опять же лишняя проверка, но зато inner join.

Решение гибкое, правда придётся во все справочники добавить пустое значение с id = 0 и перелопатить все запросы в которых используется outer join.
Не хотите, используйте предложение RatTail, гибче и проще не придумаешь.

А тригеры и indexed view штука гемороидальная и без них вполне можно обойтись.
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Необходимо изящное решение
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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