Firebird : Trigger hangi koşullarda çalışır veya çalışmaz ?
mrmcop12.08.2005 - 01:46:20
Merhabalar..

- Firebird'i kavramak için bir proje hazırlıyorum. İlk takıldığım nokta Trigger'ı devreye girip girmemesi konusu oldu.

- Paralel bir olay daha... DEFAULT tanımlanmış değerler de aynı durumla karşı karşıya.

- İlk olarak AutoIncremental artış yapmak üzere bir TRIGGER tanımı hazırladım. Tablo1 tablosunun T1_ID isimli alan adına yönelttim.

with IBSQL do
// TRIGGER - AutoInc
try
SQL.Clear;
SQL.Add('CREATE TRIGGER AUTOINC FOR TABLO1');
SQL.Add('ACTIVE BEFORE INSERT POSITION 0');
SQL.Add('AS');
SQL.Add('begin');
SQL.Add(' if (NEW.T1_ID is null) then NEW.T1_ID=GEN_ID(GEN_AUTOINC, 1);');
SQL.Add('end');
Prepare;
ExecQuery;
finally
Close;
end;


- Normalde girdi çıktıyı IBSQL ile yaptığım zaman -Trigger'a bağladığım T1_ID alanını hariç tutarak- aşağıdaki örnek gibi INSERT INTO işlemi yaparsam, Trigger görev yapıyor ve değer ataması yapıyor. Buraya kadar tamam.

With DataModule1.IBSQL1 do // Trigger'ler çalışıyor...
begin
SQL.Clear;
SQL.Add('Insert Into TABLO1');
SQL.Add(' (KELIME, RESIM, SES, ANIME)');
SQL.Add(' values');
SQL.Add(' (:KELIME, :RESIM, :SES, :ANIME)');
ParamByName('KELIME').Value := 'a';
ParamByName('RESIM').Value := 'b';
ParamByName('SES').Value := 'c';
ParamByName('ANIME').Value := 'd';
ExecQuery;
end; //With


- Soruna gelince; TDBGrid'e bir TDataSource ile yansıtılmış IBDataset'de açık olan bu tabloda yeni bir kaydı aşağı ok ile eklediğimizde bu Trigger çalışmıyor. Yani otomatik artan rakam vermiyor. Halbu ki IBDataSet'in InsertSQL tanımı IBSQL'deki gibi tanımlandı ve ilgili alan hariç tutuldu.

- IBDataSet'in InsertSQL tanımı aşağıdaki gibidir...

With DataModule1.IBDataset1 do
begin
InsertSQL.Clear;
InsertSQL.Add(' insert into TABLO1');
//InsertSQL.Add(' (T1_ID, KELIME, RESIM, SES, ANIME)');
InsertSQL.Add(' (KELIME, RESIM, SES, ANIME)'); // T1_ID Hariç tutuldu.
InsertSQL.Add(' values');
//InsertSQL.Add(' (:T1_ID, :KELIME, :RESIM, :SES, :ANIME)');
InsertSQL.Add(' (:KELIME, :RESIM, :SES, :ANIME)');
end;


- Normal bir projede bu şekilde TDBGrid'den kontrolsüz girişe izin vermem ama sebebini merak ediyorum.

- Bilgisini paylaşacaklara şimdiden teşekkürler..
 
doganzorlu12.08.2005 - 02:20:31
Selam,

IBDataset den muhtemelen TID null gitmiyordur, 0 gidiyor olabilir. Trigger çalışıyor lakin;


if (NEW.T1_ID is null) then NEW.T1_ID=GEN_ID(GEN_AUTOINC, 1);


kontrolünde takılıyordur.[/code]
 
mrmcop12.08.2005 - 02:37:00
Tekrar merhaba....

- T1_ID için atanan değer 0 değil NULL olduğu için hata alıyorum. 0 olsa kabul edecekti.

- En az bir kayıt olsun deyip burayı elimle girersem kayıt başarılı oluyor ama bir sonraki kayıtta yine null kalıyor...

- Hatta [u:d2240ab751]Trigger olmayan[/u:d2240ab751] bir alan olarak deneme amaçlı eklediğim SECENEK diye bir alan daha var en sonda. Default değer olarak 'h' alması gerekiyor. O dahi default değerini almayıp NULL kalıyor... Halbu ki IBSQL ile bu değer de default değerine kavuşuyor.

- Dediğim gibi IBSQL ile aynı INSERT INTO satırları çalışırken, IBQuery +IBUpdate veya daha zaten aynı anlama geldiği için sonradan dönüştürdüğüm IBDataSet ile değer almıyor. SECENEK dahi Default değer almıyor.

- Ek olarak bildireyim, EMS (EMS Interbase Firebird Manager 3) ile DATA girişi için tablonun DBGrid'inde elle DATA girişi yaparken hem Trigger çalışıyor hem de default değer.

- Örnek Veritabanı : http://divxturk.divxforever.com/files/gecici/vericat.zip

Tablo1 Structure aşağıdaki şekide...

const
Tablo = 'Tablo1';
begin
{ --- Table Structure --- }
With KomutListesi do
begin
Clear;
Add( 'CREATE TABLE ' + Tablo + ' (');
Add( ' T1_ID NUMERIC NOT NULL,');
Add( ' KELIME VARCHAR (50) CHARACTER SET WIN1254 COLLATE PXW_TURK,');
Add( ' RESIM VARCHAR (50) CHARACTER SET WIN1254 COLLATE PXW_TURK,');
Add( ' SES VARCHAR (50) CHARACTER SET WIN1254 COLLATE PXW_TURK,');
Add( ' ANIME VARCHAR (50) CHARACTER SET WIN1254 COLLATE PXW_TURK,');
Add( ' SECILI CHAR (01) CHARACTER SET NONE DEFAULT ''h'' COLLATE NONE,');
Add( 'Primary Key ("T1_ID")' );
Add( ')' );
end;
end;
 
bukentay12.08.2005 - 03:07:56
hata veriyordan kastiniz T1_ID alani otomatik deger almiyor ise yolladiginiz veritabanini indirip denedim. aslinda deger aliyor ama aldigi deger grid de gozukmuyor.eger veriyi girdikden sonra commit ediyorsaniz, programi acip kapadikdan sonra T1_ID alaninin degeri gozukuyor.
ayni sorun beni bir hayli ugrastirmisti, verileri grid haricinde de girseniz dataseti kapatip acmadan otomatik artan alan degeri gozukmuyordu bir turlu.otomatik alan isini datasetin generatorfield kismindan yapinca sorun hallolmustu..
 
mrmcop12.08.2005 - 03:18:48
hata veriyordan kastiniz T1_ID alani otomatik deger almiyor ise yolladiginiz veritabanini indirip denedim. aslinda deger aliyor ama aldigi deger grid de gozukmuyor.eger veriyi girdikden sonra commit ediyorsaniz, programi acip kapadikdan sonra T1_ID alaninin degeri gozukuyor.
ayni sorun beni bir hayli ugrastirmisti, verileri grid haricinde de girseniz dataseti kapatip acmadan otomatik artan alan degeri gozukmuyordu bir turlu.otomatik alan isini datasetin generatorfield kismindan yapinca sorun hallolmustu..


- Veritabanını nerede denediniz. Delphi projesinde bir DBGrid'de denemenizi salık veririm.

- Sizin projede Dataseti kapatıp açmadan aldığı değeri görememenize rağmen, kayıt işlemi başarılı oluyordu değil mi ? Unique değer veya Null kaldı hatası almıyordunuz. Buradaki sorunda durum farklı. DBGrid - IBDataSet'e bağlıyken Trigger hiç çalışmıyor. Exclaim

- EMS, IBManager gibi programlar bildiğim kadarıyla Trigger ve/veya Generator varsa olayları veritabanı cephesinde bırakmayıp manuel olarak takibe alıyorlar...

- Generatorfield ile zaten sorun kalmıyor. Bırakın orayı biliyorsunuz Table'ın beforepost olayında dahi çözüm çocuk oyuncağı Idea ama amacım Firebird'in Delphi cephesi değil, veritabanı cephesinde çözüm üretmeyi öğrenmek. Zaten doğal olarak bugüne kadar hep Delphi cephesinde program geliştirdim.

- SECILI alanının Default değer almayışına nasıl bir anlam veriyorsunuz ? O da benzeri bir durum.
 
bukentay12.08.2005 - 04:45:04
ben FIBPlus kullandigim icin sizin soylediginiz hatayi almiyormusum.
standart ibx componentleri kullaninca dediginiz gibi T1_ID alani icin deger girmelisiniz diye hata verdi.
bunu halletmek icin T1_ID alaninin FieldKind ozelligini ftInternalCalc yapmaniz lazim. o zaman grid icinden bilgi girerken sorun cikarmiyor.fakat bu seferde alanin yeni degeri dataseti kapatip acmadan gridde gozukmuyor.
 
doganzorlu12.08.2005 - 09:15:48
Selam,

Beforepost da nasıl çözüyorsunuz olayı acaba ? Bu konuda kullandığınız metodu paylaşabilir misiniz ?
 
mrmcop12.08.2005 - 09:23:22
@bukentay
- Haklı olabilirsiniz. IBX standart bileşenleri veritabanından yeterince feedback alamıyor olabilir.

@doganzorlu yanlış anladınız herhalde. Soru şeklinizden sanki before post'ta sihirli bir komutla Trigger tetikleyeceğim gibi bir şey anladığınızı sezinledim... Laughing

- BeforePost'ta Null kontrolü yapıp null olanlara ilk değer vererek ve paralel bir SQL ile son kaydı okuyup generatordeki tutulan sayı gibi olmasa da bir fazlasını vererek tabii ki 8)
 
doganzorlu12.08.2005 - 11:21:17
Selam,

Doğru anlamışım demekki.. Son numarayı bul bir artır çözümü, çok kullanıcılı ve yüksek yoğunluklu talolarda çakışmayla sonuçlanacağı için yöntem olarak tercih edilmemelidir. Bu noktada FB içinde bir SP hazırlayıp , size bir Generator den alacağı id yi vermesini sağlamalısınız.

Yani id null ise SP yi çağır, (misal stok hareket için get_new_id('stok_hareket')) değeri id ye koy kaydet.. En buyuk numara, tek kullanıcı olduğunda %100 güvenlidir. Ama bunun dışında güvenilmezdir.

Kolay gelsin,
 
mrmcop12.08.2005 - 11:41:23
- Zaten sorun da burada hocam... otomatik değer almaması. DBGrid ile satır kayıt eklendiğinde bu olmuyor. Idea

- ID alanına göre sıralı son kaydı okuma doğru kullanıldığında bence güvenlidir. BeforePost olayında yapılıyor çünkü. Baştan rakam verip beklenmiyor... Zaten Try Except bloğu olmadan Post etmek (network veritabanı erişimi kapanması vb durumlar için) doğru olmazdı değil mi...

- Buna göre IB için söylüyorum Generator de güncellenmeli tabii.

// Neyse bu aşamada vakit kaybına gerek yok //

- Generator ile nasıl halledildiğini merak eden olursa diye yazıyorum, ama ben bu şekilde bir çözümden değil, sadece TIBSQL ile veritabanına etki yapmayı tercih edicem. Trigger'ların sağlığı için sanıyorum bu şart.

With DataModule1.IBDataset1.GeneratorField do
begin
Field := 'T1_ID';
Generator := 'GEN_AUTOINC';
IncrementBy := 1;
ApplyEvent := gamOnPost;
end;


- DBGrid'i yapmam gerektiği gibi readonly yapıp TEdit'lere aldığım veriyi TIBSQL ile INSERT INTO edicem. Bu sayede tüm Trigger ve Default'lar çalışacak.

- Hala merakım devam ediyor. Önerisi/konu hakkında bilgisi olanlar varsa lütfen yazsın...
 
mrmcop12.08.2005 - 12:09:14
Herkese duyurulur... Çözüm üretmeyi başardım...
Laughing Laughing Laughing Laughing Laughing

