Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2004.01.26;
Скачать: [xml.tar.bz2];

Вниз

размен уникальными, ключевыми полями   Найти похожие ветки 

 
Alex-kosmonavt   (2003-12-29 10:34) [0]

Помогите!
Есть такая задача, которая сводится к следующему: пользователь выбирает 2 записи, и в результате операции должны обменяться все их поля между собой за исключением ключевых ID. Понятно что проще было бы поменять ключевые, но это так сказать противоречит логике построения базы данных. Подскажите возможные варианты??
Работаю с TQuery.


 
Vlad   (2003-12-29 10:43) [1]

Ввести еще одно, "псевдоключевое" поле. Оно будет содержать ссылку на ключевое. Его и менять.


 
Sergey13   (2003-12-29 10:54) [2]

2Alex-kosmonavt (29.12.03 10:34)
А в чем проблема то? Писать лень и хочется одной чудодейственной командой? ИМХО выход один - запомнить значения в переменные и потом присвоить полям значения переменных.


 
Ega23   (2003-12-29 10:57) [3]

Одной транзакцией. Как
> Sergey13 © (29.12.03 10:54) [2]
предлагает.


 
Alex-kosmonavt   (2003-12-29 11:12) [4]

э--ээ, вариант со ссылкой неохота, так как для пользователя окажется возможным делать для н-записей ссылки на один ID, а значит в некоторых случаях начнутся глюки.
а вот вариант с копированием в буфер интереснее, только подскажите метод как организовать доступ ко всем полям, чтобы можно было например включить обработку записи по циклу, перебирая все поля за исключением уникального? Поля в квери имеют свои номера что-то типа того Query.Fields[i].Value ??


 
Плохиш_   (2003-12-29 11:15) [5]

>Alex-kosmonavt (29.12.03 11:12) [4]

Не пора ли книжки про что-то типа того почитать?


 
Sergey13   (2003-12-29 11:25) [6]

Alex-kosmonavt (29.12.03 10:34)
Alex-kosmonavt (29.12.03 11:12)
----------------------------------
0:38 минут
Времени достаточно, для реализации предложенного алгоритма. Но ты все еще пишешь в форум. 8-)


 
Vlad   (2003-12-29 11:28) [7]


> Alex-kosmonavt (29.12.03 11:12) [4]
> э--ээ, вариант со ссылкой неохота, так как для пользователя
> окажется возможным делать для н-записей ссылки на один ID,
> а значит в некоторых случаях начнутся глюки.

Все в твоих руках. Сделай это поле уникальным и никаких глюков не будет. ИМХО, гораздо удобнее менять значение одного поля в таблице, чем десятка.


 
Sandman25   (2003-12-29 11:30) [8]

[7] Vlad © (29.12.03 11:28)

ИМХО зависит от того, сколько полей в таблице и как часто нужен обмен. Если редко, то не стоит заводить дополнительное поле и замедлять выполнение запросов.


 
Vlad   (2003-12-29 11:39) [9]


> Sandman25 © (29.12.03 11:30) [8]

Ну насчет замедления выполнения запросов, позвольте усомниться. Из за одного поля видимого замедления не произойдет. Единственный минус в том, что нужен будет доп. индекс, т.е. доп. пространство на диске.
Но зато есть один большой плюс - записи храняться в той последовательности(по номеру ID), в которой они были занесены в базу, и в случае чего всегда можно откатить изменение, т.е. привести записи в исходное состояние.


 
Sandman25   (2003-12-29 12:00) [10]

[9] Vlad © (29.12.03 11:39)

Лишняя операция (хоть и по индексу) - замедление.

Но зато есть один большой плюс - записи храняться в той последовательности(по номеру ID), в которой они были занесены в базу, и в случае чего всегда можно откатить изменение, т.е. привести записи в исходное состояние.

Не совсем понимаю, зачем это может быть нужно. Если нужен откат к исходному состоянию, то нужно откатить все изменения всех таблиц, а не только изменение одного поля одной таблицы.


 
Vlad   (2003-12-29 12:36) [11]


> Лишняя операция (хоть и по индексу) - замедление.

