Konuyu Oyla:
  • Derecelendirme: 0/5 - 0 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Listview veri sorgulama hk.
#1
Sn. Meslektaşlarım,

Bir konuda yardımlarınızı rica ediyorum.

Listview içerisine, her 1 saniyede farklı 400 satır değer aktarıyorum. 1 saniye sonra ise, yeni bir 400 satır veri daha ekleniyor. Böylece 10 saniyede 4000 satır oluşuyor.

Şu andaki problemime gelince, veri akışının sürekli olduğu bu işlemde, ilistviewdaki kayıtları alıp veritabanına insert etmem, ve kayıt edilenleri de listview dan silmem gerekiyor. Bununla ilgili olarak, nasıl bir yol izlemem konusunda desteklerinizi rica ederim.
Yazılımcı, kahveyi koda çeviren bir organizmadır.
Cevapla
#2
Bir yanlış anlaşılma var, her item 1 kayıt olup 400 tane subitem olunca 10 saiyede 10 satır olur.
Saygılarımla
Muharrem ARMAN

guplouajuixjzfm15eqb.gif
Cevapla
#3
(08-02-2019, Saat: 17:19)mrmarman Adlı Kullanıcıdan Alıntı: Bir yanlış anlaşılma var, her item 1 kayıt olup 400 tane subitem olunca 10 saiyede 10 satır olur.

Sevgili Muharrem hocam,

Atılacak veriler sadece tek bir alana atılacağından dolayı, satır sayısını 10 saniyede 4000 olarak verdim. Listview yapısı ektedir. Ayrıca buradaki 400 değeri bir gün sonra 450 veriye çıkabileceği için, sütunu tek bir tanede bırakmak durumunda kaldım.


   
Yazılımcı, kahveyi koda çeviren bir organizmadır.
Cevapla
#4
Tek tek atarsanız mantıksız olur batch mantığı insert cümlelerini oluşturun, en son transaction ile post edin
Yalnızım ama bir kente yürüyen ordu gibiyim, edebiyattan kaçınmalıyım..
Cevapla
#5
Arkadaşlar,
PLC cihazı, verileri her 1 saniye refresh ettiği için, değerleri kaçırmadan alıp, veri tabanına insert etmem gerekiyor. Şimdilik 400 farklı değer var. Bunları okuyorum ve listview a aktarıyorum. Burada bir veri kaybı yaşamıyorum. Ancak Listview daki bu biriken verileri 100 lük satırlar ya da 200 lük satırlar şeklinde alıp veri tabanına yazmam gerekiyor. Buradaki mantığı oluşturamadım kafamda. Yani Listview dan ilk 100 veriyi okudum ve veritabanına insert ettim diyelim, aldığım bu 100 veriyi listviewdan silmem gerekiyor. Şimdlik bu şekilde bir fikir oluştu ama, nasıl yapacağım konusunda yardımarınızı rica ediyorum.
Yazılımcı, kahveyi koda çeviren bir organizmadır.
Cevapla
#6
PLC'den gelen verileri temp tabloya alsanız, listview'i tabloya bağlasanız her 1 saniyede listviewi yeniseleniz bu sırada arkada bir tane SQL procedure de thread mantığı çalışsa parametre olarak gelen temp tabloyu gerçek tabloya transaction ile insert etse nasıl olur benim aklıma bu geldi diğer türlü külfetli geldi bana.
Geliştireceğiniz algoritmada dikkatli olmanızı öneririm olası bir recovery pending de çok uğraşırsınız
Yalnızım ama bir kente yürüyen ordu gibiyim, edebiyattan kaçınmalıyım..
Cevapla
#7
(08-02-2019, Saat: 20:04)narkotik Adlı Kullanıcıdan Alıntı: PLC'den gelen verileri temp tabloya alsanız, listview'i tabloya bağlasanız her 1 saniyede listviewi yeniseleniz bu sırada arkada bir tane SQL procedure de thread mantığı çalışsa parametre olarak gelen temp tabloyu gerçek tabloya transaction ile insert etse nasıl olur benim aklıma bu geldi diğer türlü külfetli geldi bana.
Geliştireceğiniz algoritmada dikkatli olmanızı öneririm olası bir recovery pending de çok uğraşırsınız

Çok teşekkür ederim. Dediğiniz yolu da deneyeceğim.
Yazılımcı, kahveyi koda çeviren bir organizmadır.
Cevapla
#8
Hocam bende merak ettim şöyle bir deneme yaptım kendim yazdığım küçük işlerde kullandığım bir queryim var, bununla iyi sonuçlar aldım 1 dakika falan çalıştırdım. Kendine göre iyileştirmeler yapıp bir test et istersen.

unit NrWebServiceQuery;

interface
 uses VirtualTable,System.SysUtils,System.Classes,Data.DB;

