none
Procudure içinde insert işlemleri RRS feed

  • Soru

  • Öncelikle Merhaba,

    Ben şöyle bir şey yapmak istiyorum. Procedure içinde iki tane tabloya insert işlemi yapmak istiyorum fakat c# ta transaction hata veriyor.

    yazdığım sql kodu şu;

    Begin try
    	Begin transaction
    	insert into Kuruluslar (KurTipId,KurAdi) values (@KurTipId,@KurAdi)
    		insert into STK
    		(StkTipId,SehirId,WebAdresi,Aciklama,AktifMi,Ekleyen_Id)
    		values(@StkTipId,@SehirId,@WebAdresi,@Aciklama,@AktifMi,@EkleyenId)
    		
    		commit transaction 
    		end try	
    		Begin catch
    		raiserror ('transaction hatalı',16,1)
    		
    		rollback transaction
    		end catch
    raiseerror dan transaction hatasını alıyorum. 

    18 Mart 2012 Pazar 13:49

Yanıtlar

  • raiserror ('transaction hatalı',16,1)

    yerine BOL'daki gibi:

    BEGIN CATCH
        DECLARE @ErrorMessage NVARCHAR(4000);
        DECLARE @ErrorSeverity INT;
        DECLARE @ErrorState INT;
    
        SELECT 
            @ErrorMessage = ERROR_MESSAGE(),
            @ErrorSeverity = ERROR_SEVERITY(),
            @ErrorState = ERROR_STATE();
    
        -- Use RAISERROR inside the CATCH block to return error
        -- information about the original error that caused
        -- execution to jump to the CATCH block.
        RAISERROR (@ErrorMessage, -- Message text.
                   @ErrorSeverity, -- Severity.
                   @ErrorState -- State.
                   );
    END CATCH;

    yapip, gercek hatayi gorsen. Bu da yine BOL'dan, transaction durumuna gore hareket eden catch blogu:

    BEGIN CATCH
        SELECT
            ERROR_NUMBER() as ErrorNumber,
            ERROR_MESSAGE() as ErrorMessage;
    
        -- Test XACT_STATE for 1 or -1.
        -- XACT_STATE = 0 means there is no transaction and
        -- a commit or rollback operation would generate an error.
    
        -- Test whether the transaction is uncommittable.
        IF (XACT_STATE()) = -1
        BEGIN
            PRINT
                N'The transaction is in an uncommittable state. ' +
                'Rolling back transaction.'
            ROLLBACK TRANSACTION;
        END;
    
        -- Test whether the transaction is active and valid.
        IF (XACT_STATE()) = 1
        BEGIN
            PRINT
                N'The transaction is committable. ' +
                'Committing transaction.'
            COMMIT TRANSACTION;   
        END;
    END CATCH;
    

    20 Mart 2012 Salı 07:56

