Tabloya sadece belirlediğimiz procedure üzerinden insert yapılmasını sağlamak

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
 

 

LINQ ile stored procedure den gelen değeri (SCOPE_IDENTITY) almak

  • 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ğıda gördüğünüz gibi DBML dosyası üzerinde insert yapılacak tabloyu tıklıyoruz 
  • Properties menüsünden insert alnına tıklıyoruz (use Runtime üzerine)

  • 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...