Parametre ile insert işleminde SET FMTONLY

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
Okann
Üye
Mesajlar: 81
Kayıt: 09 Tem 2010 02:55

Parametre ile insert işleminde SET FMTONLY

Mesaj gönderen Okann »

Arkadaşlar Merhaba,

Insert işleminde parametre kullanarak veritabanına kayıt attığımda profiler ile incelediğimde SET FMTONLY sorgusu çalışıyor.
Fakat düz bir insertte bu sorgu çalışmıyor. SCOPE_IDENTITY() ile referansı almam gerektiğinden parametre ile kayıt atıyorum.
SET FMTONLY sorgusunun çalışmasını istemiyorum. Bunu nasıl engelleyebilirim. Acaba insert ederken hatalımı kullanıyorum kodlarımı veya bu sorgunun çalışıp çalışmaması parametrik bir şey midir? Kod bloğum aşağıdadır. Yardımcı olursanız çok sevinirim.

Kod: Tümünü seç

var
  QUnit: TMSQuery;
  UnitRef: Integer;
begin
  if edtCode.Text <> '' then
  begin
    QUnit := TMSQuery.Create(nil);
    QUnit.Connection := fmMain.db;
    with QUnit do
    begin
      SQL.Clear;
      SQL.Add('SELECT CODE');
      SQL.Add('FROM "' + Database + '".."UNIT" WITH(NOLOCK)');
      Open;
      First;
    end;
    try
      if not QUnit.Locate('CODE', Variant(edtCode.Text), [loCaseInsensitive]) then
      begin
        QUnit.Close;
        QUnit.Connection.StartTransaction;
        try
          with QUnit do
          begin
            SQL.Clear;
            SQL.Add('SET NOCOUNT OFF; INSERT INTO "' + Database + '".."UNIT" ');
            SQL.Add('("CODE", "NAME", "CARDTYPE", "ACODE", "BCODE")');
            SQL.Add('VALUES(:CODE, :NAME, :CARDTYPE, :ACODE, :BCODE); SELECT SCOPE_IDENTITY()');
            Params.ParamByName('CODE').Value := edtCode.Text;
            Params.ParamByName('NAME').Value := edtName.Text;
            Params.ParamByName('CARDTYPE').Value := 5;
            Params.ParamByName('ACODE').Value := edtACode.Text;
            Params.ParamByName('BCODE').Value := edtBCode.Text;
            ExecSQL;
            UnitRef := Fields.Fields[0].Value;
          end;
          QUnit.Connection.Commit;
        except
          QUnit.Connection.Rollback;
          TfmMessages.MessagesExecute(1, 4, MB_ICONHAND, #13#10 + #13#10 +
            '     Birim kaydedilirken bir hata oluştu!');
        end;
      end else
      begin
        TfmMessages.MessagesExecute(1, 3, MB_ICONWARNING, #13#10 + #13#10 +
          '       Aynı kodlu bir birim daha var!');
      end;
    finally
      QUnit.Free;
    end;
  end;
end;
ertank
Kıdemli Üye
Mesajlar: 1716
Kayıt: 12 Eyl 2015 12:45

Re: Parametre ile insert işleminde SET FMTONLY

Mesaj gönderen ertank »

Merhaba,

Öncelikle kullandığınız Delphi sürümü ve database bileşenlerini soru sorarken bildirmenizde fayda var.

İstediğiniz özelliği Database bileşenlerinin desteklemesi gerekmekte. Zira siz insert için ExecSQL() komutunu kullanıyorsunuz ve bu komut geriye veri çevirmeyen bir SQL komutudur. Bileşen ilk INSERT komutunu çalıştırıp ardındaki "select scope_identity()" komutunu otomatik algılayarak bu komut için ayrı bir OPEN() işlemi geçekleştirmesi gerekir.

1- Devart firmasının UniDAC bileşenleri ile test ettiğimde ExecSQL() komutu ile sorun yaşamadan değeri okuyabildim.
2- Delphi ile gelen FireDAC bileşenleri ile test ettiğimde ExecSQL() komutu ile değer okuyamadım. Diğer taraftan FireDAC bileşenleri aynı SQL komutunu Open() ile çalıştırdığım zaman geriye değer çevirdi.

Teste istinaden sizin kullandığınız bileşenlerin bu yönde bir desteği olmadığını söyleyebiliriz. Çözüm olarak ise Query komutunuzu Open() şeklinde değiştirmenizi öneririm.
Okann
Üye
Mesajlar: 81
Kayıt: 09 Tem 2010 02:55

Re: Parametre ile insert işleminde SET FMTONLY

Mesaj gönderen Okann »

Ben Delphi XE7 ve SDAC bileşenlerini kullanıyorum.

Benim sıkıntım insert edebilmek veya identity değeri okuyabilmekde değilki. ben identity değeri okuyabilmek için parametre vererek insert sorgusunu oluşturuyorum dedim. bu noktada hiçbir problemim yok. Düz insertte aşağıdaki sorgu profilerda görünmüyor ama parametre vererek bir insert sorgusu oluşturduğumda aşağıdaki sorgu otomatik olarak çalışıyor. Benim merak ettiğim şudur. bu sorgunun otomatik olarak çalışmasını nasıl engelleyebilirim. bir kaç sefer transaction ların askıda kalmasına sebebiyet verdi.

SET FMTONLY ON select "CODE","NAME","CARDTYPE","ACODE","BCODE" from "DB".."UNIT" WHERE 1=2 SET FMTONLY OFF
ertank
Kıdemli Üye
Mesajlar: 1716
Kayıt: 12 Eyl 2015 12:45

Re: Parametre ile insert işleminde SET FMTONLY

Mesaj gönderen ertank »

Siz tablo içindeki bir alanın değerini okumak için select scope_identity() komutunu kullanıyorsunuz. Bu komut tablo içindeki hangi alanın bilgisini okuması gerektiğini bilmiyor normalde.

Hangi kolon olduğunu tablo alanlarının bilgilerini okuyup Identity alanı tespit edip size gösteriyor.

Kısaca bu komutun çalışmasını sizin insert komutunuzun arkasından gelen select zorunlu kılıyor.
Okann
Üye
Mesajlar: 81
Kayıt: 09 Tem 2010 02:55

Re: Parametre ile insert işleminde SET FMTONLY

Mesaj gönderen Okann »

İlgilendiğiniz için teşekkür ederim.
Ancak select scope_identity() ifadesini sorgudan çıkardığım halde yinede o komut çalışıyor.
ertank
Kıdemli Üye
Mesajlar: 1716
Kayıt: 12 Eyl 2015 12:45

Re: Parametre ile insert işleminde SET FMTONLY

Mesaj gönderen ertank »

SDAC bileşenlerindeki başka bir ayar sebebi ile çalışyor olmalı. Aşağıdaki bağlantıdan sorunuzu esas bileşen üreticilerine iletebilirsiniz.
http://forums.devart.com/
Okann
Üye
Mesajlar: 81
Kayıt: 09 Tem 2010 02:55

Re: Parametre ile insert işleminde SET FMTONLY

Mesaj gönderen Okann »

Teşekkürler ilgilendiğiniz için.
Cevapla