uniquery post sonrası id null değer

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
apex06
Üye
Mesajlar: 58
Kayıt: 19 Nis 2012 12:21

uniquery post sonrası id null değer

Mesaj gönderen apex06 »

Arkadaşlar merhaba,

Delphi 10 Seattle
Unidac 7.0.2
SQL Server 2012

Çok basit bir işlem yapıyorum :)

Kod: Tümünü seç

procedure TForm1.Button2Click(Sender: TObject);
begin
  UniQuery1.Active := True;
  UniQuery1.Append;
  UniQuery1Adi.AsString := 'deneme';
  UniQuery1.Post;
  ShowMessage(IntToStr(UniQuery1RecId.AsInteger));
end;
Bu işlemden sonra normal olarak bana aldığı ID numarasını mesaj olarak göstermesi lazım. Ama göstermiyor. Bu sebepten dolayı kaydı da silemiyorum ID numarasını göremediği için. (silmek istediğimde aldığım hata : update failed. found 0 records)

Veritabanından bakıyorum sorun yok kayıt eklenmiş. ID numarası var.

forma bir adet grid koydum ne yapacak diye KurumAdi'nda deneme yazıyor fakat ID alanı boş. O yüzden de bana boş değer dönüyor.

Aynı işlemi ADOQuery ile yapıyorum hiç bir sorun vermeden çalışıyor.


Uniquery'de yaptığım işlemler;

Kod: Tümünü seç

UniQuery1.Options.StrictUpdate := False;

Kod: Tümünü seç

UniQuery1.DMLRefresh:=True;
araştırma sonucunda yukarıdaki ayarlar ile sorunun çözülebileceği yazıyor ama olmadı.

Uniquery'nin after post olayına query.refresh ve query.last dediğim zaman ID numrasını gösteriyor ama bana da bu yöntem hiç mantıklı gelmedi. Kullanıcı aşamasında illaki bir karışıklık çıkabilir :)

daha önce böyle bir sorun yaşayan oldu mu?

Teşekkürler, iyi çalışmalar
me_turan@mynet.com
Üye
Mesajlar: 29
Kayıt: 09 Eyl 2017 02:53

Re: uniquery post sonrası id null değer

Mesaj gönderen me_turan@mynet.com »

bende de aynı sorun olmuştu. yeni oluşturduğum kaydın id sini öğrenmek sorun oluyor. query.refresh kesin cözüm. aslında kullanımda bence bir sakınca yok. query.last tarzı bir kod belki hatalı bir sonuç doğurabilir ama refresh ile hiç sorun yaşamadım.Kullandığın program değilde accesin sorunu bu. asp ile de aynı sorunu yaşamıştım.
ertank
Kıdemli Üye
Mesajlar: 1650
Kayıt: 12 Eyl 2015 12:45

Re: uniquery post sonrası id null değer

Mesaj gönderen ertank »

Merhaba,

Öncelikle, IDENTITY türündeki alanların değerini okumak için mutlaka aşağıdaki gibi özel SQL kullanılmalı. Her bir SQL server için formatı değişir. SQL Server için şöyledir:

Kod: Tümünü seç

INSERT INTO testme (adi)
OUTPUT Inserted.autoinc
VALUES('deneme');
Eğer özel SQL komutu kullanılmaz ise Post işlemi sonrasında Query bileşeni Refresh edilmelidir. Bu iki yöntem dışında IDENTITY değerini öğrenmek mümkün değildir.

Size her ne kadar mantıklı gelmese dahi bunun çok geçerli bir sebebi var: Uygulamanın kayıt girer iken yaptığı işlem SQL sunucuya "bu bilgileri kaydet" demektir. Daha detaylı ifade etmek gerekir ise siz TUniQuery1.Post() komutunu verdiğinizde bileşen arka planda yukarıdaki örnek SQL komutuna benzer bir INSERT SQL komutunu oluşturur ve sunucuya gönderir. Aynı anda onlarca veya yüzlerce kullanıcı aynı tabloya kayıt giriyor olabilir. Uygulama SQL sunucu tarafından IDENTITY alanına atanan değeri bilemez. Bunu özellikle sorgulayarak öğrenmesi gerekli.

TUniQuery bileşeni IDENTITY türündeki alanları otomatik olarak algılayabilir. Ayrıca ilgili parametresi (TUniQuery.SpecificOptions.QueryIdentity parametresidir ve standart olarak açıktır) açık olduğu zaman özel SQL komutunu (atanan IDENTITY değerini geri çevirecek SQL komutu) kendisi arka planda sizin için otomatik olarak oluşturur ve SQL sunucu tarafından yeni kayıt için kullanılan değeri okur.

Benim bilgim dahilinde aşağıdaki parametreler UniDAC bileşenleri tarafından FirebirdSQL sunucusuna özel kullanılırlar.

Kod: Tümünü seç

UniQuery1.Options.StrictUpdate := False;
UniQuery1.DMLRefresh:=True;
Aşağıdaki kod ile deneme yaptığımda ID değerini geriye çeviriyor.

Kod: Tümünü seç

procedure TForm1.Button1Click(Sender: TObject);
var
  Query: TUniQuery;
begin
  Query := TUniQuery.Create(nil);
  try
    Query.Connection := UniConnection1;
    Query.SQL.Text := 'select * from testme';
    Query.Open();
    Query.Append();
    Query.FieldByName('ad').AsString := 'test';
    Query.Post();
    ShowMessage(Query.FieldByName('autoinc').AsString);
  finally
    Query.Free();
  end;