Кажись мы друг друга не поняли. Какая операция ? О чем речь ?


> а не только изменение одного поля одной таблицы.

В том то все и дело, что в данном случае фактическое состояние таблицы не меняется, меняется только порядок ссылок в этом новом поле на идентификатор записи, и дальнейшая связь с другими таблицами осуществляется по этому полю. А при необходимости откатить состояние в исходное это новое поле просто заполняется соответствующим ID равным ID этой записи.


 
Sandman25   (2003-12-29 12:43) [12]

Кажись мы друг друга не поняли. Какая операция ? О чем речь ?

Это псевдоключевое поле будет использоваться для связок? То есть вместо
from A, B
where A.id = B.id придется писать
from A1, A2, B
where A1.id = B.id
and A2.id = A1.psevdo_id
?
Причем для всех операций (поиск, удаление, изменение). Даже вставка будет медленнее за счет добавления дополнительного поля.

А при необходимости откатить состояние в исходное это новое поле просто заполняется соответствующим ID равным ID этой записи
Если это об отмене одной операции, то можно вызвать хранимую процедуру обмена еще раз. Почти xor :) Я думаю, откат не будет выполняться часто, не стоит под него подстраивать структуру БД.


 
Vlad   (2003-12-29 13:00) [13]

Это еще зачем ? Так ты в одной записи выбираешь и исходное и измененное значение, а зачем ?
Было:
from A, B
where A.id = B.id

Стало:
from A, B
where A.psevdo_id = B.id


 
Sandman25   (2003-12-29 13:04) [14]

[13] Vlad © (29.12.03 13:00)

Теперь понятно. Согласен. Меня смутило Оно будет содержать ссылку на ключевое из [1]


 
Fay   (2003-12-29 20:44) [15]

set nocount on
if object_id("tt_ii") is not null drop trigger tt_ii
go
if object_id("tt") is not null drop view tt
go
if object_id("t1") is not null drop table t1
go
if object_id("t2") is not null drop table t2
go
create table t1(
id int not null identity(1,1) primary key,
name varchar(32) not null
)
go
create table t2(
id int not null identity(1,1) primary key,
name varchar(32) not null
)
go
declare @i int
select @i = 0
while @i < 100 begin
select @i = @i + 1
insert into t1 select "T1 "+cast(@i as varchar(20))
insert into t2 select "T2 "+cast(@i as varchar(20))
end
go
create view tt
as
select t1_id = cast(0 as int), t2_id = cast(0 as int)
go
create trigger tt_ii
on tt
instead of insert
as
begin
declare
@t1_id int,
@t2_id int,
@t1_name varchar(32),
@t2_name varchar(32)

select
i.t1_id,
i.t2_id,
t1.name,
t2.name
from inserted i, t1, t2
where i.t1_id = t1.id and i.t2_id = t2.id
declare c cursor local for select
i.t1_id,
i.t2_id,
t1.name,
t2.name
from inserted i, t1, t2
where i.t1_id = t1.id and i.t2_id = t2.id
open c
fetch next from c into @t1_id, @t2_id, @t1_name, @t2_name
while @@fetch_status=0 begin
update t1 set name=@t2_name where id = @t1_id
update t2 set name=@t1_name where id = @t2_id
fetch next from c into @t1_id, @t2_id, @t1_name, @t2_name
end
close c
deallocate c
end
go
insert into tt values (1,1)
go
select * from t1 where id = 1
select * from t2 where id = 1



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2004.01.26;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.005 c
3-83112
Крутыш
2003-12-27 14:09
2004.01.26
Либо что-то с ADO или гридом из пакета DeveloperExpress4.


3-83101
kiko
2003-12-26 15:44
2004.01.26
Помогите разобраться с индексами


1-83182
otistarda
2004-01-14 15:38
2004.01.26
Передача результатов в bat-файл в виде параметров


3-83123
Апач
2003-12-29 15:42
2004.01.26
Работа с DBGrid


1-83163
DeScriptor
2004-01-15 03:51
2004.01.26
Функция, обратная Chr





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский