MySQLがグローバルルーチン(ストアドプロシージャや関数)を作成する可能性


8

どういうわけかグローバルに利用可能なルーチンを定義することは可能ですか?すべてのルーチンはデータベースのスコープ内で作成する必要があるようです。

(事前に発行せずにuse dbname)コンソールからルーチンを作成しようとすると、エラーが発生します。

ERROR 1046 (3D000): No database selected

同一のデータベースが大量にあり(データは異なります)、いくつかのテーブル名に対していくつかのトリガーを作成することが目標です。ただし、実行するルーチンは1つだけにしたいので、データベースごとにこれらのルーチンを作成する必要はありません(これらは同じなので、ルーチンは各データベースで同じように動作します)。


mysqlでトリガーを作成してもよろしいですか?鉱山オフの記事このにそれを読んdba.stackexchange.com/questions/48797/...
レイモンドNijland

回答:


14

グローバルなストアドプロシージャまたはストアドファンクション(またはイベント)を定義する方法はありません。

1つの方法は、共有の共通スキーマを作成し、そのスキーマの名前を使用して関数とプロシージャの呼び出しを修飾することです(CALL shared.the_procedure();)。

これは、カスタムの日付/時刻計算関数のコレクション(例:)と、もちろん、 `common_schema`に常駐SELECT date_time.next_quarter_start_after(NOW())する、これまでにない便利なcommon_schemaフレームワークで行うものです。

そのアプローチをとる場合、ルーチンが実行されると、「現在の」データベースが自動的に変更され、DATABASE()関数の戻り値は、セッションの現在のデータベースではなく、ルーチンが定義されたスキーマの名前を返すことに注意してください。 。ルーチンが終了すると元に戻ります。そのため、トリガーで使用しても、周囲を壊すことはありませんが、必要な場合に、ルーチン内から現在のデータベースが何であるかを知る方法がありません。


+1確かにストアドプロシージャまたはストアドファンクション(またはイベント)は常にデータベース内で定義されます
Raymond Nijland 2013

3

@Michaelの答えを少し拡張するだけですが、一般的なスキーマを参照する方法ですが、ローカルデータベースに「エイリアス」を作成して、これを少し管理しやすくすることができます。

たとえば、MySQL 8のUUID_TO_BIN機能をまだ備えていないMySQL派生物を使用しているので、自分で作成し、それを自分が呼び出したグローバルなもの専用のデータベースに保存しましたcommon。したがって、この関数を参照するにはcommon.UUID_TO_BIN、すべてのクエリとストアドプロシージャで使用する必要があります。大きな問題ではありませんが、単純に呼び出すほど簡単ではありませんUUID_TO_BIN(ネイティブ関数が使用可能である場合と同じです)。

だから私がやったことはまた、次のように私のデータベースのそれぞれに「エイリアス」を追加しています:

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

このようにして、各データベースにこの「エイリアス」をUUID_TO_BIN(some_uuid, TRUE)追加します。データベース名を追加せずに単純に呼び出すことができますが、関数全体を複製する手間がありません。つまり、何らかの理由で関数を変更または最適化する必要がある場合は、common.UUID_TO_BINすべてのデータベースを更新するのではなく、1か所()で行う必要があります。

後でネイティブUUID_TO_BINを使用してデータベースにアップグレードする場合、「エイリアス」関数をすべて削除するだけで、既存のすべてのクエリとプロシージャで、変更を加えなくても使用できるようになります。または、グローバル関数を別のデータベースに移動する場合は、それを使用するすべてのクエリではなく、エイリアスを更新するだけで済みます。

別の関数を呼び出すだけの関数を最適化する場合、MySQLがどれほど賢いかわからないので、このようにリダイレクトすることに関連して少しコストがかかる可能性がありますが、管理を簡素化するには価値があると思いますが、単一の「グローバル」定義のみを保持します。


1

非常に単純なアプローチはこれです:

  1. 特定の関数に渡される共通の変数とパラメーターがあることを確認してください。
  2. そして、他のデータベースから作成した関数を呼び出すだけです。例:select [databasename].empstatus(empid) as status;

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);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.