Yorumları: 669
Konuları: 73
Kayıt Tarihi: 20-12-2018
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 1.544 Programcı
08-02-2019, Saat: 16:37
(Son Düzenleme: 08-02-2019, Saat: 20:49, Düzenleyen: shooterman.
Sebep: düzenleme
)
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.
Yorumları: 1.660
Konuları: 20
Kayıt Tarihi: 05-08-2016
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 18.981 Üstad
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
Yorumları: 669
Konuları: 73
Kayıt Tarihi: 20-12-2018
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 1.544 Programcı
08-02-2019, Saat: 18:13
(Son Düzenleme: 08-02-2019, Saat: 18:13, Düzenleyen: shooterman.)
(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.
Yorumları: 644
Konuları: 84
Kayıt Tarihi: 04-10-2017
Aktif Kullandığınız Delphi Sürümü:
- Delphi 11
- Delphi 10.4
- Delphi 10.3
- Delphi 10.2
- Delphi 10.1
- Delphi 10
- Delphi XE Serisi
Rep Puanı: 2.701 Uzman
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..
Yorumları: 669
Konuları: 73
Kayıt Tarihi: 20-12-2018
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 1.544 Programcı
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.
Yorumları: 644
Konuları: 84
Kayıt Tarihi: 04-10-2017
Aktif Kullandığınız Delphi Sürümü:
- Delphi 11
- Delphi 10.4
- Delphi 10.3
- Delphi 10.2
- Delphi 10.1
- Delphi 10
- Delphi XE Serisi
Rep Puanı: 2.701 Uzman
08-02-2019, Saat: 20:04
(Son Düzenleme: 08-02-2019, Saat: 20:24, Düzenleyen: narkotik.)
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..
Yorumları: 669
Konuları: 73
Kayıt Tarihi: 20-12-2018
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 1.544 Programcı
(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.
Yorumları: 644
Konuları: 84
Kayıt Tarihi: 04-10-2017
Aktif Kullandığınız Delphi Sürümü:
- Delphi 11
- Delphi 10.4
- Delphi 10.3
- Delphi 10.2
- Delphi 10.1
- Delphi 10
- Delphi XE Serisi
Rep Puanı: 2.701 Uzman
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..
Yorumları: 231
Konuları: 12
Kayıt Tarihi: 06-07-2018
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 1.178 Programcı
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.
Yorumları: 1.460
Konuları: 80
Kayıt Tarihi: 05-08-2016
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 11.868 Üstad
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...
|