- ID alanına göre sıralı son kaydı okuma doğru kullanıldığında bence güvenlidir. BeforePost olayında yapılıyor çünkü. Baştan rakam verip beklenmiyor... Zaten Try Except bloğu olmadan Post etmek (network veritabanı erişimi kapanması vb durumlar için) doğru olmazdı değil mi...


- Son yazdığım mesajdaki şu cümleme bir daha bakınca zihnim aydınlanıverdi...

- DBGrid ile giriş yapılmasına müsade ettim ve beforepost olayında bu işlemi iptal ettirdim. İptal ettirmeden önce de IBSQL'e mevcut verileri aktardım. NULL kalması gereken alanları NULL bıraktım ve işte sonuç. Çalışıyor... Hem default değerler hem de Trigger'lar... 8)

procedure TForm2.IBDataSet1BeforePost(DataSet: TDataSet);
begin
With DataModule1.IBSQL1 do // Trigger'ler çalışıyor...
begin
DataModule1.IBSQL1.Transaction := DataModule1.IBTransaction1;
DataModule1.IBSQL1.Database := DataModule1.IBDatabase1;
SQL.Clear;
SQL.Add('Insert Into TABLO1');
SQL.Add(' (KELIME, RESIM, SES, ANIME)');
SQL.Add(' values');
SQL.Add(' (:KELIME, :RESIM, :SES, :ANIME)');
ParamByName('KELIME').Value := DataModule1.IBDataSet1.FieldByName('KELIME').AsString;
ParamByName('RESIM').Value := DataModule1.IBDataSet1.FieldByName('RESIM').AsString;
ParamByName('SES').Value := DataModule1.IBDataSet1.FieldByName('SES').AsString;;
ParamByName('ANIME').Value := DataModule1.IBDataSet1.FieldByName('ANIME').AsString;
DataModule1.IBDataSet1.Cancel;
ExecQuery;
end; //With
If DataModule1.IBTransaction1.InTransaction
then DataModule1.IBTransaction1.CommitRetaining;
Application.ProcessMessages;
DataModule1.IBDataSet1.Active := False;
DataModule1.IBDataSet1.Active := True;
Abort;
end;
 
doganzorlu12.08.2005 - 12:29:38
Selam,

Sanırım tam ifade edemedim. Son olarak belirtmek isterim ki, sadece beforepost içinden bir SP aracılığıyla bir GENERATOR kullarak id alıp işinizi görebilirsiniz. Son numara yerine generatorden alacaksınız numarayı hepsi bu. Böylelikle DataBound kontrolleri de olması gerektiği gibi kullanmaya başlayabilirsiniz. Bu çalışıyor dediğiniz yöntemle içinde onlarca field bulunan tablolarda nasıl çalışacaksınız ? Her seferinde dataset i refresh ederseniz oluşacak network trafiğiyle nasıl başa çıkacaksınız ? Bu şekilde bir çözüm çözüm değil. Ama yine de karar sizin tabi ki....

İllaki true/false la dataseti refresh eden bir metod kullanacaksanız, id alanından sıfır gönderip (null değil, böylece contraint lere yakalanmazsınız) trigger içinde de null değil sıfır ı kontrol ederek değer atayın.. Böylece dataseti refresh ettiğinizde hem defualt değerler hem de id databound controller içinde görünecektir. Araya yazdığınız değişikliği iptal et/SQL ile insert et bölümünden kurtulmuş olursunuz...

Kalın sağlıcakla,
 
mrmcop12.08.2005 - 13:14:48
Selam...

- Generator'den okuma fikrine katılıyorum. Otomatik artan rakamlar için ideal olabilir ama sonuçta bu rakamı okuyup yerine yenisini koymak için de Delphi'de kod yazmak gerekecek.

- İşi tamamen bedavaya getirmeye niyetim yok ama asıl konu IBSQL ile IBDataset veya IBQuery+IBUpdateSQL aynı SQL satırlarına rağmen neden farklı davranıp tetikleme görevlerini ifa edemiyorlar... Asıl sorun burada. Buna dair bir fikriniz var mı öğrenmek isterdim...

