Khả năng của MySQL để tạo các thói quen toàn cầu (các thủ tục được lưu trữ và / hoặc các chức năng)


8

Có thể bằng cách nào đó xác định các thói quen có sẵn trên toàn cầu? Có vẻ như mọi thói quen phải được tạo trong một phạm vi của cơ sở dữ liệu.

Khi tôi cố gắng tạo một thói quen từ bảng điều khiển (không phát hành trước use dbname), tôi gặp lỗi:

ERROR 1046 (3D000): No database selected

Chúng tôi có hàng tấn cơ sở dữ liệu giống hệt nhau (dữ liệu là khác nhau) và mục tiêu là tạo ra một số kích hoạt cho một số tablenames. Nhưng chúng tôi chỉ muốn chạy một thói quen vì vậy chúng tôi không phải tạo các thói quen đó cho mọi cơ sở dữ liệu (vì chúng giống hệt nhau, các thói quen sẽ hoạt động giống nhau cho mỗi cơ sở dữ liệu).


Bạn có chắc chắn rằng bạn muốn tạo các kích hoạt trong mysql? đọc nó một bài báo ra tôi dba.stackexchange.com/questions/48797/...
Raymond Nijland

Câu trả lời:


14

Không có cách nào để xác định các thủ tục được lưu trữ hoặc các hàm được lưu trữ (hoặc các sự kiện) là toàn cục.

Một cách tiếp cận là tạo một lược đồ chung được chia sẻ và sau đó đủ điều kiện gọi các hàm và thủ tục với tên của lược đồ đó ( CALL shared.the_procedure();).

Đây là điều tôi làm với bộ sưu tập các hàm tính toán ngày / giờ tùy chỉnh của mình (ví dụ SELECT date_time.next_quarter_start_after(NOW()):) và với khung common_schema cực kỳ tiện dụng , tất nhiên, nằm trong `common_schema`.

Nếu bạn thực hiện phương pháp đó, bạn phải nhớ sau đó khi một thường trình đang chạy, cơ sở dữ liệu "hiện tại" sẽ tự động thay đổi và giá trị trả về của DATABASE()hàm trả về tên của lược đồ theo đó thường trình được xác định, không phải là cơ sở dữ liệu hiện tại của phiên của bạn . Nó thay đổi trở lại khi thói quen thoát ra, vì vậy nếu được sử dụng trong trình kích hoạt, nó sẽ không phá vỡ bất cứ thứ gì xung quanh nó nhưng bạn không có cách nào để biết từ bên trong thói quen cơ sở dữ liệu hiện tại là gì, nếu bạn cần biết.


+1 Các thủ tục được lưu trữ hoặc các chức năng được lưu trữ (hoặc các sự kiện) luôn được xác định trong cơ sở dữ liệu
Raymond Nijland

3

Chỉ cần mở rộng một chút theo câu trả lời của @ Michael, nhưng trong khi tham khảo một lược đồ chung là cách để đi, bạn có thể tạo "bí danh" trong cơ sở dữ liệu cục bộ để giúp việc này dễ quản lý hơn một chút.

Ví dụ: tôi đang làm việc với một công cụ phái sinh MySQL chưa có UUID_TO_BINchức năng của MySQL 8 , vì vậy tôi đã tạo riêng cho mình và lưu trữ nó trong cơ sở dữ liệu dành riêng cho các công cụ toàn cầu mà tôi đã gọi common. Vì vậy, để tham chiếu chức năng này, bây giờ tôi phải sử dụng common.UUID_TO_BINtrong tất cả các truy vấn và thủ tục được lưu trữ của mình. Không phải là một vấn đề lớn, nhưng không hoàn toàn dễ dàng như gọi đơn giản UUID_TO_BIN(như tôi sẽ làm nếu chức năng gốc có sẵn).

Vì vậy, những gì tôi đã làm cũng được thêm một "bí danh" vào mỗi cơ sở dữ liệu của mình như sau:

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);

Bằng cách này, trong mỗi cơ sở dữ liệu tôi thêm "bí danh" này, giờ đây tôi chỉ có thể gọi UUID_TO_BIN(some_uuid, TRUE)mà không cần thêm bất kỳ tên cơ sở dữ liệu nào, nhưng không gặp rắc rối khi sao chép toàn bộ chức năng, tức là - nếu tôi cần thay đổi hoặc tối ưu hóa chức năng vì một số lý do, tôi chỉ phải làm như vậy ở một nơi duy nhất ( common.UUID_TO_BIN) thay vì cập nhật mọi cơ sở dữ liệu.

Nếu sau này tôi nâng cấp lên cơ sở dữ liệu với bản địa, UUID_TO_BINtôi cũng có thể xóa tất cả các hàm "bí danh" của mình và tất cả các truy vấn và quy trình hiện có của tôi sẽ sử dụng nó mà không cần sửa đổi gì thêm. Hoặc nếu chức năng toàn cầu được chuyển đến một cơ sở dữ liệu khác, tôi chỉ phải cập nhật bí danh của mình, thay vì mỗi truy vấn sử dụng nó.

Tôi không chắc chắn MySQL thông minh như thế nào khi tối ưu hóa một chức năng chỉ đơn giản gọi một chức năng khác, do đó có thể có một chi phí nhỏ liên quan đến việc chuyển hướng nó theo cách này, nhưng tôi nghĩ rằng nó đáng để quản lý đơn giản hóa, trong khi chỉ giữ lại một định nghĩa "toàn cầu" duy nhất.


1

Một cách tiếp cận rất đơn giản là thế này:

  1. Đảm bảo rằng bạn có các biến và tham số chung sẽ được truyền cho một hàm nhất định.
  2. Và chỉ cần gọi hàm mà bạn đã thực hiện từ cơ sở dữ liệu khác. Ví dụ. select [databasename].empstatus(empid) as status;

Tập lệnh 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);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.