end;
Yukarıdaki örnek kod ile sizin kodunuz arasındaki farklar anlayabildiğim kadarıyla aşağıdaki gibi:
1- Örnek kod TUniQuery bileşeni içine alan tanımlarını (TUniQuery üzerinde sağ tuş -> Fields Editor...) tasarım zamanında doldurmuyor. Yani alan tanımları TUniQuery1.Open komutu ile bileşen tarafından otomatik olarak dolduruluyor. Dolayısıyla, TUniQuery bileşeni çalışma zamanında autoinc isimli alanın IDENTITY türünde bir alan olduğunu otomatik algılıyor. Bu anlamda sizin Fields Editor içinden "RecId" alanının tanımını kontrol etmenizde fayda var.
2- Örnek kod TUniQuery bileşeninin tüm ayarları standart şekilde iken çalıştırılıyor. Yani TUniQuery.Options veya TUniQuery.DMLRefresh parametreleri hiç değiştirilmiyor.

Eğer siz de örnek kod gibi denediğinizde IDENTITY değerini yine de okuyamıyor iseniz sorunu gösteren örnek tablo yapısı ve örnek proje dosyalarını paylaşmanızda fayda olacaktır.
apex06
Üye
Mesajlar: 58
Kayıt: 19 Nis 2012 12:21

Re: uniquery post sonrası id null değer

Mesaj gönderen apex06 »

@ertank merhaba,
Allah senden razı olsun, o kadar güzel anlattın ki test sırasında sorunun çözüleceğini bile anlıyor insan :)

dediğin gibi ilgili field'ın AutoGenerateValue özelliğini None > arAutoInc yapınca düzeldi.

Çok teşekkürler, iyi çalışmalar :)

ertank yazdı: 27 Eyl 2017 02:37 Merhaba,

Öncelikle, IDENTITY türündeki alanların değerini okumak için mutlaka aşağıdaki gibi özel SQL kullanılmalı. Her bir SQL server için formatı değişir. SQL Server için şöyledir:

Kod: Tümünü seç

INSERT INTO testme (adi)
OUTPUT Inserted.autoinc
VALUES('deneme');
Eğer özel SQL komutu kullanılmaz ise Post işlemi sonrasında Query bileşeni Refresh edilmelidir. Bu iki yöntem dışında IDENTITY değerini öğrenmek mümkün değildir.

Size her ne kadar mantıklı gelmese dahi bunun çok geçerli bir sebebi var: Uygulamanın kayıt girer iken yaptığı işlem SQL sunucuya "bu bilgileri kaydet" demektir. Daha detaylı ifade etmek gerekir ise siz TUniQuery1.Post() komutunu verdiğinizde bileşen arka planda yukarıdaki örnek SQL komutuna benzer bir INSERT SQL komutunu oluşturur ve sunucuya gönderir. Aynı anda onlarca veya yüzlerce kullanıcı aynı tabloya kayıt giriyor olabilir. Uygulama SQL sunucu tarafından IDENTITY alanına atanan değeri bilemez. Bunu özellikle sorgulayarak öğrenmesi gerekli.

TUniQuery bileşeni IDENTITY türündeki alanları otomatik olarak algılayabilir. Ayrıca ilgili parametresi (TUniQuery.SpecificOptions.QueryIdentity parametresidir ve standart olarak açıktır) açık olduğu zaman özel SQL komutunu (atanan IDENTITY değerini geri çevirecek SQL komutu) kendisi arka planda sizin için otomatik olarak oluşturur ve SQL sunucu tarafından yeni kayıt için kullanılan değeri okur.

Benim bilgim dahilinde aşağıdaki parametreler UniDAC bileşenleri tarafından FirebirdSQL sunucusuna özel kullanılırlar.

Kod: Tümünü seç

UniQuery1.Options.StrictUpdate := False;
UniQuery1.DMLRefresh:=True;
Aşağıdaki kod ile deneme yaptığımda ID değerini geriye çeviriyor.

Kod: Tümünü seç

procedure TForm1.Button1Click(Sender: TObject);
var
  Query: TUniQuery;
begin
  Query := TUniQuery.Create(nil);
  try
    Query.Connection := UniConnection1;
    Query.SQL.Text := 'select * from testme';
    Query.Open();
    Query.Append();
    Query.FieldByName('ad').AsString := 'test';
    Query.Post();
    ShowMessage(Query.FieldByName('autoinc').AsString);
  finally
    Query.Free();
  end;
end;
Yukarıdaki örnek kod ile sizin kodunuz arasındaki farklar anlayabildiğim kadarıyla aşağıdaki gibi:
1- Örnek kod TUniQuery bileşeni içine alan tanımlarını (TUniQuery üzerinde sağ tuş -> Fields Editor...) tasarım zamanında doldurmuyor. Yani alan tanımları TUniQuery1.Open komutu ile bileşen tarafından otomatik olarak dolduruluyor. Dolayısıyla, TUniQuery bileşeni çalışma zamanında autoinc isimli alanın IDENTITY türünde bir alan olduğunu otomatik algılıyor. Bu anlamda sizin Fields Editor içinden "RecId" alanının tanımını kontrol etmenizde fayda var.
2- Örnek kod TUniQuery bileşeninin tüm ayarları standart şekilde iken çalıştırılıyor. Yani TUniQuery.Options veya TUniQuery.DMLRefresh parametreleri hiç değiştirilmiyor.

Eğer siz de örnek kod gibi denediğinizde IDENTITY değerini yine de okuyamıyor iseniz sorunu gösteren örnek tablo yapısı ve örnek proje dosyalarını paylaşmanızda fayda olacaktır.
Cevapla