Perl - Akses Database

Bab ini mengajarkan Anda cara mengakses database di dalam skrip Perl Anda. Mulai dari Perl 5 menjadi sangat mudah untuk menulis aplikasi database menggunakanDBImodul. DBI adalah singkatan dariDatabase Independent Interface untuk Perl, yang berarti DBI menyediakan lapisan abstraksi antara kode Perl dan database yang mendasarinya, memungkinkan Anda untuk mengganti implementasi database dengan sangat mudah.

DBI adalah modul akses database untuk bahasa pemrograman Perl. Ini menyediakan satu set metode, variabel, dan konvensi yang menyediakan antarmuka database yang konsisten, tidak tergantung pada database aktual yang digunakan.

Arsitektur Aplikasi DBI

DBI tidak bergantung pada database apa pun yang tersedia di backend. Anda dapat menggunakan DBI apakah Anda bekerja dengan Oracle, MySQL atau Informix, dll. Ini terlihat jelas dari diagram architure berikut.

Di sini DBI bertanggung jawab untuk mengambil semua perintah SQL melalui API, (yaitu, Application Programming Interface) dan mengirimkannya ke driver yang sesuai untuk eksekusi sebenarnya. Dan terakhir, DBI bertanggung jawab mengambil hasil dari pengemudi dan mengembalikannya ke scritp yang menelepon.

Notasi dan Konvensi

Di sepanjang bab ini, notasi berikut akan digunakan dan Anda disarankan untuk mengikuti ketentuan yang sama.

$dsn    Database source name
$dbh    Database handle object
$sth    Statement handle object
$h      Any of the handle types above ($dbh, $sth, or $drh)
$rc     General Return Code  (boolean: true=ok, false=error)
$rv     General Return Value (typically an integer)
@ary    List of values returned from the database.
$rows   Number of rows processed (if available, else -1)
$fh     A filehandle
undef   NULL values are represented by undefined values in Perl
\%attr  Reference to a hash of attribute values passed to methods

Koneksi Database

Dengan asumsi kita akan bekerja dengan database MySQL. Sebelum menghubungkan ke database, pastikan hal-hal berikut ini. Anda dapat mengambil bantuan tutorial MySQL kami jika Anda tidak tahu tentang cara membuat database dan tabel di database MySQL.

  • Anda telah membuat database dengan nama TESTDB.

  • Anda telah membuat tabel dengan nama TEST_TABLE di TESTDB.

  • Tabel ini memiliki bidang FIRST_NAME, LAST_NAME, AGE, SEX dan INCOME.

  • ID pengguna "testuser" dan kata sandi "test123" disetel untuk mengakses TESTDB.

  • Perl Module DBI diinstal dengan benar di komputer Anda.

  • Anda telah melalui tutorial MySQL untuk memahami Dasar-Dasar MySQL.

Berikut adalah contoh koneksi dengan database MySQL "TESTDB" -

#!/usr/bin/perl

use DBI
use strict;

my $driver = "mysql"; 
my $database = "TESTDB";
my $dsn = "DBI:$driver:database=$database";
my $userid = "testuser";
my $password = "test123";

my $dbh = DBI->connect($dsn, $userid, $password ) or die $DBI::errstr;

Jika koneksi dibuat dengan sumber data, maka Database Handle dikembalikan dan disimpan ke $ dbh untuk digunakan lebih lanjut jika tidak $ dbh disetel ke nilai undef dan $ DBI :: errstr mengembalikan string kesalahan.

Operasi INSERT

Operasi INSERT diperlukan saat Anda ingin membuat beberapa record ke dalam tabel. Di sini kami menggunakan tabel TEST_TABLE untuk membuat catatan kami. Jadi setelah koneksi database kita dibuat, kita siap untuk membuat record ke TEST_TABLE. Berikut adalah prosedur untuk membuat satu record ke TEST_TABLE. Anda dapat membuat rekaman sebanyak yang Anda suka menggunakan konsep yang sama.

Pembuatan rekaman mengambil langkah-langkah berikut -

  • Mempersiapkan pernyataan SQL dengan pernyataan INSERT. Ini akan dilakukan dengan menggunakanprepare() API.

  • Menjalankan kueri SQL untuk memilih semua hasil dari database. Ini akan dilakukan dengan menggunakanexecute() API.

  • Melepaskan gagang Stattement. Ini akan dilakukan dengan menggunakanfinish() API.

  • Jika semuanya baik-baik saja commit operasi ini jika tidak, Anda bisa rollbackselesaikan transaksi. Commit dan Rollback dijelaskan di bagian selanjutnya.