type
TNrWebServiceQuery = class(TVirtualTable)
private
 FSQLTableName: String;
 FSQLPrimaryFields: String;
 FSQLBatch: TStrings;
 FBatch: Boolean;
 procedure SetSQLTableName(const Value: String);
 procedure SetSQLPrimaryFields(const Value: String);
 procedure SetSQLBatch(const Value: TStrings);
 procedure SetBatch(const Value: Boolean);
 function GetFieldList:String;
 function GetFieldListNotPrimaryFields:String;
 function GetFieldValue(AField:TField):String;
 function GetFound: Boolean;
 { private declarations }
protected
 { protected declarations }
public
 constructor Create(AOwner: TComponent); override;
 Destructor  Destroy; override;
 procedure   DoBeforePost; override;
published
 property SQLTableName: String read FSQLTableName write SetSQLTableName;
 property SQLPrimaryFields: String read FSQLPrimaryFields write SetSQLPrimaryFields;
 property Batch: Boolean read FBatch write SetBatch;
 property SQLBatch : TStrings read FSQLBatch write SetSQLBatch;
 property Found: Boolean read GetFound;
end;

implementation

{ TNrWebServiceQuery }

constructor TNrWebServiceQuery.Create(AOwner: TComponent);
begin
 inherited;
 SQLBatch := TStringList.Create;
end;

destructor TNrWebServiceQuery.Destroy;
begin
 SQLBatch.Free;
 inherited;
end;

procedure TNrWebServiceQuery.DoBeforePost;
Var BatchString : String;
   TempValue   : String;
   PTempValue  : String;
   PrimaryList : TStringList;
   Ind         : Integer;
begin
 inherited;
 if Batch then
 begin
   if SQLTableName = '' then
   begin
     SQLBatch.Add('SQLTableName boş olamaz!');
     Exit;
   end
   else if SQLPrimaryFields = '' then
   begin
     SQLBatch.Add('SQLPrimaryFields boş olamaz!');
     Exit;
   end;
   try
     if State in [dsEdit] then
     begin
       BatchString := Concat('UPDATE ',SQLTableName,' SET ');
       PrimaryList := TStringList.Create;
       try
         PrimaryList.BeginUpdate;
         PrimaryList.Text := StringReplace(SQLPrimaryFields,',',sLineBreak,[rfReplaceAll]);
         PrimaryList.EndUpdate;
         for Ind := 0 to Pred(FieldCount) do
         begin
           If PrimaryList.IndexOf(Fields[Ind].FieldName) <> -1 then
           begin
             if PTempValue = '' then
               PTempValue := Concat(Fields[Ind].FieldName,'=')
             else
               PTempValue := PTempValue + Concat(' AND ',Fields[Ind].FieldName,'=');
             PTempValue := Concat(PTempValue,GetFieldValue(Fields[Ind]));
             Continue;
           end;
           TempValue := Concat(TempValue,Fields[Ind].FieldName,'=',GetFieldValue(Fields[Ind]),',');
         end;
         TempValue   := Copy(TempValue,1,TempValue.Length-1);
         BatchString := Concat(BatchString,TempValue,' WHERE ',PTempValue);
         SQLBatch.BeginUpdate;
         SQLBatch.Add(BatchString);
         SQLBatch.EndUpdate;
       finally
         FreeAndNil(PrimaryList);
       end;
     end
     else if State in [dsInsert] then
     begin
       BatchString := Concat('INSERT INTO ',SQLTableName,'(',GetFieldListNotPrimaryFields,')',' VALUES(');
       PrimaryList := TStringList.Create;
       try
         PrimaryList.BeginUpdate;
         PrimaryList.Text := StringReplace(SQLPrimaryFields,',',sLineBreak,[rfReplaceAll]);
         PrimaryList.EndUpdate;
         for Ind := 0 to Pred(FieldCount) do
         begin
           If PrimaryList.IndexOf(Fields[Ind].FieldName) <> -1 then Continue;
           TempValue := Concat(TempValue,GetFieldValue(Fields[Ind]),',');
         end;
         TempValue   := Copy(TempValue,1,TempValue.Length-1);
         BatchString := Concat(BatchString,TempValue,')');
         SQLBatch.BeginUpdate;
         SQLBatch.Add(BatchString);
         SQLBatch.EndUpdate;
       finally
         FreeAndNil(PrimaryList);
       end;
     end;
   Except
     on e:Exception do
     begin
       SQLBatch.Add(e.Message);
     end;
   end;
 end;
end;

function TNrWebServiceQuery.GetFieldList: String;
Var Ind : Integer;
begin
 for Ind := 0 to Pred(FieldCount) do
   Result := Concat(Result,Fields[Ind].FieldName,',');
 Result := Copy(Result,1,Result.Length-1);
end;

function TNrWebServiceQuery.GetFieldListNotPrimaryFields: String;
Var Ind : Integer;
   PrimaryList : TStringList;