Tüm Yanıtlar

  • raiserror ('transaction hatalı',16,1)

    yerine BOL'daki gibi:

    BEGIN CATCH
        DECLARE @ErrorMessage NVARCHAR(4000);
        DECLARE @ErrorSeverity INT;
        DECLARE @ErrorState INT;
    
        SELECT 
            @ErrorMessage = ERROR_MESSAGE(),
            @ErrorSeverity = ERROR_SEVERITY(),
            @ErrorState = ERROR_STATE();
    
        -- Use RAISERROR inside the CATCH block to return error
        -- information about the original error that caused
        -- execution to jump to the CATCH block.
        RAISERROR (@ErrorMessage, -- Message text.
                   @ErrorSeverity, -- Severity.
                   @ErrorState -- State.
                   );
    END CATCH;

    yapip, gercek hatayi gorsen. Bu da yine BOL'dan, transaction durumuna gore hareket eden catch blogu:

    BEGIN CATCH
        SELECT
            ERROR_NUMBER() as ErrorNumber,
            ERROR_MESSAGE() as ErrorMessage;
    
        -- Test XACT_STATE for 1 or -1.
        -- XACT_STATE = 0 means there is no transaction and
        -- a commit or rollback operation would generate an error.
    
        -- Test whether the transaction is uncommittable.
        IF (XACT_STATE()) = -1
        BEGIN
            PRINT
                N'The transaction is in an uncommittable state. ' +
                'Rolling back transaction.'
            ROLLBACK TRANSACTION;
        END;
    
        -- Test whether the transaction is active and valid.
        IF (XACT_STATE()) = 1
        BEGIN
            PRINT
                N'The transaction is committable. ' +
                'Committing transaction.'
            COMMIT TRANSACTION;   
        END;
    END CATCH;
    

    20 Mart 2012 Salı 07:56
  • Öncelikle ilgilendiğiniz için teşekkürler.

    Uzun uzun düşündükten sonra ben hatamı siz bunları paylaşmadan buldum. Hatam şu insert etmeye çalıştığım iki tablo birbiriyle ilişkili ve ikisinde de KurAdi var. Fakat tekrarlı veriyi engellemek için ikinci tabloda KurAdi nin yerine bunun eklendiği satırın Idsini eklemem lazım. Birinci insert  sorgusu çalışmadan bu Id yi almam imkansız oluyor. ilk insert gerçekleştikten sonra Id yi alabilir miyim. 

    Biraz karışık oldu ama inşaallah anlamışsınızdır.

    20 Mart 2012 Salı 10:45
  • Alabilirsin.

    SQL serverda kayit, guncelleme ve silme islemleri sirasinda olusturulan inserted ve deleted ozel tablolari var. Saglam olani onlardan almak. Bunun disinda identity fonksiyonlari var ama saglami inserted tablosundan almak bence:

    DECLARE @id TABLE (id INT);
    DECLARE @thisId INT;
    insert into Kuruluslar (KurTipId,KurAdi) 
      OUTPUT INSERTED.KurId INTO @id 
      values (@KurTipId,@KurAdi);
    SELECT @thisId = id FROM @id;
     
    insert into STK
    		(KurId, StkTipId,SehirId,WebAdresi,Aciklama,AktifMi,Ekleyen_Id)
    		VALUES (@thisId, @StkTipId,@SehirId,@WebAdresi,@Aciklama,@AktifMi,@EkleyenId);

    • Yanıt Olarak Öneren CetinBasoz 27 Temmuz 2013 Cumartesi 12:58
    20 Mart 2012 Salı 11:39
  • Bu arada eger ID olarak GUID kullanirsan (SQL server icinde NewID(), NewSequentialId() uretiyor, disarida C# Guid.NewGuid ve onun COMB GUID versiyonu, CoCreateGuid vs ile uretiliyor) o zaman buna ihtiyacin yok. Daha insert etmeden ID'yi bilirsin, sonra da ister insert edersin ister etmezsin.

    (GUID: GloballyUniqueIDentifier - kuresel olarak essiz tanimlayici. Herhangi biri tarafindan uretilenin dunyada esi olmayacagi pratikte garanti ediliyor, teorikte sonlu eleman oldugu icin cakisma olma ihtimalu sifir degil ama ustuste 3 kez piyango daha kolay cikar herhalde.)


    Not: ID olarak int ya da GUID kullanimi yazilimcilari kamplara boluyor. Int genelde iyi ama GUID bircok problemi cozuyor ve sanildigi kadar yavas degil.
    20 Mart 2012 Salı 12:08
  • Teşekkür ederim yardımlarınız için sayenizde çözebildim. Ben ümidimi kesmiştim :) Hatta bilmediğim bazı şeyleride sayenizde öğrendim.

    Ben size bir soru daha sormak istiyorum. Bulduğum kaynak sitede de sordum ama bi cevap dönülmedi Sorum şu; 
    raiserror ('transaction hatalı',16,1) deki 16,1 ne anlama geliyor.


    Tekrar teşekkürler
    20 Mart 2012 Salı 21:12
  • 16 - severity level yani ciddiyet seviyesi. Bu seviyeler degisik yerlerde anlatiliyor. Mesela (http://msdn.microsoft.com/en-us/library/aa937483(v=sql.80).aspx). Ozetle:

    0-10 bilgi niteligindeki hatalar (ikazlar)
    11-16 Kullanici tarafindan olusturulan ve yine kullanici tarafindan duzeltilebilecek hatalar (kabul edilen sinirlarin disinda veri girilmesi gibi)
    17 Kaynak yetersizligi
    18 Olumcul olmayan ic hata
    19 Kaynak limitlerinin asilmasi
    20-25 Sistem problemleri - olumcul

    RaiseError'de 19-25 arasi sadece sistem adminleri tarafindan olusturabiliyor. Yani seni daha cok ilgilendiren, olumcul olmayan ve bir sekilde duzeltilebilen 0-18 arasi (0 sysmessages'a kaydedilmiyor, tam bilgi amacli).

    1 - state yani durum. Ismi biraz garip amacina gore. Bu 0 ile 255 arasinda bir sayi (bazi kaynaklara gore 1 ile 127, SQL server BOL'da 0-255 ama 1-127 diyen kaynak da yabana atilacak bir kaynak degil, bir bildigi vardir. Belki de signed/unsigned integer nedeniyle, bilemiyorum). Bu sayiyi sen veriyorsun. Faydasi, ayni hata mesajindan bircok yerde veriyorsan, degisik yerlerde bu 'durum' degerini farkli vererek hata ayiklarken bu hatanin programin hangi bolumunden geldigini gorebiliyorsun (Microsoft'un hata mesajlarinin ne kadar aciklayici(!) oldugu hepimizin malumu:) Sanirim oncelikle kendileri icin dusunmusler bunu).


    • Düzenleyen CetinBasoz 21 Mart 2012 Çarşamba 11:11
    21 Mart 2012 Çarşamba 11:11