11. January 2013
dearly
T-SQL
SQL server üzerindeki bir tabloya sadece belli bir procedure ile insert yapılmasını, direkt tablo üzerinde insert yapılamamsını sağlamak istiyoruz.
Bunu sağlamak için procedure içinde insert komutundan önce bir iz bırakıyoruz(CONTEXT_INFO). Insert trigger'ı içinde de bu izi arıyoruz. Eğer CONTEXT_INFO içindeki bilgi istediğimiz procedure e ait ise işlemi yapıyoruz. Değilse hata verdirtiyoruz.
Örnek Pocedure:
---************************************
---INSERT yaparken Prosedurun ismini CONTEXT_INFO ya ekliyoruz. Triggerda Prosedur ismi kontrol edilecek!
DECLARE @string VARCHAR(128) ,
@CONTEXT_INFO VARBINARY(128)
SET @string = ISNULL(OBJECT_NAME(@@PROCID), 'none')
SET @CONTEXT_INFO = CAST('Procedure=' + @string + REPLICATE(' ', 128) AS VARBINARY(128))
SET CONTEXT_INFO @CONTEXT_INFO
---***********************************
Trigger Örneği:
CREATE TRIGGER dbo.TRIGGER_ADI
ON dbo.TABLO_ADI
INSTEAD OF INSERT
AS
BEGIN
DECLARE @string varchar(128)
,@sCONTEXT_INFO varchar(128)=''
SELECT @sCONTEXT_INFO=CAST(CONTEXT_INFO() AS VARCHAR) FROM master.dbo.SYSPROCESSES WHERE SPID=@@SPID
IF @sCONTEXT_INFO IS NULL OR LEFT(@sCONTEXT_INFO,23)<>'Procedure=PROCEDURE_ADI'
BEGIN
DECLARE @errorMsg1 VARCHAR(500);
SET @errorMsg1 = 'TABLO_ADI TABLOSUNA SEDECE PROCEDURE_ADI PROSEDÜRÜ İLE KAYIT EKLENEBİLİR!' ;
RAISERROR(@errorMsg1,16,1)
END
ELSE
BEGIN
INSERT INTO TABLO_ADI
SELECT AlanAdi1,AlanAdi2,....
FROM INSERTED
END
END
- Merhaba,
Öncelikle yazıyı özensiz şekilde hazırladığım için kusura bakmayın. Boş vakit bulduğumda (tabi bulabilirsem) düzenlemeye çalışacağım.,
LINQ ile çalışırken bir tabloya insert eden prosedürden gelen SCOPE_IDENTITY() verisini almak umduğumdan biraz daha karmaşıkmış. Aşağıda basit bir şekilde anlatmaya çalışacağım.
1-)Prosedürümüzü ID gönderecek şekilde düzenleyelim
Sadece OID ve Name alanı bulunan source adında bir tablomuz olsun. Bunun insert'i için yazacağımız prosedür aşağıdaki gibi olmalı
ALTER procedure [dbo].[TR_InsertSource]
@OID int OUTPUT,
@Name nvarchar(255)
AS
insert into source
( [Name] )
VALUES
( @Name )
set @ID= cast(SCOPE_IDENTITY() AS INT)
2-)Prosedürümüzü ve ilgili tabloyu DBML'e ekleyelim
bu kısım için detaylı açıklamayı vakit bulursam ekleyeceğim :(
3-)insert işlemi yapılacak tablo için Dbml deki değişikliklerimizi yapalım
- aşağıdaki gibi bir pencere açılacaktır
Burada Customize radiobutton unu seçiyoruz
çıkan dropdowndan stored procedure mizi seçiyoruz (benim kullandığım TR_InsertSource)
oiD olarak tanımladığımız alanın karşısında identity alan adımızın olduğundan emin olalım (OID)
sonra da OK butonuna basalım
Properties penceresi aşağıdaki gibi olacaktır:
3-)Kodumuzu güncelleyelim
- öncelikle yeni OID değerini tutacak bir değişken yaratalım:
int? sourceID = 0;
- şimdi prosedürü çalıştıracak kodu yazalım:
MDDBDataContext dc = new MDDBDataContext();
dc.TR_InsertSource(ref sourceID, txtName.Text)
prosedürün içine yazdığımız ref sourceID sayesinde yukarda integer olarak tanımladığımız sourceID alanına yeni OID değeri kaydedilecektir.
- şimdi de prosedürü çalıştıralım
dc.SubmitChanges();
kodun son hali aşağıdaki gibi olacaktır :
int? sourceID = 0;
MDDBDataContext dc = new MDDBDataContext();
dc.TR_InsertSource(ref sourceID, txtName.Text)
dc.SubmitChanges();
artık sourceID'yi istediğiniz gibi kullanabilirsiniz.
Umarım işinize yarar...