Добавление данных в связанные таблицы
От: Stanislav V. Zudin Россия  
Дата: 21.03.02 12:58
Оценка:
Приветствую.
Как правильно сделать subj на MS SQL?
Допустим, есть пара таблиц, связанных отношением "многие к одному":

CREATE TABLE [dbo].[Employees] (
    [EmployeeID] [int] IDENTITY (1, 1) NOT NULL ,
    [LastName] [nvarchar] (20) NOT NULL ,bla-bla-bla )

CREATE TABLE [dbo].[EmployeeTerritories] (
    [EmployeeID] [int] NOT NULL ,
    [TerritoryID] [nvarchar] (20) NOT NULL 
)


Чтобы добавить запись в EmployeeTerritories нужно знать EmployeeID свежедобавленной записи в Employees
А откуда его взять, если он создается автоматически?

В Interbase есть генераторы. И перед записью в главную таблицу я могу получить новый идентификатор из генератора, а потом его использовать и для главной таблицы, и для подчиненной.

____________________________
С уважением,
Stanislav V. Zudin
_____________________
С уважением,
Stanislav V. Zudin
Re: Добавление данных в связанные таблицы
От: vav Россия  
Дата: 21.03.02 13:04
Оценка: 1 (1)
Здравствуйте Stanislav V. Zudin, Вы писали:

SVZ>Как правильно сделать subj на MS SQL?

SVZ>Допустим, есть пара таблиц, связанных отношением "многие к одному":

SVZ>
SVZ>CREATE TABLE [dbo].[Employees] (
SVZ>    [EmployeeID] [int] IDENTITY (1, 1) NOT NULL ,
SVZ>    [LastName] [nvarchar] (20) NOT NULL ,bla-bla-bla )
SVZ>


SVZ>Чтобы добавить запись в EmployeeTerritories нужно знать EmployeeID свежедобавленной записи в Employees

SVZ>А откуда его взять, если он создается автоматически?

В MSSQL есть глобальная переменная @@Identity
т.е. после вставки в Employees @@Identity будет равна IDENTITY последней вставленной записи. Но надо быть осторожным, т.к. если в тригере вставить запись куда-то еще (обычное журналирование), то переменная вернет уже другое значение.
Re[2]: Добавление данных в связанные таблицы
От: Stanislav V. Zudin Россия  
Дата: 21.03.02 13:17
Оценка:
Здравствуйте vav, Вы писали:

vav>Здравствуйте Stanislav V. Zudin, Вы писали:


SVZ>>Как правильно сделать subj на MS SQL?


SVZ>>Чтобы добавить запись в EmployeeTerritories нужно знать EmployeeID свежедобавленной записи в Employees

SVZ>>А откуда его взять, если он создается автоматически?

vav>В MSSQL есть глобальная переменная @@Identity

vav>т.е. после вставки в Employees @@Identity будет равна IDENTITY последней вставленной записи.

А если другой пользователь в это время что-нибудь добавит, @@Identity изменится?
___________________________
С уважением,
Stanislav V. Zudin
_____________________
С уважением,
Stanislav V. Zudin
Re[3]: Добавление данных в связанные таблицы
От: Merle Австрия http://rsdn.ru
Дата: 21.03.02 13:57
Оценка: 1 (1)
Здравствуйте Stanislav V. Zudin, Вы писали:



SVZ>А если другой пользователь в это время что-нибудь добавит, @@Identity изменится?


Нет, не изменится..
@@IDENTITY работает в рамках сессии.
Мы уже победили, просто это еще не так заметно...
Re[4]: Добавление данных в связанные таблицы
От: Stanislav V. Zudin Россия  
Дата: 21.03.02 14:23
Оценка:
Здравствуйте Merle, Вы писали:

SVZ>>А если другой пользователь в это время что-нибудь добавит, @@Identity изменится?


M>Нет, не изменится..

M>@@IDENTITY работает в рамках сессии.
Ясно. Спасибо.

Вот как бы еще и с триггерами уладить.
Может глобальную переменную на время сессии создать для каждой таблицы (если возможно)?
Или лучше свой вариант генератора на основе таблицы написать?
__________________
С уважением,
Stanislav V. Zudin
_____________________
С уважением,
Stanislav V. Zudin
Re[5]: Добавление данных в связанные таблицы
От: vav Россия  
Дата: 22.03.02 03:41
Оценка: 2 (1)
SVZ>Вот как бы еще и с триггерами уладить.
SVZ>Может глобальную переменную на время сессии создать для каждой таблицы (если возможно)?

можно

SVZ>Или лучше свой вариант генератора на основе таблицы написать?

не стоит


а обычно примерно так:
Поле F1 — identity
INSERT INTO T1 (F2,F3) VALUES (V2,V3)
DECLARE @a int
SELECT @a = F1 FROM T1 WHERE F2 = V2 and F3=V3


А еще лучше (ИМХО) все делать через stored procedures.

Пускай она осуществляет вставку и журналирование, а тиргеры просто проверяют корректность вносимых данных.

