![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
каскадное копирование TSQL [D7, XP]
pleasure © (2010-02-18 13:28:00)существует три взаимосвязанных таблицы a->b->c ("c" подчинена "b", а "b" подчинена "а") меж ними связь один ко многим. каскадное удаление происходит на ура. а вот каким образом реализовать каскадное копирование ?
к примеру в таблице "а" копируем одну из строчек. следом копировать все свзяанные строки из "b" в неё же но с новым a.id, далее свзяанные строки из "с" ....
Проще говоря делается справочник прейскуранта услуг. а - прейскурант, b - услуги, с - составляющие услуг.
копирование предназначено для того, чтобы не вносить новые услуги и их составляющие с нуля.
к тому же у составляющих услуг должна быть ссылка адекватная новому Id услуги.
у кого какие соображения по этому поводу?
b z (2010-02-19 14:04:00) [1]
> Нет проверки, если в FirstTable нет записей с FID=1
Тут же будет параметр его не с потолка берут, а если запись успели удалить (долго принимали решение, на клонирование) - на откуп пользователям. ;) Можно добавить и проверку +
> А дальше автор пусть как хочет так и делает.
.
Я к курсорам/рекурсиям прибегаю когда уж совсем без них никак.
pleasure (2010-02-19 13:53:00) [2]
> 12 ©
В соседнем городе побратиме ;)) - Рузаевке
Ega23 (2010-02-19 13:51:00) [3]Ну и потом, я специально такую мудрёную структуру наваял. Тут и пример с курсором, и проверка на отсутствие записей, и рекурсивный вызов ХП, и конструкция
Insert into Select from
А дальше автор пусть как хочет так и делает.
Ega23 (2010-02-19 13:48:00) [4]
> вроде так проще и понятнее. :)
Нет проверки, если в FirstTable нет записей с FID=1
b z (2010-02-19 13:21:00) [5]
declare @i int
insert into dbo.FirstTable (fname) values('123')
select @i = scope_identity()
insert into dbo.SecondTable
select @i as fid, st.sname as sname
from dbo.SecondTable as st
join dbo.FirstTable as ft on ft.fid=st.fid
where ft.fid=1
insert into dbo.ThirdTable
select
(select st2.sid from dbo.SecondTable as st2
where st2.fid=@i and st.sname=st2.sname) as sid,
tt.tname as tname
from dbo.ThirdTable as tt
join dbo.SecondTable as st on st.sid=tt.sid
join dbo.FirstTable as ft on ft.fid=st.fid
where ft.fid=1
вроде так проще и понятнее. :)
Ega23 (2010-02-19 13:02:00) [6]Просто у тебя в скрипте как раз @@Identity использовалось, глаза резануло.
12 (2010-02-19 13:02:00) [7]короче, если во время вставки, триггер вдруг сработает какой - @@IDENTITY могет быть не той, которую ожидаешь
а не секрет если, что за контора? Имхо, в Саранске мало кому надо именно _писать_
Сам отсюда %)
Ega23 (2010-02-19 13:02:00) [8]Угу. Т.е. у тебя таблица1 с identity и таблица2 c identity. И на первой таблице триггер висит на Insert. и в этом триггере идёт вставка чего-то во вторую.
Так вот, в этом случае Scope_Identity и @@Identity с большой вероятностью не совпадут, т.к. первая вернёт именно значение, вставленное в первую таблицу, а @@Identity - значение вставленной записи во вторую.
pleasure (2010-02-19 12:58:00) [9]Функции SCOPE_IDENTITY и @@IDENTITY возвращают последние значения идентификатора, созданные в таблицах во время текущего сеанса. Однако функция SCOPE_IDENTITY возвращает значения, вставленные только в рамках текущей области, тогда как действие функции @@IDENTITY не ограничивается никакими областями.
Ega23 (2010-02-19 12:55:00) [10]
> у меня MSSQL2000
я в синтаксисе 2000 и написал всё, "примочек" из 2005 и выше не использовал (да и не нужны они тут)
pleasure (2010-02-19 12:53:00) [11]у меня MSSQL2000
Ega23 (2010-02-19 12:43:00) [12]
> алгоритм ещё стоит разобрать и понять
Обрати внимание наScope_Identity(), в отличие от@@Identity.
Это тонкий момент, по нему посмотри в BOL.
pleasure (2010-02-19 12:39:00) [13]o_O. Не может быть но работает корректно )), алгоритм ещё стоит разобрать и понять. Ega23 должен буду ;). С наступающим Вас.
Ega23 (2010-02-19 12:13:00) [14]Использование:
exec S_MyProc @actNam= 'FIRST.ADD', @ID=1
Select * from FirstTable
Select * from SecondTable
Select * from ThirdTable
Ega23 (2010-02-19 12:12:00) [15]
if exists (select * from sysobjects where id = object_id(N'[S_MyProc]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [S_MyProc]
GO
CREATE PROCEDURE S_MyProc
@ActNam varchar(32)='NONE',
@ID int = -1,
@parID int = -1,
@Name varchar(32) = ''
As
declare
@aName varchar (32),
@aID int,
@x int;
if (@ID = -1) Goto FIN;
Set NoCount ON;
Set @ActNam = Upper(LTrim(RTrim(@ActNam)));
Set @aName = NULL;
if @ActNam = 'FIRST.ADD'
begin
Select @aName = FName
from FirstTable
where FID = @ID;
if @aName is null Goto FIN; -- Нет записей c таким ID
Insert into FirstTable (FName) Values (@aName);
Select @aID = Scope_Identity();
Declare Cur cursor local static for
Select SID, SName from SecondTable
where FID = @ID;
Open Cur;
While (0=0)
begin
Fetch Next from Cur into @x, @aName;
if @@FETCH_STATUS <> 0 Break;
exec S_MyProc @ActNam = 'SECOND.ADD', @ID = @x, @parID = @aID, @Name = @aName;
end;
Close Cur;
Deallocate Cur;
Goto FIN;
end;
if @ActNam = 'SECOND.ADD'
begin
Select @aName = SName
from SecondTable
where SID = @ID;
if @aName is null Goto FIN; -- Нет записей c таким ID
Insert into SecondTable (FID, SName) Values (@parID, @aName);
Select @aID = Scope_Identity();
Insert into ThirdTable (SID, TName)
Select SID=@aID, TName
from ThirdTable
where SID = @ID;
Goto FIN;
end;
FIN:
return(0);
GO
Ega23 (2010-02-19 12:12:00) [16]
Create Table FirstTable (
FID int identity (1,1),
FName varchar(32) not null,
constraint PK_FirstTable primary key (FID)
);
Create Table SecondTable (
SID int identity (1,1),
FID int not null,
SName varchar(32) not null,
constraint PK_SecondTable primary key (SID)
);
Create Table ThirdTable (
TID int identity (1,1),
SID int not null,
TName varchar(32) not null,
constraint PK_TirdTable primary key (TID)
);
alter table SecondTable
add constraint FK_Second_Ref_First foreign key (FID)
references FirstTable (FID);
alter table ThirdTable
add constraint FK_Third_Ref_Second foreign key (SID)
references SecondTable (SID);
Set NoCount ON;
Insert into FirstTable (FName) Values ('First_1');
Insert into FirstTable (FName) Values ('First_2');
Insert into SecondTable (FID, SName) Values (1, 'Second_1_1');
Insert into SecondTable (FID, SName) Values (1, 'Second_1_2');
Insert into SecondTable (FID, SName) Values (2, 'Second_2_1');
Insert into SecondTable (FID, SName) Values (2, 'Second_2_2');
Insert into ThirdTable (SID, TName) Values (1, 'Third_1_1_1');
Insert into ThirdTable (SID, TName) Values (1, 'Third_1_1_2');
Insert into ThirdTable (SID, TName) Values (2, 'Third_1_2_1');
Insert into ThirdTable (SID, TName) Values (2, 'Third_1_2_2');
Insert into ThirdTable (SID, TName) Values (3, 'Third_1_3_1');
Insert into ThirdTable (SID, TName) Values (3, 'Third_1_3_2');
Insert into ThirdTable (SID, TName) Values (4, 'Third_1_4_1');
Insert into ThirdTable (SID, TName) Values (4, 'Third_1_4_2');
b z (2010-02-19 11:45:00) [17]Например два select into должны справиться.
Ega23 (2010-02-19 11:34:00) [18]Щас накидаю.
pleasure (2010-02-19 10:09:00) [19]каркас может не сложно накидать?
12 (2010-02-19 09:54:00) [20]
> ;((
там делов то - сам бы написал давно
и я бы написал тебе, просто в sql синиаксис долгий, на каждый вздох - оператор, просто в лом писать :)