En iyi yanıtlayıcılar
Procudure içinde insert işlemleri

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.
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;
- Düzenleyen CetinBasoz 20 Mart 2012 Salı 07:59
- Yanıt Olarak İşaretleyen Sadık Bozkurt 20 Mart 2012 Salı 16:24
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;
- Düzenleyen CetinBasoz 20 Mart 2012 Salı 07:59
- Yanıt Olarak İşaretleyen Sadık Bozkurt 20 Mart 2012 Salı 16:24
-
Ö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.
-
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
-
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.- Düzenleyen CetinBasoz 20 Mart 2012 Salı 12:09
-
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 -
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 - olumculRaiseError'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