ورود

View Full Version : سوال: کلید اصلی



mehdi1357
دوشنبه 09 شهریور 1388, 14:08 عصر
با سلام
من داری یک جدول در SQL می باشم داری یک کلید اصلی می باشد حال سه فیلد دیگر نیز دارم که باید ترکیب این سه فلید یونیک باشد در SQL چگونه بدون تعریف کردن آنها به عنوان کلید اصلی می توانم کاری کنم که ترکیب این سه فیلد تکراری نشود مرسی

محمد سلیم آبادی
دوشنبه 09 شهریور 1388, 14:43 عصر
می توانید از UNIQUE بهره ببرید
http://www.simple-talk.com/sql/t-sql-programming/unique-experiences!/

یک روش دیگر هم استفاده از trigger و exists می باشد.

علیرضا مداح
دوشنبه 09 شهریور 1388, 14:54 عصر
سلام دوست عزیز،
شما باید یک Composite Unique Constraint ایجاد نمایید:

ALTER TABLE dbo.MyTable ADD CONSTRAINT [IX_MyTable] UNIQUE NONCLUSTERED
(
[Column1] ASC,
[Column2] ASC,
[Column3] ASC
)

،/

محمد سلیم آبادی
دوشنبه 09 شهریور 1388, 17:09 عصر
شما باید یک ... ایجاد کنید

پس از مشاهده ی این جمله به این فکر افتادم که چه بایدی وجود دارد؟ آیا اصلا بایدی وجود دارد یا خیر. این شد که یک تحقیق کوچکی راجب به راه حل خودم و راه حل آقای مداح انجام دادم.

یکی از تفاوت های اصلی راه حل من با راه حل پیشنهادی آقای مداح در این است که اگر بخواهیم با کمک عملگر union چند سطر را ترکیب کرده سپس در جدول درج کنیم، در صورتیکه یک سطر تکراری داشته باشیم unique constraint اجازه ی درج هیچ سطری را نخواهد داد (در واقع عملیات fail خواهد شد) و رویداد instead of insert trgger در هر حالت تنها سطر اول را سعی می کند درج کند (شاید رویداد درج تنها در سطر اول انجام می گیرد....).

ولی اگر بخواهیم دستورات درج را به شکل زیر انجام دهیم هیچ مشکلی به وجود نخواهد آمد

insert into tbl values (....)
برای پی بردن به این مساله می توانید این دو کد را با یکدیگر مقایسه کنید.




create table tbl
(
id int primary key,
col1 char,
col2 char,
col3 char
)
go

create trigger trg
on tbl
instead of insert
as
begin
declare @col1 char,
@col2 char,
@col3 char,
@id int

select @col1=col1,
@col2=col2,
@col3=col3,
@id=id
from inserted

if exists( select *
from tbl
where col1=@col1
and col2=@col2
and col3=@col3
)
raiserror('Warning: You have a combination unique on your tabel!',1,1)

else

insert into tbl
select @id, @col1, @col2, @col3

end
go


insert into tbl
select 1, 'a', 'a', 'a' union all
select 2, 'a', 'a', 'b' union all
select 3, 'a', 'a', 'c' union all
select 4, 'a', 'a', 'a'

/*
insert into tbl values (1, 'a', 'a', 'a');
insert into tbl values (2, 'a', 'a', 'b');
insert into tbl values (3, 'a', 'a', 'c');
insert into tbl values (4, 'a', 'a', 'd');

insert into tbl values (5, 'a', 'a', 'a');
*/





create table tb2
(
id int primary key,
col1 char,
col2 char,
col3 char,
unique(col1, col2, col3)
)
go


insert into tb2
select 1, 'a', 'a', 'a' union all
select 2, 'a', 'a', 'b' union all
select 3, 'a', 'a', 'c' union all
select 4, 'a', 'a', 'a'

/*
insert into tb2 values (1, 'a', 'a', 'a');
insert into tb2 values (2, 'a', 'a', 'b');
insert into tb2 values (3, 'a', 'a', 'c');
insert into tb2 values (4, 'a', 'a', 'd');

insert into tb2 values (5, 'a', 'a', 'a');
*/

arman_Nasrollahi
دوشنبه 09 شهریور 1388, 17:52 عصر
با سلام
فکر کنم جواب این موضوع رو میشه به زبان خیلی ساده تر هم بیان کرد.
فقط کافیه یک index از نوع unique بسازید و اون سه تا فیلد مورد نظر رو توش اضافه کنید!!!

علیرضا مداح
سه شنبه 10 شهریور 1388, 15:32 عصر
مسلما" ممکن است برای یک سوال، راه حل های گوناگونی وجود داشته باشد که شخص سوال کننده باید بر اساس نیازمندی های پروژه خود، بهترین راه را انتخاب نماید،/

رضا عربلو
سه شنبه 10 شهریور 1388, 21:26 عصر
Composite Unique Constraint روش بهتر ویه.
در روش اول شما عین تریگر برای اینزرت برای آپدیت نیز بایستی تریگری مشابه بنویسید. این روش پیچیدگی دیتابیستان را بیشتر می کند.

محمد سلیم آبادی
سه شنبه 10 شهریور 1388, 21:51 عصر
Composite Unique Constraint روش بهتر ویه.
در روش اول شما عین تریگر برای اینزرت برای آپدیت نیز بایستی تریگری مشابه بنویسید. این روش پیچیدگی دیتابیستان را بیشتر می کند.

دقیقا همین طور است، و غیر از این مساله، trigger یک مشکلی که دارد این است که هنگامی که بخواهیم با یک insert چند سطر را درج کنیم رویداد instead of insert trigger روی هر سطر اتفاق نمی افتد!

محمد سلیم آبادی
جمعه 13 شهریور 1388, 23:55 عصر
trigger قبلی که ایجاد کرده بودم را با کمک cursor توسعه دادم.
این تریگر هنگام update نیز عمل کرده و هنگامی که چند سطر را یکجا بخواهیم درج کنیم نیز جوابگو خواهد بود و مشکل fail نیز نخواد داشت!




/*
create table tbl
(
id int primary key,
col1 char,
col2 char,
col3 char
)*/
go

alter trigger trg
on tbl
instead of insert, update
as
begin
declare @col1 char,
@col2 char,
@col3 char,
@id int
Declare cur cursor
For Select id, col1, col2, col3 from Inserted
open cur
Fetch next from cur into @id, @col1, @col2, @col3
while (@@fetch_status)=0
begin
if exists( select *
from tbl
where col1=@col1
and col2=@col2
and col3=@col3
)
raiserror('Warning: You have a combination unique on your tabel!',1,1)
else
insert into tbl
select @id, @col1, @col2, @col3
fetch next from cur into @id, @col1, @col2, @col3
end
close cur
deallocate cur
end
go

--Insert a group of rows NOT fail!!
insert into tbl
select 1,'a','a','a' union all
select 2,'a','a','a' union all
select 3,'b','b','b' union all
select 4,'a','b','c'

--Update and Insert using ONE trigger
update tbl
set col2='a', col3='a'
where id=4