my $sth = $dbh->prepare("INSERT INTO TEST_TABLE
                       (FIRST_NAME, LAST_NAME, SEX, AGE, INCOME )
                         values
                       ('john', 'poul', 'M', 30, 13000)");
$sth->execute() or die $DBI::errstr;
$sth->finish();
$dbh->commit or die $DBI::errstr;

Menggunakan Bind Values

Mungkin ada kasus ketika nilai yang akan dimasukkan tidak diberikan sebelumnya. Jadi, Anda dapat menggunakan variabel bind yang akan mengambil nilai yang diperlukan pada waktu proses. Modul Perl DBI menggunakan tanda tanya sebagai pengganti nilai aktual dan kemudian nilai aktual diteruskan melalui API eksekusi () pada saat dijalankan. Berikut contohnya -

my $first_name = "john";
my $last_name = "poul";
my $sex = "M";
my $income = 13000;
my $age = 30;
my $sth = $dbh->prepare("INSERT INTO TEST_TABLE
                        (FIRST_NAME, LAST_NAME, SEX, AGE, INCOME )
                          values
                        (?,?,?,?)");
$sth->execute($first_name,$last_name,$sex, $age, $income) 
          or die $DBI::errstr;
$sth->finish();
$dbh->commit or die $DBI::errstr;

BACA Operasi

Operasi BACA pada database berarti mengambil beberapa informasi yang berguna dari database, misalnya, satu atau lebih catatan dari satu atau lebih tabel. Jadi, setelah koneksi database kami dibuat, kami siap untuk membuat kueri ke dalam database ini. Berikut adalah prosedur untuk menanyakan semua record yang memiliki AGE lebih dari 20. Ini akan mengambil empat langkah -

  • Mempersiapkan kueri SQL SELECT berdasarkan kondisi yang diperlukan. Ini akan dilakukan dengan menggunakanprepare() API.

  • Menjalankan kueri SQL untuk memilih semua hasil dari database. Ini akan dilakukan dengan menggunakanexecute() API.

  • Mengambil semua hasil satu per satu dan mencetak hasil tersebut. Ini akan dilakukan dengan fetchrow_array() API.

  • Melepaskan gagang Stattement. Ini akan dilakukan dengan menggunakanfinish() API.

my $sth = $dbh->prepare("SELECT FIRST_NAME, LAST_NAME
                        FROM TEST_TABLE 
                        WHERE AGE > 20");
$sth->execute() or die $DBI::errstr;
print "Number of rows found :" + $sth->rows;
while (my @row = $sth->fetchrow_array()) {
   my ($first_name, $last_name ) = @row;
   print "First Name = $first_name, Last Name = $last_name\n";
}
$sth->finish();

Menggunakan Bind Values

Mungkin ada kasus ketika kondisi tidak diberikan sebelumnya. Jadi, Anda dapat menggunakan variabel bind, yang akan mengambil nilai yang diperlukan pada waktu proses. Modul Perl DBI menggunakan tanda tanya sebagai pengganti nilai aktual dan kemudian nilai aktual diteruskan melalui API eksekusi () pada saat dijalankan. Berikut contohnya -

$age = 20;
my $sth = $dbh->prepare("SELECT FIRST_NAME, LAST_NAME
                        FROM TEST_TABLE
                        WHERE AGE > ?");
$sth->execute( $age ) or die $DBI::errstr;
print "Number of rows found :" + $sth->rows;
while (my @row = $sth->fetchrow_array()) {
   my ($first_name, $last_name ) = @row;
   print "First Name = $first_name, Last Name = $last_name\n";
}
$sth->finish();

UPDATE Operasi

UPDATE Operasi pada database apa pun berarti memperbarui satu atau lebih rekaman yang sudah tersedia di tabel database. Berikut adalah prosedur untuk memperbarui semua record yang memiliki SEX sebagai 'M'. Di sini kami akan meningkatkan AGE semua pria satu tahun. Ini akan mengambil tiga langkah -

  • Mempersiapkan kueri SQL berdasarkan kondisi yang diperlukan. Ini akan dilakukan dengan menggunakanprepare() API.

  • Menjalankan kueri SQL untuk memilih semua hasil dari database. Ini akan dilakukan dengan menggunakanexecute() API.

  • Melepaskan gagang Stattement. Ini akan dilakukan dengan menggunakanfinish() API.

  • Jika semuanya baik-baik saja commit operasi ini jika tidak, Anda bisa rollbackselesaikan transaksi. Lihat bagian selanjutnya untuk commit dan rollback API.

my $sth = $dbh->prepare("UPDATE TEST_TABLE
                        SET   AGE = AGE + 1 
                        WHERE SEX = 'M'");
$sth->execute() or die $DBI::errstr;
print "Number of rows updated :" + $sth->rows;
$sth->finish();
$dbh->commit or die $DBI::errstr;

Menggunakan Bind Values

Mungkin ada kasus ketika kondisi tidak diberikan sebelumnya. Jadi, Anda dapat menggunakan variabel bind, yang akan mengambil nilai yang diperlukan pada waktu proses. Modul Perl DBI menggunakan tanda tanya sebagai pengganti nilai aktual dan kemudian nilai aktual diteruskan melalui API eksekusi () pada saat dijalankan. Berikut contohnya -

$sex = 'M';
my $sth = $dbh->prepare("UPDATE TEST_TABLE
                        SET   AGE = AGE + 1
                        WHERE SEX = ?");
$sth->execute('$sex') or die $DBI::errstr;
print "Number of rows updated :" + $sth->rows;
$sth->finish();
$dbh->commit or die $DBI::errstr;

Dalam beberapa kasus Anda ingin menyetel nilai, yang tidak diberikan sebelumnya sehingga Anda dapat menggunakan nilai penjilidan sebagai berikut. Dalam contoh ini, pendapatan semua pria akan ditetapkan menjadi 10.000.

$sex = 'M';
$income = 10000;
my $sth = $dbh->prepare("UPDATE TEST_TABLE
                        SET   INCOME = ?
                        WHERE SEX = ?");
$sth->execute( $income, '$sex') or die $DBI::errstr;
print "Number of rows updated :" + $sth->rows;
$sth->finish();

HAPUS Operasi

Operasi HAPUS diperlukan saat Anda ingin menghapus beberapa rekaman dari database Anda. Berikut adalah prosedur untuk menghapus semua catatan dari TEST_TABLE dimana AGE sama dengan 30. Operasi ini akan mengambil langkah-langkah berikut.

  • Mempersiapkan kueri SQL berdasarkan kondisi yang diperlukan. Ini akan dilakukan dengan menggunakanprepare() API.

  • Menjalankan kueri SQL untuk menghapus rekaman yang diperlukan dari database. Ini akan dilakukan dengan menggunakanexecute() API.

  • Melepaskan gagang Stattement. Ini akan dilakukan dengan menggunakanfinish() API.

  • Jika semuanya baik-baik saja commit operasi ini jika tidak, Anda bisa rollback selesaikan transaksi.

$age = 30;
my $sth = $dbh->prepare("DELETE FROM TEST_TABLE
                         WHERE AGE = ?");
$sth->execute( $age ) or die $DBI::errstr;
print "Number of rows deleted :" + $sth->rows;
$sth->finish();
$dbh->commit or die $DBI::errstr;

Menggunakan do Statement

Jika Anda melakukan UPDATE, INSERT, atau DELETE, tidak ada data yang keluar dari database, jadi ada jalan pintas untuk melakukan operasi ini. Kamu dapat memakaido pernyataan untuk menjalankan salah satu perintah sebagai berikut.

$dbh->do('DELETE FROM TEST_TABLE WHERE age =30');

domengembalikan nilai benar jika berhasil, dan nilai salah jika gagal. Sebenarnya, jika berhasil mengembalikan jumlah baris yang terpengaruh. Dalam contoh ini akan mengembalikan jumlah baris yang benar-benar dihapus.

Operasi COMMIT

Komit adalah operasi yang memberikan sinyal hijau ke database untuk menyelesaikan perubahan dan setelah operasi ini tidak ada perubahan yang dapat dikembalikan ke posisi aslinya.

Berikut adalah contoh sederhana untuk menelepon commit API.

$dbh->commit or die $dbh->errstr;

Operasi ROLLBACK

Jika Anda tidak puas dengan semua perubahan atau Anda menemukan kesalahan di antara operasi apa pun, Anda dapat mengembalikan perubahan tersebut untuk digunakan rollback API.

Berikut adalah contoh sederhana untuk menelepon rollback API.

$dbh->rollback or die $dbh->errstr;

Mulailah Transaksi

Banyak database mendukung transaksi. Ini berarti Anda dapat membuat sejumlah besar kueri yang akan mengubah database, tetapi tidak ada perubahan yang benar-benar dibuat. Kemudian pada akhirnya, Anda mengeluarkan kueri SQL khususCOMMIT, dan semua perubahan dilakukan secara bersamaan. Atau, Anda dapat mengeluarkan kueri ROLLBACK, dalam hal ini semua perubahan dibuang dan database tetap tidak berubah.

Modul Perl DBI disediakan begin_workAPI, yang memungkinkan transaksi (dengan mematikan AutoCommit) hingga panggilan berikutnya untuk melakukan atau memutar balik. Setelah commit atau rollback berikutnya, AutoCommit akan secara otomatis dihidupkan lagi.

$rc  = $dbh->begin_work  or die $dbh->errstr;

Opsi AutoCommit

Jika transaksi Anda sederhana, Anda dapat menghindari masalah karena harus mengeluarkan banyak komitmen. Saat Anda membuat panggilan terhubung, Anda dapat menentukanAutoCommitopsi yang akan melakukan operasi komit otomatis setelah setiap kueri berhasil. Ini tampilannya -

my $dbh = DBI->connect($dsn, $userid, $password,
              {AutoCommit => 1}) 
              or die $DBI::errstr;

Di sini AutoCommit dapat mengambil nilai 1 atau 0, di mana 1 berarti AutoCommit aktif dan 0 berarti AutoCommit tidak aktif.

Penanganan Kesalahan Otomatis

Saat Anda melakukan panggilan koneksi, Anda dapat menentukan opsi RaiseErrors yang menangani kesalahan untuk Anda secara otomatis. Ketika terjadi kesalahan, DBI akan membatalkan program Anda alih-alih mengembalikan kode kegagalan. Jika yang Anda inginkan hanyalah membatalkan program karena kesalahan, ini bisa menjadi cara yang nyaman. Ini tampilannya -

my $dbh = DBI->connect($dsn, $userid, $password,
              {RaiseError => 1})
              or die $DBI::errstr;

Di sini RaiseError dapat mengambil nilai 1 atau 0.

Memutus Database

Untuk memutuskan koneksi database, gunakan disconnect API sebagai berikut -

$rc = $dbh->disconnect  or warn $dbh->errstr;

Sayangnya, perilaku transaksi metode putuskan sambungan tidak ditentukan. Beberapa sistem database (seperti Oracle dan Ingres) akan secara otomatis melakukan perubahan yang luar biasa, tetapi yang lain (seperti Informix) akan membatalkan perubahan yang luar biasa. Aplikasi yang tidak menggunakan AutoCommit harus secara eksplisit memanggil commit atau rollback sebelum memanggil putuskan.

Menggunakan Nilai NULL

Nilai yang tidak ditentukan, atau undef, digunakan untuk menunjukkan nilai NULL. Anda dapat memasukkan dan memperbarui kolom dengan nilai NULL seperti yang Anda lakukan dengan nilai non-NULL. Contoh ini memasukkan dan memperbarui usia kolom dengan nilai NULL -

$sth = $dbh->prepare(qq {
         INSERT INTO TEST_TABLE (FIRST_NAME, AGE) VALUES (?, ?)
       });
$sth->execute("Joe", undef);

Sini qq{} digunakan untuk mengembalikan string yang dikutip ke prepareAPI. Namun, kehati-hatian harus dilakukan saat mencoba menggunakan nilai NULL dalam klausa WHERE. Pertimbangkan -

SELECT FIRST_NAME FROM TEST_TABLE WHERE age = ?

Mengikat undef (NULL) ke placeholder tidak akan memilih baris, yang memiliki usia NULL! Setidaknya untuk mesin database yang sesuai dengan standar SQL. Lihat manual SQL untuk mesin database Anda atau buku SQL apa pun untuk alasannya. Untuk memilih NULL secara eksplisit, Anda harus mengatakan "WHERE age IS NULL".

Masalah umum adalah memiliki fragmen kode yang menangani nilai yang dapat didefinisikan atau undef (non-NULL atau NULL) pada waktu proses. Teknik sederhana adalah menyiapkan pernyataan yang sesuai sesuai kebutuhan, dan mengganti placeholder untuk kasus non-NULL -

$sql_clause = defined $age? "age = ?" : "age IS NULL";
$sth = $dbh->prepare(qq {
         SELECT FIRST_NAME FROM TEST_TABLE WHERE $sql_clause
       });
$sth->execute(defined $age ? $age : ());

Beberapa Fungsi DBI Lainnya

available_drivers

@ary = DBI->available_drivers;
@ary = DBI->available_drivers($quiet);

Menampilkan daftar semua driver yang tersedia dengan mencari modul DBD :: * melalui direktori di @INC. Secara default, peringatan diberikan jika beberapa driver disembunyikan oleh orang lain dengan nama yang sama di direktori sebelumnya. Meneruskan nilai sebenarnya untuk $ tenang akan menghambat peringatan.

install_drivers

%drivers = DBI->installed_drivers();

Menampilkan daftar nama driver dan pasangan pegangan driver untuk semua driver yang 'diinstal' (dimuat) ke dalam proses saat ini. Nama driver tidak menyertakan awalan 'DBD ::'.

sumber data

@ary = DBI->data_sources($driver);

Menampilkan daftar sumber data (database) yang tersedia melalui driver bernama. Jika $ driver kosong atau undef, maka nilai variabel lingkungan DBI_DRIVER digunakan.

kutipan

$sql = $dbh->quote($value);
$sql = $dbh->quote($value, $data_type);

Kutip literal string untuk digunakan sebagai nilai literal dalam pernyataan SQL, dengan mengosongkan karakter khusus apa pun (seperti tanda kutip) yang ada di dalam string dan menambahkan jenis tanda kutip luar yang diperlukan.

$sql = sprintf "SELECT foo FROM bar WHERE baz = %s",
                $dbh->quote("Don't");

Untuk sebagian besar tipe database, kutipan akan mengembalikan 'Jangan' (termasuk tanda kutip luar). Ini valid untuk metode quote () untuk mengembalikan ekspresi SQL yang mengevaluasi ke string yang diinginkan. Misalnya -

$quoted = $dbh->quote("one\ntwo\0three")

may produce results which will be equivalent to

CONCAT('one', CHAR(12), 'two', CHAR(0), 'three')

Metode Umum untuk Semua Pegangan

berbuat salah

$rv = $h->err;
or
$rv = $DBI::err
or
$rv = $h->err

Mengembalikan kode kesalahan mesin database asli dari metode driver terakhir yang dipanggil. Kode biasanya berupa bilangan bulat tetapi Anda tidak boleh berasumsi seperti itu. Ini sama dengan $ DBI :: err atau $ h-> err.

errstr

$str = $h->errstr;
or
$str = $DBI::errstr
or
$str = $h->errstr

Menampilkan pesan kesalahan mesin database asli dari metode DBI terakhir yang dipanggil. Ini memiliki masalah masa pakai yang sama dengan metode "err" yang dijelaskan di atas. Ini sama dengan $ DBI :: errstr atau $ h-> errstr.

baris

$rv = $h->rows;
or
$rv = $DBI::rows

Ini mengembalikan jumlah baris yang dipengaruhi oleh pernyataan SQL sebelumnya dan setara dengan $ DBI :: baris.

jejak

$h->trace($trace_settings);

DBI memiliki kemampuan yang sangat berguna untuk menghasilkan informasi penelusuran runtime dari apa yang dilakukannya, yang dapat menjadi penghemat waktu yang sangat besar saat mencoba melacak masalah aneh dalam program DBI Anda. Anda dapat menggunakan nilai yang berbeda untuk menyetel tingkat jejak. Nilai ini bervariasi dari 0 hingga 4. Nilai 0 berarti menonaktifkan jejak dan 4 berarti menghasilkan jejak lengkap.

Dilarang Pernyataan Interpolasi

Sangat disarankan untuk tidak menggunakan pernyataan interpolasi sebagai berikut -

while ($first_name = <>) {
   my $sth = $dbh->prepare("SELECT * 
                          FROM TEST_TABLE 
                          WHERE FIRST_NAME = '$first_name'");
   $sth->execute();
   # and so on ...
}

Jadi jangan gunakan pernyataan interpolasi sebagai gantinya gunakan bind value untuk menyiapkan pernyataan SQL dinamis.