begin
 PrimaryList := TStringList.Create;
 PrimaryList.BeginUpdate;
 PrimaryList.Text := StringReplace(SQLPrimaryFields,',',sLineBreak,[rfReplaceAll]);
 PrimaryList.EndUpdate;
 try
   for Ind := 0 to Pred(FieldCount) do
   begin
     If PrimaryList.IndexOf(Fields[Ind].FieldName) <> -1 then Continue;
     Result := Concat(Result,Fields[Ind].FieldName,',');
   end;
   Result := Copy(Result,1,Result.Length-1);
 finally
   FreeAndNil(PrimaryList);
 end;
end;

function TNrWebServiceQuery.GetFieldValue(AField:TField): String;
begin
 case AField.DataType of
   ftString   : Result := QuotedStr(AField.AsString);
   ftInteger  : Result := IntToStr(AField.AsInteger);
   ftFloat    : Result := StringReplace(FloatToStr(AField.AsFloat),FormatSettings.DecimalSeparator,'.',[rfReplaceAll]);
   ftDate     : Result := QuotedStr(FormatDateTime('yyyy-mm-dd',AField.AsDateTime));
   ftDateTime : Result := QuotedStr(FormatDateTime('yyyy-mm-dd hh:nn:ss:',AField.AsDateTime));
   ftBlob     : Result := QuotedStr(AField.AsString);
 end;
end;

function TNrWebServiceQuery.GetFound: Boolean;
begin
 Result := Active and (RecordCount > 0);
end;

procedure TNrWebServiceQuery.SetBatch(const Value: Boolean);
begin
 FBatch := Value;
end;

procedure TNrWebServiceQuery.SetSQLBatch(const Value: TStrings);
begin
 FSQLBatch := Value;
end;

procedure TNrWebServiceQuery.SetSQLPrimaryFields(const Value: String);
begin
 FSQLPrimaryFields := Value;
end;

procedure TNrWebServiceQuery.SetSQLTableName(const Value: String);
begin
 FSQLTableName := Value;
end;

end.

procedure TFrmTest.FormCreate(Sender: TObject);
begin
 xLocalQuery := TNrWebServiceQuery.Create(nil);
 xLocalQuery.FieldDefs.Add('VALUE',ftFloat);
 xLocalQuery.FieldDefs.Add('ID',ftInteger);
 xLocalQuery.SQLTableName := 'TEST_TABLE';
 xLocalQuery.SQLPrimaryFields := 'ID';
 xLocalQuery.Batch := True;
 xLocalQuery.Open;
 DataSource1.DataSet := xLocalQuery;
end;

procedure TFrmTest.Timer1Timer(Sender: TObject);
Var Ind : Integer;
begin
 xLocalQuery.DisableControls;
 xLocalQuery.SQLBatch.Clear;
 xLocalQuery.Clear;
 for Ind := 1 to 400 do
 begin
   xLocalQuery.Insert;
   xLocalQuery.FieldByName('VALUE').Value := Ind;
   xLocalQuery.Post;
 end;
 Caption := xLocalQuery.RecordCount.ToString;
 xLocalQuery.EnableControls;
 if xLocalQuery.SQLBatch.Text <> '' then
 begin
   QryTest.SQL.Text := xLocalQuery.SQLBatch.Text;
   QryTest.ExecSQL;
 end;
end;
Yalnızım ama bir kente yürüyen ordu gibiyim, edebiyattan kaçınmalıyım..
Cevapla
#9
1 seferlik bütüncül okuma sonrasında tüm veriler istisnasız olarak veritabanına yazılır.
Veritabanını BATCH UPDATE modunda kullanmak belki faydalı olabilir.

ListView için ise bellekte bir Record listesi tutulup OnPaint olayları çalıştırılabilir.

Veritabanında ne kadar değer tutulacağı yazılmadığı için şimdilik eksik çözüm olarak bırakıyorum.
Cevapla
#10
Listview’in varlığının amacı nedir ? Direkt veritabanına atmada bir problem mi var ?
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  IEC 61850 Potokolünden veri alma shooterman 1 413 14-03-2024, Saat: 11:38
Son Yorum: shooterman
  Veri Tabanına Kontrollü Kayıt Yaptırma bünyamin68 15 617 08-03-2024, Saat: 00:06
Son Yorum: TuncayDelphi
  Problem - ZKTeco Cihazlardan Anlık Veri Alma mad85 16 7.951 25-12-2023, Saat: 11:35
Son Yorum: osiso
  Cas Terazi Veri gönderimi Delphi sürüm sorunu KUNTAY 12 4.300 08-11-2023, Saat: 00:06
Son Yorum: berkan
  Delphi Sürekli Adı Değişen Excel Dosyasından Veri Çekme bünyamin68 2 555 05-10-2023, Saat: 12:50
Son Yorum: mcuyan



Konuyu Okuyanlar: 1 Ziyaretçi