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

Откуда: Жатай->Подольск
Сообщений: 137
имеем
+

/****** Object:  Table [dbo].[Table_1]    Script Date: 03/26/2012 17:43:19 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Table_1](
	[id] [int] IDENTITY(1,1) NOT NULL,
	[name] [nvarchar](50) NOT NULL,
	[begindate] [smalldatetime] NOT NULL,
	[enddate] [smalldatetime] NULL,
 CONSTRAINT [PK_Table_1] PRIMARY KEY CLUSTERED 
(
	[id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[Table_1]  WITH NOCHECK ADD  CONSTRAINT [BeginDate_EndDate] CHECK  (([begindate]<[enddate]))
GO

ALTER TABLE [dbo].[Table_1] CHECK CONSTRAINT [BeginDate_EndDate]
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Table_1', @level2type=N'CONSTRAINT',@level2name=N'BeginDate_EndDate'
GO

ALTER TABLE [dbo].[Table_1]  WITH NOCHECK ADD  CONSTRAINT [CK_Table_1] CHECK  (([dbo].[UniqueName]([name],[begindate],[enddate])=(1)))
GO

ALTER TABLE [dbo].[Table_1] CHECK CONSTRAINT [CK_Table_1]
GO


и

/****** Object:  UserDefinedFunction [dbo].[UniqueName]    Script Date: 03/26/2012 17:43:50 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

-- =============================================
-- Author:		<Author,,Name>
-- Create date: <Create Date, ,>
-- Description:	<Description, ,>
-- =============================================
CREATE FUNCTION [dbo].[UniqueName]
(
	@name nvarchar(50),
	@begindate smalldatetime,
	@enddate smalldatetime
)
RETURNS bit
AS
BEGIN
	IF (@name is null or @begindate is null)
		return 0;
	
	declare @result int
	
	select @result=count(*) from Table_1 a where a.name=@name and a.begindate is not null and a.enddate is null
	if @result>=1
		return 0;

	return 1;
END

GO



когда пытаемся добавить запись
insert into Table_1 (name, begindate, enddate) values ('qwerty1', '20090101', null)

получаем срабатывание ограничения

P.S. Всегда считал что ограничения проверяются до вставки ...
26 мар 12, 17:47    [12316284]     Ответить | Цитировать Сообщить модератору
 Re: когда отрабатывает CHECK ???  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Matroskin
P.S. Всегда считал что ограничения проверяются до вставки ...
Типа, это пока вы еще код пишете, что ли?
26 мар 12, 17:49    [12316302]     Ответить | Цитировать Сообщить модератору
 Re: когда отрабатывает CHECK ???  [new]
Matroskin
Member

Откуда: Жатай->Подольск
Сообщений: 137
Гавриленко Сергей Алексеевич,

да, делаю уникальность по полю [name] с условием не пересечения периодов

Если есть какие либо идеи, подскажите ...
26 мар 12, 17:53    [12316325]     Ответить | Цитировать Сообщить модератору
 Re: когда отрабатывает CHECK ???  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Я бы это делал не через чек + функция. Будет тормозить. Делайте проверку на триггерах.

З.Ы. К тому же не понятно, как регламентировать порядок проверки различных чеков.
26 мар 12, 17:56    [12316339]     Ответить | Цитировать Сообщить модератору
 Re: когда отрабатывает CHECK ???  [new]
Ivan Durak
Member

Откуда: Minsk!!!
Сообщений: 3755
Matroskin
Гавриленко Сергей Алексеевич,

да, делаю уникальность по полю [name] с условием не пересечения периодов

Если есть какие либо идеи, подскажите ...

при генерации этих периодов и проверять. Самим программно.
26 мар 12, 17:57    [12316342]     Ответить | Цитировать Сообщить модератору
 Re: когда отрабатывает CHECK ???  [new]
Matroskin
Member

Откуда: Жатай->Подольск
Сообщений: 137
забыл добавить, изначально таблица пустая, т.е. вставляю первую запись
26 мар 12, 17:57    [12316344]     Ответить | Цитировать Сообщить модератору
 Re: когда отрабатывает CHECK ???  [new]
trew
Member

Откуда: Москва
Сообщений: 2646
Может триггер FOR INSERT на таблицу повесить, и там проверять?
26 мар 12, 17:57    [12316345]     Ответить | Цитировать Сообщить модератору
 Re: когда отрабатывает CHECK ???  [new]
Matroskin
Member

Откуда: Жатай->Подольск
Сообщений: 137
Гавриленко Сергей Алексеевич,

а в чем разница?

ведь и в том и в другом случае будет выполняться код триггера/функции
26 мар 12, 17:59    [12316363]     Ответить | Цитировать Сообщить модератору
 Re: когда отрабатывает CHECK ???  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Matroskin
Гавриленко Сергей Алексеевич,

а в чем разница?

ведь и в том и в другом случае будет выполняться код триггера/функции
Разница в том, что в триггере можно написать пакетную проверку на все вставляемые записи разом, а тут будет вызов функции на каждую запись, скорее всего.
26 мар 12, 18:00    [12316375]     Ответить | Цитировать Сообщить модератору
 Re: когда отрабатывает CHECK ???  [new]
Matroskin
Member

Откуда: Жатай->Подольск
Сообщений: 137
Гавриленко Сергей Алексеевич,

понятно, спасибо ...
26 мар 12, 18:03    [12316393]     Ответить | Цитировать Сообщить модератору
 Re: когда отрабатывает CHECK ???  [new]
aleks2
Guest
Гавриленко Сергей Алексеевич
Matroskin
Гавриленко Сергей Алексеевич,

а в чем разница?

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


1. А вот Microsoft настоятельно рекомендует CHECK CONSTRAINT вместо триггеров. А триггера тока от безысходности.

2. Какие проблемы? Надеюсь у тредстартера в таблице есть primary key?
26 мар 12, 18:09    [12316418]     Ответить | Цитировать Сообщить модератору
 Re: когда отрабатывает CHECK ???  [new]
invm
Member

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

Ваша функция вполне корректно отработала, чего вы удивляетесь?
А вообще, вместо чека и функции можно вот так:
create unique index IX_Table_1__name on dbo.Table_1 (name) where begindate is not null and enddate is null;
26 мар 12, 18:10    [12316428]     Ответить | Цитировать Сообщить модератору
 Re: когда отрабатывает CHECK ???  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
aleks2
1. А вот Microsoft настоятельно рекомендует CHECK CONSTRAINT вместо триггеров. А триггера тока от безысходности.
Пруфлинк можно?
26 мар 12, 18:10    [12316432]     Ответить | Цитировать Сообщить модератору
 Re: когда отрабатывает CHECK ???  [new]
Гавриленко Сергей Алексеевич
Member

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

Ваша функция вполне корректно отработала, чего вы удивляетесь?
А вообще, вместо чека и функции можно вот так:
create unique index IX_Table_1__name on dbo.Table_1 (name) where begindate is not null and enddate is null;
Кстати, да. Я как то не заметил, что чекается та же самая таблица.
26 мар 12, 18:12    [12316442]     Ответить | Цитировать Сообщить модератору
 Re: когда отрабатывает CHECK ???  [new]
aleks2
Guest
Гавриленко Сергей Алексеевич
aleks2
1. А вот Microsoft настоятельно рекомендует CHECK CONSTRAINT вместо триггеров. А триггера тока от безысходности.
Пруфлинк можно?


Не, перерывать BOL мне лениво.
26 мар 12, 18:14    [12316452]     Ответить | Цитировать Сообщить модератору
 Re: когда отрабатывает CHECK ???  [new]
Matroskin
Member

Откуда: Жатай->Подольск
Сообщений: 137
Цель: сделать уникальность по полю [name] c отсутствием пересечения по периодам

т.е.
'петя', '20100101', '20101231'
'петя', '20110101', '20111231'
можно

а
'петя', '20100101', '20101231'
'петя', '20100501', '20111231'
нельзя
26 мар 12, 18:16    [12316471]     Ответить | Цитировать Сообщить модератору
 Re: когда отрабатывает CHECK ???  [new]
Ivan Durak
Member

Откуда: Minsk!!!
Сообщений: 3755
invm
Matroskin,

Ваша функция вполне корректно отработала, чего вы удивляетесь?
А вообще, вместо чека и функции можно вот так:
create unique index IX_Table_1__name on dbo.Table_1 (name) where begindate is not null and enddate is null;

Афтору нужна проверка на ПЕРЕСЕКАЮЩИЕСЯ периоды!
26 мар 12, 18:18    [12316481]     Ответить | Цитировать Сообщить модератору
 Re: когда отрабатывает CHECK ???  [new]
Matroskin
Member

Откуда: Жатай->Подольск
Сообщений: 137
invm
Matroskin,

Ваша функция вполне корректно отработала, чего вы удивляетесь?
А вообще, вместо чека и функции можно вот так:
create unique index IX_Table_1__name on dbo.Table_1 (name) where begindate is not null and enddate is null;


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

я только начал писать функцию, проверил, а она отрабатывает не так как я предполагал, посему и возник вопрос
26 мар 12, 18:18    [12316487]     Ответить | Цитировать Сообщить модератору
 Re: когда отрабатывает CHECK ???  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Ivan Durak
Афтору нужна проверка на ПЕРЕСЕКАЮЩИЕСЯ периоды!
Однако сам автор написал проверку на то, что только один период для одного name может быть открытым.
26 мар 12, 18:20    [12316497]     Ответить | Цитировать Сообщить модератору
 Re: когда отрабатывает CHECK ???  [new]
aleks2
Guest
Кстате, местный гуру
https://www.sql.ru/forum/actualthread.aspx?bid=1&tid=283228&hl=
26 мар 12, 18:22    [12316514]     Ответить | Цитировать Сообщить модератору
 Re: когда отрабатывает CHECK ???  [new]
Matroskin
Member

Откуда: Жатай->Подольск
Сообщений: 137
Гавриленко Сергей Алексеевич,

Так, стоп, не пинайте. Изначально вопрос состоял в том, когда отрабатывает CHECK - до или после вставки.

Соответственно в данном случае на приведенную функцию, как реализующую проверку уникальности с учетом не пересечения периодов считать верной не стоит, поскольку это не так.
26 мар 12, 18:24    [12316519]     Ответить | Цитировать Сообщить модератору
 Re: когда отрабатывает CHECK ???  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
aleks2
Кстате, местный гуру
https://www.sql.ru/forum/actualthread.aspx?bid=1&tid=283228&hl=
Инстедный тоже будет выполняться до. Ну и чек с обычной проверкой и чек с вызовом функции в которой делается какой-то запрос - это две разные функции по перфомансу, не так ли?
26 мар 12, 18:24    [12316522]     Ответить | Цитировать Сообщить модератору
 Re: когда отрабатывает CHECK ???  [new]
Matroskin
Member

Откуда: Жатай->Подольск
Сообщений: 137
aleks2
Кстате, местный гуру
https://www.sql.ru/forum/actualthread.aspx?bid=1&tid=283228&hl=


да, читал, по моему не сошлось ...
26 мар 12, 18:25    [12316530]     Ответить | Цитировать Сообщить модератору
 Re: когда отрабатывает CHECK ???  [new]
invm
Member

Откуда: Москва
Сообщений: 9844
Matroskin
Цель: сделать уникальность по полю [name] c отсутствием пересечения по периодам

т.е.
'петя', '20100101', '20101231'
'петя', '20110101', '20111231'
можно

а
'петя', '20100101', '20101231'
'петя', '20100501', '20111231'
нельзя
И причем тогда ваши проверки на null и not null?
Триггером надо проверять
create trigger on dbo.Table_1
instead on insert, update
as
begin
 if not exists(select * from inserted)
  return;
 
 set nocount on;
 
 if exists(
   select
    *
   from
    inserted i join
    dbo.Table_1 t on t.name = i.name and t.enddate >= i.begindate and t.begindate <= i.enddate
  )
  begin
   raiserror('Страшная матерная ругань');
   return;
  end;
  
 ...

end;
26 мар 12, 18:28    [12316542]     Ответить | Цитировать Сообщить модератору
 Re: когда отрабатывает CHECK ???  [new]
Ivan Durak
Member

Откуда: Minsk!!!
Сообщений: 3755
я реализовывал такую же задачу.... и не раз
Быстрее всего когда эта проверка в месте где эти периоды СОЗДАЮТСЯ перед инсертом!!
26 мар 12, 18:38    [12316581]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить