Przeniesienie pracy na bazę danych – CSV i Triggery

Przepisanie danych między różnymi bazami w php.

Ostatnio trafiło mi się całkiem ciekawe zlecenie. Chodziło o przeniesienie pewnych danych z Systemu na bazie Oracle do innego na silniku Firebird. Rozwiązanie okazało się dość proste a zrobiłem to tak. Najpierw wyeksportowałem dane z Systemu ‘A’ do pliku CSV. Następnie z poziomu PHP za pośrednictwem sterownika PDO podłączyłem się do niej i w pętli wykonałem masowe UPDATE.
Jako, że pdo dla firebird na starcie jest niedostępny odblokowałem tą funkcjonalność z poziomu php.ini.
Po upewnieniu się, że biblioteczka php_pdo_firebird.dll znajduje się na serwerze zmieniłem wpis z

#extension=php_pdo_firebird.dll

na

 extension=php_pdo_firebird.dll

. Później jeszcze restart serwera i można było już z niej sobie korzystać.
Oto listing programu wykonujący zadanie przepisu danych do bazy ‘B’:

  

 abstract class Operations {

            private $_filePath;

            protected function __construct() {
                $this->_filePath = 'FILE_WITH_DATA.csv';
            }

            protected function getDataFromFile() {
                $file = new SplFileObject($this->_filePath);

                while (!$file->eof()) {
                    $aData[] = $file->fgetcsv();
                }

                return $aData;
            }

        }

        class DBOperation extends Operations {

            private $dbh;

            public function __construct() {

                parent::__construct();

                try {
                    $str_conn = "firebird:host=localhost; dbname=PATH_TO_DB_FILE=UTF8";
                    $this->dbh = new PDO($str_conn, "USER", "PASSWORD");
                } catch (PDOException $err) {
                    die($err->getMessage());
                }
            }

            public function updateDb() {
                $aData = $this->getDataFromFile();
                $count = 0;

                foreach ($aData as $val) {
                    $this->dbh->exec("UPDATE TABLE_NAME SET client_nr= '{$val[0]}' WHERE PESEL = '{$val[1]}'");
                    $count++;
                }

                return $count;
            }

            public function displaySolutions() {
                $aData = $this->getDataFromFile();
                $count = 0;

                foreach ($aData as $val) {

                    $result = $this->dbh->query("SELECT * FROM TABLE_NAME WHERE PESEL = '{$val[1]}'");

                    while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
                        echo "Pesel: " . $row['PESEL'] . " Nr klienta: " . $row['client_nr'];
                        $count++;
                    }
                }

                return $count;
            }

            public function __destruct() {
                echo 'Operation Successfull';
                $this->dbh = null;
            }

        }

        $test = new DBOperation();
        echo "{$test->updateDb()} records updated.";

        echo "============ = SPRAWDZENIE============ = ";
        $results = $test->displaySolutions();
        $test = null;
        echo "W BAZIE ISTNIEJE: {$results}";

 

Przeniesienie pracy na bazę danych.

Jak się później okazało rekordy, które znalazły się nowej bazie danych powinny być jeszcze obsługiwane w specyficzny sposób, którego nie oferuje standardowa funkcjonalność programu.
Zadanie polegało na auto zwiększaniu zaimportowanego numeru klienta w bazie B, który w dodatku był VARCHAR-em.
Jako, że dostęp do kodu programu był niemożliwy (miałem tylko wersję skompilowaną) pozostało mi się załamać lub znaleźć inne rozwiązanie :).
W tej sytuacji zdecydowałem dodać prosty trigger do bazy B.
Jeśli nie wiesz czym są triggery zachęcam do zapoznania się z tym tematem. Materiałów w google jest o nich wiele. W skrócie tylko powiem, że trigger to zestaw instrukcji bazodanowych wywołujących się automatycznie w reakcji na jakieś zdarzenie. U mnie takim zdarzeniem było dodawanie nowego klienta do bazy. Gdy ten został dopisany odpalał się trigger, który wykonywał zadanie rozpoznawania największego nr. klienta z wśród istniejących w bazie, zwiększał go o 1 i updatował pole właśnie wstawionego rekordu.
Oto listing triggera:

DELIMITER //

create or alter trigger TRIGGERA_NAME for TABLE_NAME
	active after insert position 0
AS
BEGIN
 UPDATE TABLE_NAME SET CLIENT_NR  =
        (select (MAX(CAST(client_nr as INTEGER)) + 1) as client_nr from TABLE_NAME where CLIENT_NR != '') 
 WHERE OSO_AD_ID = 
	(SELECT GEN_ID( SEQUENCE_FOR_TABLE, 0) FROM RDB$DATABASE);
END


DELIMITER ;

Taki trigger można w dowolnej chwili zdjąć wywołując polecenie:

DROP trigger NAZWA_TRIGGERA

Autor: Piotr Kaczorowski – Strony internetowe Gdańsk

Kontakt :

Creative Technology

Piotr Kaczorowski

Władysława Broniewskiego 3c/15

80-524 Gdańsk


    Pola oznaczone * są wymagane.

    Wyrażam zgodę na cookie. Więcej informacji.

    Nasza strona internetowa używa plików cookies (tzw. ciasteczka) w celach statystycznych, reklamowych oraz funkcjonalnych. Dzięki nim możemy indywidualnie dostosować stronę do twoich potrzeb. Każdy może zaakceptować pliki cookies albo ma możliwość wyłączenia ich w przeglądarce, dzięki czemu nie będą zbierane żadne informacje.

    Zamknij