- Dediğim gibi DBGrid'den direkt veri girişine normalde zaten izin vermem. Çözüm budur demek illaki bunu kullanıcam veya hekes bunu kullansın anlamına gelmiyor. Eldeki kuş daldaki kuş olayı anlayacağınız.

- Table listelemiyoruz. DBGrid'de listelenecek kadar dar bir SQL sorgunun network trafiğindeki etkisini büyütmemek lazım. Buradaki asıl konu default değerlerin alınabilmesi ve trigger, generator ve SP'lerin çalışır halde olması.

İllaki true/false la dataseti refresh eden bir metod kullanacaksanız, id alanından sıfır gönderip (null değil, böylece contraint lere yakalanmazsınız) trigger içinde de null değil sıfır ı kontrol ederek değer atayın.. Böylece dataseti refresh ettiğinizde hem defualt değerler hem de id databound controller içinde görünecektir. Araya yazdığınız değişikliği iptal et/SQL ile insert et bölümünden kurtulmuş olursunuz...


- Bir de DBGrid'e değer yansıtabilen IBQuery veya IBDataset',in SP'lerin çalışacağının garantisi nedir ? Ben şimdi deniycem ama ümitli değilim...
 
miskin12.08.2005 - 13:49:10
soruna tam cevap degil, buna ragmen.
Ben benzeri bir sorunla karsilastigimda. IBConsole ve Programi design modusta calistirip Delphi'nin Debugger'ini Kullandim.
Trigger davranisinin nasil oldugunu bulduydum. Ama niye öyle calistigini anlamadiydim.
Degisiklikleri triggerle baska bir tabloya yaziyordum.
 
doganzorlu12.08.2005 - 13:56:40
Selam,


İşi tamamen bedavaya getirmeye niyetim yok ama asıl konu IBSQL ile IBDataset veya IBQuery+IBUpdateSQL aynı SQL satırlarına rağmen neden farklı davranıp tetikleme görevlerini ifa edemiyorlar... Asıl sorun burada. Buna dair bir fikriniz var mı öğrenmek isterdim...


IBDataSet adından da anlaşılacağı gibi verinin çift yönlü aktarımı için çalışır. İçinde field collection ve buna bağlı client-side constraint ler barındırır. UpdateSQL ise bunları barındırmaz vereceğiniz DML i çalıştırır. Yani verinin prezentasyonu için IBUpdateSQL i kullanamazsınız bu nedenle. Adım adım ne olduğuna bakalım;

IBDataSet;

1. Design time DataSet i oluşturduğunuzda, db den db constraintlerine uygun şekilde field listi oluşturur. Elle değiştirme hakkınız her zaman vardır. Post etmeye kalkışıldığında, DB den önce buradaki constraint ler çalışacaktır.

2. Active ettiniz... Filtreye uygun kayıtlar geldi.

3. Yeni kayıt eklediniz DB ye birşey gitmedi ve oradan da default değerler gelmedi.. DB etkileşimi sadece post/delete/activate durumlarında çalışır.

4. Post ettiniz. Öncelikle client-side constraintler değerlendirildi. Not null alan var ve böyle göndermeye kalktınızsa daha DB ye gidemeden engellendiniz. Diyerlim ki burayı geçtiniz.. DB ye veriler gönderildi, sonuç pozitifse kaydedildi dedi ve bitti. Farkettiniz mi ? DB den geri bilgi gelmedi... DB tarafındaki default larınız ve varsa trigger la değiştirdiğiniz alanlar buraya yansımadı ve şu anda bir ekranda gördüğünüz bilgiler bir de DB de bulunanlar olarak aynı kaydın iki versiyonu elinize geçti..

5. Active false yaptınız, resetlendi.

6. Active true yaptınız, değerler DB den tekrar geri geldi.. Trigger tarafından değiştirildiği haliyle.. Default lar da geldi..