Тут еще есть интересный момент: процедуры выполняются от имени создателя

Воспользоваться этим можно так:
В тригере откатывать изменения, если вносящий их юзер не DBO, т.е. запрещается ЛЮБАЯ ПРЯМАЯ вставка записей.
Re[6]: Добавление данных в связанные таблицы
От: Stanislav V. Zudin Россия  
Дата: 22.03.02 07:00
Оценка:
Здравствуйте vav, Вы писали:

vav>а обычно примерно так:

vav>Поле F1 — identity
vav>
vav>INSERT INTO T1 (F2,F3) VALUES (V2,V3)
vav>DECLARE @a int
vav>SELECT @a = F1 FROM T1 WHERE F2 = V2 and F3=V3
vav>


Делал подобное на Accesse, но там уникальность записи можно было определить по дате, которая хранилась в одном из полей (да и условие было — база однопользовательская). В общем случае такой метод не сработает. Значения в полях F2 и F3 могут быть не уникальны.
____________________________
С уважением,
Stanislav V. Zudin
_____________________
С уважением,
Stanislav V. Zudin
Re[5]: Добавление данных в связанные таблицы
От: Merle Австрия http://rsdn.ru
Дата: 22.03.02 07:52
Оценка:
Здравствуйте Stanislav V. Zudin, Вы писали:


SVZ>Вот как бы еще и с триггерами уладить.

А ты уверен, что они нужны? Лучше все операции по возможности через процедуры делать, по ряду причин.

SVZ>Может глобальную переменную на время сессии создать для каждой таблицы (если возможно)?

SVZ>Или лучше свой вариант генератора на основе таблицы написать?

А ты уверен, что тебе надо в качестве ключа использовать именно int?

Можешь делать например так:
DECLARE @ID uniqueidentifier
SET @ID = NewID()


И пользуй потом этот @ID во всех связанных таблицах как суррогатный ключ.
Этот NewID, по заверениям MS уникален в пределах планеты
Выборка будет немного медленнее, но именно что немного... Зато ты избавляешься от гиганского! геморроя, буде тебе понадобится делать репликацию, сливать несколько баз в одну или наоборот и пр. Вообщем гибкости здорово добавится.
Мы уже победили, просто это еще не так заметно...
Re[7]: Добавление данных в связанные таблицы
От: vav Россия  
Дата: 22.03.02 07:56
Оценка:
Здравствуйте Stanislav V. Zudin, Вы писали:

SVZ>В общем случае такой метод не сработает. Значения в полях F2 и F3 могут быть не уникальны.


Действительно, такое решение подходит не для всех случаев. Очень часто сурогатные ключи используются одновременно с естественными, в этом случае все будет Ок.

Наличие одинаковых записей, различающихся только ключом, часто (но не всегда) является результатом ошибки при проектировании БД.
Re[5]: Добавление данных в связанные таблицы
От: Дмитрий Михайлов Россия  
Дата: 22.03.02 08:19
Оценка: 4 (1)
M>>@@IDENTITY работает в рамках сессии.
SVZ>Ясно. Спасибо.

SVZ>Вот как бы еще и с триггерами уладить.

SVZ>Может глобальную переменную на время сессии создать для каждой таблицы (если возможно)?
SVZ>Или лучше свой вариант генератора на основе таблицы написать?

Для этого в MSSQL2k есть функция SCOPE_IDENTITY()
MSDN: Returns the last IDENTITY value inserted into an IDENTITY column in the same scope. A scope is a module -- a stored procedure, trigger, function, or batch.

Делать надо примерно так (выдержка хранимой процедуры):

DECLARE @Err INT, @NewID INT
INSERT INTO Employes VALUES ('Vasya')
SELECT @Err=@@ERROR, @NewID=SCOPE_IDENTITY()
IF @@Err <> 0 RETURN @@Err

INSERT INTO [EmployeeTerritories]
SELECT @NewID, [TerritoryID]
FROM [Teritories]
Re[6]: Добавление данных в связанные таблицы
От: vav Россия  
Дата: 22.03.02 08:30
Оценка:
Здравствуйте Дмитрий Михайлов, Вы писали:

ДМ>Для этого в MSSQL2k есть функция SCOPE_IDENTITY()

Ну 2000к!!! Там и тригеры нумеруются и вьюшки с параметрами есть...
Вот только 27 баз на семерке не дают перейти
Re[7]: Добавление данных в связанные таблицы
От: Дмитрий Михайлов Россия  
Дата: 22.03.02 08:45
Оценка:
vav>Вот только 27 баз на семерке не дают перейти

Какие конкретно причины не дают перейти с 7 на 2k?
У меня особых (вернее никаких) проблем не возникло (правда не 27 баз было).
Re[8]: Добавление данных в связанные таблицы
От: vav Россия  
Дата: 22.03.02 09:04
Оценка:
Здравствуйте Дмитрий Михайлов, Вы писали:

ДМ>Какие конкретно причины не дают перейти с 7 на 2k?

А деньги? Некоторые сервера покупают..
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.