Calculated field gibi davranan bir field inşa etmek (MySQL)

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
fatihbarut
Üye
Mesajlar: 368
Kayıt: 15 Ara 2011 08:02

Calculated field gibi davranan bir field inşa etmek (MySQL)

Mesaj gönderen fatihbarut » 25 Kas 2017 09:48

Arkadaşlar,
MySQL'de sayı ile fiyatı çarpıp toplam fiyat gösteren bir calculated field'ım vardı. Herşey mutlu mesut gidiyordu.
Derken Unidump ile veri tabanını yedekleyip geri aldım ve virtual fieldları desteklemediğini gördüm.
Şimdi bu toplam ücret virtual fieldını normale çevirip aynı işi triger'la yapmam gerekecek.
Nasıl olacağı hakkında fikri olan var mı?
teşekkürler

fatihbarut
Üye
Mesajlar: 368
Kayıt: 15 Ara 2011 08:02

Re: Calculated field gibi davranan bir field inşa etmek (MySQL)

Mesaj gönderen fatihbarut » 25 Kas 2017 10:41

Aşağıdaki gibi iki triger sanırsam galiba

CREATE DEFINER = 'root'@'localhost' TRIGGER makbuzdaki_analizler_before_upd_tr1 BEFORE UPDATE ON makbuzdaki_analizler
FOR EACH ROW
BEGIN
set NEW.toplam_analiz_ucreti=NEW.analiz_yapilacak_ornek_sayisi * NEW.analizin_birim_fiyati;
END;

CREATE DEFINER = 'root'@'localhost' TRIGGER MakbuzdakiAnalizlerToplamUcret BEFORE INSERT ON makbuzdaki_analizler
FOR EACH ROW
BEGIN
set NEW.toplam_analiz_ucreti=NEW.analiz_yapilacak_ornek_sayisi * NEW.analizin_birim_fiyati;
END;

ertank
Üye
Mesajlar: 964
Kayıt: 11 Eyl 2015 11:45

Re: Calculated field gibi davranan bir field inşa etmek (MySQL)

Mesaj gönderen ertank » 25 Kas 2017 01:33

fatihbarut yazdı:
25 Kas 2017 09:48
Arkadaşlar,
MySQL'de sayı ile fiyatı çarpıp toplam fiyat gösteren bir calculated field'ım vardı. Herşey mutlu mesut gidiyordu.
Derken Unidump ile veri tabanını yedekleyip geri aldım ve virtual fieldları desteklemediğini gördüm.
Şimdi bu toplam ücret virtual fieldını normale çevirip aynı işi triger'la yapmam gerekecek.
Nasıl olacağı hakkında fikri olan var mı?
teşekkürler
Merhaba,

Benim anladığım kadarıyla bahsettiğiniz özellik MySQL generated columns özelliği
https://dev.mysql.com/doc/refman/5.7/en ... lumns.html
Yine benim anladığım VIRTUAL olarak tanımlanmış generated colum değeri disk üzerinde saklanmaz.
As of MySQL 5.7.6, CREATE TABLE supports the specification of generated columns. Values of a generated column are computed from an expression included in the column definition.
Bu durumda TUniDump ile aldığınız bilgileri ilgili VIRTUAL kolon verileri olmadan aynı tanıma sahip boş başka bir MySQL tablosuna yüklediğiniz zaman ilgili VIRTUAL kolonlarınız hesaplanarak yine aynı değerleri vermesi gerekli.

Dışa aktarılan verileri yeni bir tablo içine yükleyerek aynı değerleri görüp görmediğinizi hiç test ettiniz mi?

fatihbarut
Üye
Mesajlar: 368
Kayıt: 15 Ara 2011 08:02

Re: Calculated field gibi davranan bir field inşa etmek (MySQL)

Mesaj gönderen fatihbarut » 25 Kas 2017 04:20

yok ya mesele Unidump'ın mysql'in 5.x'inde çıkmış olan virtual field'lara adaptasyonunu yapmamış olması.

haber verdim, foruma atın yeterince oy alırsa bu özelliği ekleyelim dediler. Ben de ne zamandan beri debug oylama ile yapılıyor diye onlara sordum.

anlayacağınız bir şey tek tıklama ile olmuyorsa olmuyor demektir.


Unidump kendini düzeltinceye kadar virtual fieldları normale çevirdim yukardaki triger'lar da işi gördü.

fatihbarut
Üye
Mesajlar: 368
Kayıt: 15 Ara 2011 08:02

Re: Calculated field gibi davranan bir field inşa etmek (MySQL)

Mesaj gönderen fatihbarut » 25 Kas 2017 11:06

Edit:
Çok akıllı unidump trigerları da backuplamıyormuş...
Kaldık mysqldump'a

ertank
Üye
Mesajlar: 964
Kayıt: 11 Eyl 2015 11:45

Re: Calculated field gibi davranan bir field inşa etmek (MySQL)

Mesaj gönderen ertank » 25 Kas 2017 11:10

Az önce test ettiğim kadarıyla TUniDump yedeklemesinde bütün kolonları yedeğe dahil ediyor. Özetle "SELECT * FROM <tablo_adi>" komutu ile listelenen tüm kolonlar yedeğe dahil edilmiş oluyor.

Ancak MySQL için VIRTUAL kolonların yedeğe dahil edilmesi geri yüklemenin yapılamamasına sebep oluyor. Çünkü MySQL VIRTUAL tanımlı kolonlara veri ataması yapılmasına izin vermiyor.

Sorun için aşağıdaki şekilde dolaylı bir çözüm mümkün olabilir. Aşağıdaki gibi bir tablo tanımınız olduğunu düşünelim:

Kod: Tümünü seç

CREATE TABLE `deneme` (
  `abc` varchar(10) COLLATE utf8_turkish_ci DEFAULT NULL,
  `i1` int(11) DEFAULT NULL,
  `i2` int(11) DEFAULT NULL,
  `calc` int(11) GENERATED ALWAYS AS ((`i1` + `i2`)) VIRTUAL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_turkish_ci;
İçindeki veriler aşağıdaki gibi olsun:

Kod: Tümünü seç

# abc, i1, i2, calc
'abc1', '1', '2', '3'
'abc2', '2', '2', '4'
'abc3', '3', '2', '5'
'abc4', '4', '2', '6'
'abc5', '5', '2', '7'
'abc6', '6', '2', '8'
Aşağıdaki gibi bir kod kullanarak sadece gerekli kolonlara ait verilerin yedeklenmesini sağlamak mümkün olacaktır:

Kod: Tümünü seç

  UniDump1.BackupQuery('select abc,i1,i2 from deneme');
  UniDump1.SQL.SaveToFile('test.sql');
Oluşan yedek dosyasının içeriği aşağıdaki gibi olacaktır:

Kod: Tümünü seç

-- UniDAC version: 7.1.3
-- MySQL server version: 5.7.20
-- MySQL client version: 8.0.0 Direct
-- Script date 26/11/2017 00:02:09
-- ---------------------------------------------------------------------- 
-- Server: 192.168.1.101
-- Database: test

/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
-- 
-- Dumping data for table deneme
-- 

TRUNCATE TABLE deneme;
INSERT INTO deneme(abc, i1, i2) VALUES
 ('abc1',1,2),
 ('abc2',2,2),
 ('abc3',3,2),
 ('abc4',4,2),
 ('abc5',5,2),
 ('abc6',6,2);

/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
Bu dosyanın geri yüklenmesinde de bir sorun oluşmayacaktır.

Bu işlemin zorluğu tüm database yedeklemesi için her bir tabloyu ayrı ayrı ve eğer var ise tabloya özel SELECT komutu ile yedeklemek gerekmesidir.

fatihbarut
Üye
Mesajlar: 368
Kayıt: 15 Ara 2011 08:02

Re: Calculated field gibi davranan bir field inşa etmek (MySQL)

Mesaj gönderen fatihbarut » 26 Kas 2017 12:03

Teşekkür ederim.
Yalnız sorun şu ki 37 tablonun her birinde bilmem kaç tane fiedl olunca, bu manuel işlemler acı veriyor. Sonuçta para verip aldığımız bir ürün ve doğru düzgün bir hizmet gerekiyor.

ertank
Üye
Mesajlar: 964
Kayıt: 11 Eyl 2015 11:45

Re: Calculated field gibi davranan bir field inşa etmek (MySQL)

Mesaj gönderen ertank » 26 Kas 2017 05:00

Aşağıdaki kod örneği ile database içindeki tüm kullanıcı tarafından oluşturulan tablo ve bu tablo kolon isimlerini VIRTUAL kolonlar filtrelenmiş şekilde text dosyasına kaydedebilirsiniz. İlgili text dosyalarını TUniDump için yükleyip kullanmanız halinde VIRTUAL kolon sorununuz kalmamış olur. Sadece TUniDump ile ilgili kodunuzda bir miktar düzenleme yapmanız gerekecektir.

Kod: Tümünü seç

procedure GetRealFields(Connection: TUniConnection; const TableName: string; List: TStrings);
var
  Query: TUniQuery;
begin
  Query := TUniQuery.Create(nil);
  try
    Query.Connection := Connection;
    Query.SQL.Text := 'show columns from ' + TableName + ' where Extra <> ''VIRTUAL GENERATED''';
    Query.Open();

    List.Clear();
    while not Query.Eof do
    begin
      List.Add(Query.Fields[0].AsString);
      Query.Next();
    end;
  finally
    Query.Free();
  end;
end;

procedure DumpTablesFields(Connection: TUniConnection);
var
  TableList: TStringList;
  FieldList: TStringList;
  SW: TStreamWriter;
  I: Integer;
  I2: Integer;
  TempString: string;
begin
  TableList := TStringList.Create();
  try
    Connection.GetTableNames(TableList);
    FieldList := TStringList.Create();
    try
      for I := 0 to Pred(TableList.Count) do
      begin
        GetRealFields(Connection, TableList[I], FieldList);
        SW := TStreamWriter.Create(TableList[I] + '.txt', False, TEncoding.UTF8);
        try
          TempString := 'SELECT ';
          for I2 := 0 to Pred(FieldList.Count) do
          begin
            TempString := TempString + FieldList[I2] + ',';
          end;
          if FieldList.Count > 0 then SetLength(TempString, Length(TempString) - 1);
          TempString := TempString + ' FROM ' + TableList[I];

          SW.WriteLine(TempString);
        finally
          SW.Free();
        end;
      end;
    finally
      FieldList.Free();
    end;
  finally
    TableList.Free();
  end;
end;

fatihbarut
Üye
Mesajlar: 368
Kayıt: 15 Ara 2011 08:02

Re: Calculated field gibi davranan bir field inşa etmek (MySQL)

Mesaj gönderen fatihbarut » 26 Kas 2017 06:58

Teşekkür ederim.
Yalnız sorun şuydu bu işleri admin konumundaki kişinin yapması gerekiyor. Bunun için Unidump kullandım ki tek tıklama ile halletsin diye. Bu kadar karmaşa riskine giremem.
Mysqldump'dan devam edicem.
Yalnız şu konuda yardımcı olursanız gerçekten sevinirim.
mysqldump'ın command shell ini çalıştırıp tüm trigerlar, tüm table'lar ve tüm viewlar şeklinde ayarları ile backup yapmasını sağlayacak kodu nasıl yazacağım ve delphi'den bunu nasıl yapabileceğim hakkında bir yorumunuz var mı?
tekrar teşekkürler.

ertank
Üye
Mesajlar: 964
Kayıt: 11 Eyl 2015 11:45

Re: Calculated field gibi davranan bir field inşa etmek (MySQL)

Mesaj gönderen ertank » 26 Kas 2017 01:24

ShellAPI unitesi içindeki ShellExecute() fonksiyonunu inceleyebilirsiniz.

https://msdn.microsoft.com/en-us/librar ... s.85).aspx

fatihbarut
Üye
Mesajlar: 368
Kayıt: 15 Ara 2011 08:02

Re: Calculated field gibi davranan bir field inşa etmek (MySQL)

Mesaj gönderen fatihbarut » 26 Kas 2017 01:43

Aslına bakarsanız mysqldump'ın 50 den fazla option'ı var. Bu sebeple belki deneyimi olan vardır diye ilgili kod satırını paylaşabilen var mı diye sordum.

https://dev.mysql.com/doc/refman/5.7/en ... erformance

ertank
Üye
Mesajlar: 964
Kayıt: 11 Eyl 2015 11:45

Re: Calculated field gibi davranan bir field inşa etmek (MySQL)

Mesaj gönderen ertank » 26 Kas 2017 01:47

https://stackoverflow.com/questions/134 ... mmand-line
http://www.mediacollege.com/computer/da ... ackup.html
http://www.thegeekstuff.com/2008/09/bac ... mysqldump/
https://meta.wikimedia.org/wiki/Databas ... e_examples

Benim gördüğüm kadarıyla parametreler özel durumlarda kullanılıyor ve genel kullanım şekli aşağıdaki gibi:

Kod: Tümünü seç

mysqldump  -u[username] -p[password] databasename > databasefilename.sql

fatihbarut
Üye
Mesajlar: 368
Kayıt: 15 Ara 2011 08:02

Re: Calculated field gibi davranan bir field inşa etmek (MySQL)

Mesaj gönderen fatihbarut » 26 Kas 2017 02:47

teşekkür ederim.
Sanırsam default değerler tüm trigerları tüm table ve viewları yedekle yönünde.
bi deneyip döneyim.

dipnot mysqldump da virtual alanları yedekleyemiyor bu versiyonda ki daha önceki bazılarında yedekliyormuş, bu koskoca firmalar nasıl bu kadar büyük hata yapar ben anlayamıyorum.

ertank
Üye
Mesajlar: 964
Kayıt: 11 Eyl 2015 11:45

Re: Calculated field gibi davranan bir field inşa etmek (MySQL)

Mesaj gönderen ertank » 26 Kas 2017 03:12

Virtual kolonlar çalışma zamanında sürekli hesaplanırlar. Tablo içinde kaydedilmezler. Bu sebeple yedek verisi içine kaydetmenin bir anlamı olmayabilir.
Bir istisnası VIRTUAL değil STORED şeklinde tanımlanmış kolonlar olabilir. Denemedim ancak belki STORED şeklindeki kolonlar yedek içine dahil ediliyor olabilir. Bu tür kolonlar çalışma zamanında hesaplanmayarak INSERT/UPDATE sırasında hesaplanır ve tabloya (disk üzerine) kaydedilir.

fatihbarut
Üye
Mesajlar: 368
Kayıt: 15 Ara 2011 08:02

Re: Calculated field gibi davranan bir field inşa etmek (MySQL)

Mesaj gönderen fatihbarut » 26 Kas 2017 03:27

stored u ben de denedim olmuyor.
Zaten virtual fieldlar için benim beklentim veriyi kaydetmesi değil aktarım sırasında hesap mekanizmasını tetiklemesiydi ama o normal aktarım yapmaya çalışıyor

Cevapla