Bunu nasıl engellersiniz ..? Multiuser kullanımlarda ortak payda olan primary key, yani buradaki ID yi beforepost a yazacağınız bir satırlık bir ifade ile DB den "generator kullanarak" alırsınız. Default değerleri, DataSet de de set edersiniz. Burada yapıyorsam bir de DB ye neden yapıyorum demeyin. Oraya birisi başka bir kaynaktan veri insert ederse DB stabilitesi için gerekli olacaktır. Üstelik ID nin boş olması durumunda bir ID verme işlemi de mutlaka bulunmalıdır.

Bu şekilde active true/false yapmadan ekranla db deki değerlerin eşlenik olmasını sağlarsınız.

Gelelim UpdateSQL e,

1. DesignTime create. Hiçbirşey yapmazz.
2. SQL i içine yaz ve Exec ettir.. Bu durumda verdiğiniz SQL çalıştırılır ve sonuç bildirilir.. Hepsi bu... Veriyi bununla prezente etmediğiniz için başkaca birşey yapmak gerekmez.

Sizin anlayacağınız eğer Dataset i kullanıyor ve client-side constraint leri geçemiyorsanız, DB ile etkileşmediğinizden trigger lar çalışmaz. Öncelikle bu iki katmanı farketmelisiniz. Eğer client-side constraint lerden geçebilir de DB ye kadar gidebilirseniz emin olun trigger mutlaka çalışacaktır.

Aradaki farkı anladığınızı umuyorum....

Kolay gelsin,
 
Master4314.08.2005 - 12:40:05
Öncelikle doganzorlu beye herkezin başını az çok ağrıtan bu konuda değerli bilgileri paylaştığı için teşekkür ederim.

Generator ve Constraint kısmı ok. Peki DB tarafında çalışan Trigger'da yapılan hesapları-değişiklikleri Gride eşgüdümlü olarak nasıl yansıtabiliriz.
(Active := False; Active := True; olmadan)
 
FAOsoft14.08.2005 - 15:06:56
NULL Hatasını engellemek için field editörden requirefield özelliğini false yapabilirsiniz. bence sorun tetiklenip tetiklenmemesinden değil database tarafından oluşan işlemleri delphide eş zamanlı olarak gösterebilmek.

bu konudada düşünüyorum düşünüyorum ampülü yakamıyorum. illaki dataseti kapatıp açmak gerekiyor.
 
coderlord14.08.2005 - 16:59:05
Delphi tarafında Trigger ile değeri koyulan AutoInc alanları IBX vs. bileşenleri ile alamazsın. GEN_ID ile alıp alana manuel koyman gerekir.

Aynı mantıkla, Default değerler, yeni kayıt insert edildiğinde alanlarda görünmez, çünkü bileşenler bu değerleri Firebird den fetch edemez. Gözükmesini istiyorsan BeforeInsert te kendin alanlara atama yaparsın.

Bu IBO'da da böyle, IBX de de bu şekilde. Sanırım Default değerlerin alınması için bir Interbase API bulunmuyor, metadata dan parse edilip alınması gerekiyor.
 
doganzorlu14.08.2005 - 19:46:54
Selam,

IBDataset1.refresh;

gibi bir komutla triggerlar içinde meydana gelen değişiklik ve defaultlardan gelen değerler yenilenebilir. Fakat en iyisi property lerden ForcedRefresh değerini true yapmak olacaktır. Sadece aktif row un refresh edildiğini sanıyorum.. (Emin değilim bir yerde okumuştum.. Sadece IBDataSet e mahsus olarak)
 
FAOsoft14.08.2005 - 19:49:23
refresh işlemez
 
doganzorlu14.08.2005 - 20:29:49
Selam,

refresh bende çalışıyor.. Sizde çalışmayan nedir ? Bu arada default değerlerin db de atanması için ekranda görünmemesi gerekiyor. Ekranda gorunen değerler null dan farklı gittiği için db tarafında default değerleri almıyorlar...

Dikkat edilecek en önemli şey refresh SQL bölümüne girip ordaki optimistik aramayı primary keye göre düzenlenmesidir. Zira ekrandaki tum alanlara göre arıyor ve siz içerde değeri değiştirdiğinizden dolayı refresh edemiyor.. Başıma gelmedi ama bunu atlarsanız kayıt başkası tarafından değiştirilmiş gibi bir hatayla da karşılaşabilirsiniz.

