Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

каскадное копирование TSQL [D7, XP]


Страницы:   1 2

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 синиаксис долгий, на каждый вздох - оператор, просто в лом писать :)


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо