Kemungkinan MySQL untuk membuat rutinitas global (prosedur dan / atau fungsi yang tersimpan)

8

Apakah mungkin untuk mendefinisikan rutin yang tersedia secara global? Sepertinya setiap rutin harus dibuat dalam lingkup basis data.

Ketika saya mencoba membuat rutin dari konsol (tanpa mengeluarkan sebelumnya use dbname) saya mendapatkan kesalahan:

ERROR 1046 (3D000): No database selected

Kami memiliki banyak basis data yang identik (datanya berbeda) dan tujuannya adalah untuk menciptakan beberapa pemicu untuk beberapa nama tabel. Tetapi kami hanya ingin menjalankan satu rutin sehingga kami tidak harus membuat rutinitas tersebut untuk setiap database (karena identik, rutinitas akan bekerja sama untuk setiap database).

bakytn
sumber
Anda yakin ingin membuat pemicu di mysql? bacalah ini artikel dari tambang dba.stackexchange.com/questions/48797/…
Raymond Nijland

Jawaban:

14

Tidak ada cara untuk mendefinisikan prosedur tersimpan atau fungsi tersimpan (atau peristiwa) yang bersifat global.

Salah satu pendekatan adalah membuat skema bersama bersama dan kemudian memenuhi syarat panggilan ke fungsi dan prosedur dengan nama skema itu ( CALL shared.the_procedure();).

Ini adalah sesuatu yang saya lakukan dengan koleksi saya fungsi perhitungan tanggal / waktu kustom (misalnya, SELECT date_time.next_quarter_start_after(NOW())), dan dengan kerangka common_schema yang selalu berguna , yang, tentu saja, tinggal di `common_schema`.

Jika Anda mengambil pendekatan itu, Anda harus mengingatnya ketika suatu rutinitas sedang berjalan, database "saat ini" secara otomatis berubah, dan nilai balik DATABASE()fungsi mengembalikan nama skema di mana rutin didefinisikan, bukan basis data sesi Anda saat ini. . Itu berubah kembali ketika rutin keluar, jadi jika digunakan dalam pemicu, itu tidak merusak apa pun di sekitarnya tetapi Anda tidak memiliki cara untuk mengetahui dari dalam rutin apa database saat ini, jika Anda perlu tahu.

Michael - sqlbot
sumber
+1 Memang prosedur tersimpan atau fungsi tersimpan (atau acara) selalu ditentukan dalam database
Raymond Nijland
3

Hanya untuk memperluas sedikit pada jawaban @ Michael, tetapi sementara referensi skema umum adalah cara untuk pergi, Anda dapat membuat "alias" di database lokal untuk membuat ini sedikit lebih mudah untuk dikelola.

Sebagai contoh, saya bekerja dengan turunan MySQL yang belum memiliki UUID_TO_BINfungsi MySQL 8 , jadi saya membuatnya sendiri, dan menyimpannya dalam database khusus untuk hal-hal global yang saya panggil common. Jadi untuk referensi fungsi ini, saya sekarang harus menggunakan common.UUID_TO_BINsemua pertanyaan dan prosedur tersimpan saya. Bukan masalah besar, tetapi tidak semudah hanya memanggil UUID_TO_BIN(seperti yang saya lakukan jika fungsi asli tersedia).

Jadi yang saya lakukan juga menambahkan "alias" ke masing-masing basis data saya seperti:

CREATE FUNCTION `UUID_TO_BIN`(a_uuid CHAR(36), a_reorder BOOL) RETURNS binary(16)
    DETERMINISTIC
RETURN `common`.UUID_TO_BIN(a_uuid, a_reorder);

Dengan cara ini, di setiap basis data saya menambahkan "alias" ini. Saya sekarang dapat dengan mudah memanggil UUID_TO_BIN(some_uuid, TRUE)tanpa menambahkan nama basis data, tetapi tanpa kerumitan menduplikasi seluruh fungsi, yaitu - jika saya perlu mengubah atau mengoptimalkan fungsi untuk beberapa alasan, saya hanya harus melakukannya di satu tempat ( common.UUID_TO_BIN) daripada memperbarui setiap basis data tunggal.

Jika nanti saya memutakhirkan ke database dengan yang asli UUID_TO_BINsaya juga bisa menghapus semua fungsi "alias" saya dan semua pertanyaan dan prosedur saya yang ada sekarang akan menggunakannya tanpa modifikasi lebih lanjut. Atau jika fungsi global dipindahkan ke database yang berbeda, saya hanya perlu memperbarui alias saya, daripada setiap pertanyaan saya yang menggunakannya.

Saya tidak yakin seberapa pintar MySQL dalam hal mengoptimalkan fungsi yang hanya memanggil fungsi lain, jadi mungkin ada sedikit biaya yang terkait dengan mengarahkan ulang dengan cara ini, tapi saya pikir itu layak untuk manajemen yang disederhanakan, sementara hanya mempertahankan satu definisi "global".

Haravikk
sumber
1

Pendekatan yang sangat sederhana adalah ini:

  1. Pastikan Anda memiliki variabel dan parameter umum yang akan diteruskan ke fungsi tertentu.
  2. Dan cukup panggil fungsi yang telah Anda buat dari basis data lain. ex. select [databasename].empstatus(empid) as status;

Script PHP:

$empid=trim($_REQUEST['empid']);
$conn=mysqli_connect($db_host, $db_user, $db_pass, $db_name);
$sqld="SELECT [otherdatabasename].empstatus('$empid') as employee_status";
$rs=mysqli_query($conn,$sqld);
$rw= mysqli_fetch_array($rs);
Mactamps Brown
sumber