Test için bir trigger da atama yaparak denedim..
 
FAOsoft14.08.2005 - 21:20:03
Embarassed Embarassed Embarassed Embarassed Embarassed Shocked
şoke oldum ben firebirde ilk başladığımda böyle yaptığımda sonuç alamamıştım. hem çok sevidim hem de cehaletime ağladım :(
beni uykudan uyandırdığın için teşekkürler.
Hala Şoktayım Shocked
 
coderlord14.08.2005 - 21:42:59
Sayın @doganzorlu benim bahsetmek istediğim dataset i Insert ettiğinizde DBGrid de oluşan boş row, kendiliğinden default değerleri ve generator değerini alamayacaktır. Post yaptıktan sonra bahsettiğiniz şekilde trigger dan atanan değerleri görmek mümkündür. Ancak post etmeden beforeinsert te bu değerleri kendimiz atamamız gerekir. BAhsettiğiniz yöntem ile Insert ten sonra refresh yaparsak dataset otomatik post edecek, değer giriş bölümünü kaçıracağız.
 
mrmcop14.08.2005 - 22:14:18
Ancak post etmeden beforeinsert te bu değerleri kendimiz atamamız gerekir. BAhsettiğiniz yöntem ile Insert ten sonra refresh yaparsak dataset otomatik post edecek, değer giriş bölümünü kaçıracağız.


- Bu duruma paralel başka bir ekleme daha yapayım.. Idea

- İlk verdiğim kod örneklerinde göreceğiniz gibi, Not Null kontrollü ve Trigger tarafından :
SQL.Add('ACTIVE BEFORE INSERT POSITION 0');
olayında görüldüğü gibi Before Insert ile AutoIncremental artışa ayarlanmış bir alan olan T1_ID alanına atanan değeri TDBGrid'de [u:7d1949f64f]OnLine[/u:7d1949f64f] göremeyişime rağmen, şöyle bir deneme yaptım.

- Verdiğini değerlendirdiğim değere karşın INSERT aşamasında bu alana kendim rastgele bir değer girdim. POST sonrası bir sürpriz ile daha karşılaştım. Verdiğim rastegele değer değil Trigger'in verdiği değerlendirmeye alınmış...!!!

- Şöyle bir durum daha söz konusu olduğu görüyorum, yanılıyorsam düzeltiniz; Trigger ile Before Insert olayında şartlar ile kontrolü sağlamak üzere verdiğimiz değerleri, program içerisinden normal INSERT sırasında zaten Trigger çoktan belirlemiştir ama biz yenisini yazalım desek bile, TDBGrid ile yeniden değerleme yapamıyoruz... Böyle bir mecburiyet varsa taa başa gidip trigger üzerinde yeni duruma göre güncelleme yapmak gerekiyor veya TDBGrid'i devre dışı bırakıp TIBSQL ile direkt kayıt yapmak gerekiyor...

- Mesela "Pazar günlerine rastlayan tarihlerde %50 indirim yapar" diye ayarlanmış bir trigger için, program içerisinden "Resmi Tatile rastlayan şu tarihte bunu uygulama" demek için DBGrid'den girişe müsade etmemek gerekiyor... 8)
 
doganzorlu14.08.2005 - 22:59:00
Selam,


Sayın @doganzorlu benim bahsetmek istediğim dataset i Insert ettiğinizde DBGrid de oluşan boş row, kendiliğinden default değerleri ve generator değerini alamayacaktır.


thread in biraz üzerlerindeki bir yazımdan;


Default değerleri, DataSet de de set edersiniz. Burada yapıyorsam bir de DB ye neden yapıyorum demeyin. Oraya birisi başka bir kaynaktan veri insert ederse DB stabilitesi için gerekli olacaktır.


Bunu zaten belirtmiştim...
 
NOT : Bu sayfa google'un siteyi indekslemesi içindir. www.delphiturkiye.com/forum/ adresini kullanınız!
1998-2006 www.delphiturkiye.com