powered by simpleCommunicator - 2.0.39     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / ограничение FK
17 сообщений из 17, страница 1 из 1
ограничение FK
    #36678702
Фотография Shakill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в таблице T1 хранится справочник с историей, таблица T2 ссылается на T1 с помощью FK T2.that_Id = T1.this_Id. надо ограничить допустимые значения FK набором, подпадающим под условие T1.this_Id = T1.root_Id или же просто всеми вариантами T1.root_Id, но root_Id в T1 не уникально. возможно это как-то сделать не триггером, а констрейном?
...
Рейтинг: 0 / 0
ограничение FK
    #36678704
Гавриленко Сергей Алексеевич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для констрейнта нужен ключ, так что никак.
...
Рейтинг: 0 / 0
ограничение FK
    #36678724
Фотография Shakill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
спасибо
придется либо выносить историю из справочников в отдельные таблицы, либо вешать на все таблицы с такими FK триггеры, которые будут обрабатывать все имеющиеся FK. первое выглядит заметно лучше
...
Рейтинг: 0 / 0
ограничение FK
    #36678749
лолл
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shakill,

Если я правильно понимаю, сделайте констрейнт:
Код: plaintext
1.
ALTER TABLE T1
ADD CONSTRAINT FK_T1_this_Id FOREIGN KEY (this_Id) REFERENCES T1 (root_Id)
...
Рейтинг: 0 / 0
ограничение FK
    #36678753
лолл
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RootID в таком случае правильнее называть ParentID... Ведь дерево описываем, да?
...
Рейтинг: 0 / 0
ограничение FK
    #36678774
Гавриленко Сергей Алексеевич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
лоллShakill,

Если я правильно понимаю, сделайте констрейнт:
Код: plaintext
1.
ALTER TABLE T1
ADD CONSTRAINT FK_T1_this_Id FOREIGN KEY (this_Id) REFERENCES T1 (root_Id)

И получит сообщение:

Код: plaintext
1.
Msg  1776 , Level  16 , State  0 , Line  10 
There are no primary or candidate keys in the referenced table ... that match the referencing column list in the foreign key ...
...
Рейтинг: 0 / 0
ограничение FK
    #36678779
Фотография Shakill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
лолл, все наоборот, в T1 уже есть FK сам на себя, т.е. в каждой записи истории root_Id ссылается на this_Id актуальной записи. у актуальной записи root_Id = this_Id, то есть дерево получается не очень ветвистое )
...
Рейтинг: 0 / 0
ограничение FK
    #36678787
лолл
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гавриленко Сергей Алексеевич,

Наверное мы друг дуга не понимаем...

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
CREATE TABLE Tree(
  ID            int IDENTITY( 1 ,  1 ) NOT NULL,
  ParentID      int NULL,

  CONSTRAINT PK_Tree PRIMARY KEY CLUSTERED (ID),
  CONSTRAINT FK_Tree_ParentID FOREIGN KEY (ParentID) REFERENCES Tree (ID)
)
...
Рейтинг: 0 / 0
ограничение FK
    #36678792
Фотография Shakill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
лолл, ага, так оно и выглядит. хотел ограничить ссылки из внешних таблиц сюда списком Id актуальных записей. не вышло
...
Рейтинг: 0 / 0
ограничение FK
    #36678825
лолл
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shakill,

в смысле, почему не вышло? во внешних таблицах ссылки на ID должны идти, а не на ParentID...
...
Рейтинг: 0 / 0
ограничение FK
    #36678846
Фотография Shakill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
лолл, в том смысле, что в справочнике Id есть у всех записей - и актуальных, и исторических. хотел со стороны базы установить ограничение, что в остальных таблицах как FK будут использоваться только Id актуальных записей, т.е. подмножество, попавшее в root_Id
...
Рейтинг: 0 / 0
ограничение FK
    #36678888
лолл
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shakill,

Есть способ ограничить это множество через check constraint:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
CREATE TABLE TreeNodes(
  ID            int IDENTITY( 1 ,  1 ) NOT NULL,
  ParentID      int NULL,

  CONSTRAINT PK_TreeNodes PRIMARY KEY CLUSTERED (ID),
  CONSTRAINT FK_TreeNodes_ParentID FOREIGN KEY (ParentID) REFERENCES TreeNodes (ID)
)

CREATE TABLE NodeData(
  ID            int IDENTITY( 1 ,  1 ) NOT NULL,
  TreeNodeID    int NOT NULL CONSTRAINT CHK_NodeData_TreeNodeID CHECK (dbo.fn_NodeIsValid(TreeNodeID) =  1 ),

  CONSTRAINT PK_NodeData PRIMARY KEY CLUSTERED (ID),
  CONSTRAINT FK_NodeData_TreeNodeID FOREIGN KEY (TreeNodeID) REFERENCES TreeNodes (ID)
)
...
Рейтинг: 0 / 0
ограничение FK
    #36678934
Фотография Shakill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
лолл, а вариант, спасибо. функцию надо будет для каждого справочника копировать, но это уже не ворох разных триггеров на все журналы

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
CREATE FUNCTION dbo.fn_NodeIsValid (@id int)
RETURNS int
AS
BEGIN
	RETURN 
		CASE WHEN EXISTS(
			SELECT * FROM TreeNodes WHERE ParendID = @Id) 
			THEN  1  ELSE  0  
		END
END
...
Рейтинг: 0 / 0
ограничение FK
    #36678938
лолл
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
только у вас EXISTS(SELECT * FROM TreeNodes WHERE ParendID = @Id) уже обеспечено ограничением CONSTRAINT FK_TreeNodes_ParentID FOREIGN KEY (ParentID) REFERENCES TreeNodes (ID)

Так что в данном контексте такая функция не нужна.
...
Рейтинг: 0 / 0
ограничение FK
    #36678946
лолл
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
видимо к концу рабдня мозги вскипели =) увидел, что вы проверяете существование ветки, не относящееся к корню. т.е. данная функция отметает все корневые записи дерева (у которых ParentID is null)... но это ли нужно на самом деле?
...
Рейтинг: 0 / 0
ограничение FK
    #36678949
Фотография Shakill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
лолл, всё-таки нужна. не все ID являются еще и ParentID => не все могут быть использованы в сторонних ссылках, об этом речь

а у корневых записей ParentID = ID, я в начале писал
...
Рейтинг: 0 / 0
ограничение FK
    #36678978
лолл
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shakillфункцию надо будет для каждого справочника копировать, но это уже не ворох разных триггеров на все журналы


Можно и одной обойтись в принципе:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
CREATE FUNCTION dbo.fn_NodeIsValid (@HandbookID int, @id int)
RETURNS int
AS
BEGIN
  RETURN 
    CASE @HandbookID
      WHEN  1  THEN CASE WHEN EXISTS(SELECT * FROM TreeNodes1 WHERE ParendID = @Id) 
			                 THEN  1  ELSE  0  
                  END
      WHEN  2  THEN CASE WHEN EXISTS(SELECT * FROM TreeNodes2 WHERE ParendID = @Id) 
			                 THEN  1  ELSE  0  
                  END
      ...
    END
END

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


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