3

ストアドプロシージャを使用するクライアントのクエリを作成しました。ユーザーにデータベースへの書き込みアクセスを許可できないため、プロシージャを保存できません。ストアドプロシージャを使用せずに機能を維持するために、ストアドプロシージャをクエリ内で無名関数に変換できますか?

$establishFunction = mysql_query("DROP FUNCTION IF EXISTS fn_distance_cosine;
CREATE FUNCTION fn_distance_cosine (
    latitude_1 DOUBLE,
    longitude_1 DOUBLE,
    latitude_2 DOUBLE,
    longitude_2 DOUBLE
)
RETURNS DOUBLE
DETERMINISTIC
SQL SECURITY INVOKER
RETURN ACOS(
      SIN(RADIANS(latitude_1)) * SIN(RADIANS(latitude_2))
      + COS(RADIANS(latitude_1)) * COS(RADIANS(latitude_2))
      * COS(RADIANS(longitude_2 - longitude_1))
    ) * 3956.547;
");

mysql_query("SET @input_lat :=" . $lat . ";");
mysql_query("SET @input_lon :=" . $lon . ";");

mysql_query("SET @max_latitude := @input_lat + DEGREES(50.0/3956.547);");
mysql_query("SET @min_latitude := @input_lat - DEGREES(50.0/3956.547);");
mysql_query("SET @max_longitude := @input_lon + DEGREES(50.0/3956.547/COS(RADIANS(@input_lat)));");
mysql_query("SET @min_longitude := @input_lon - DEGREES(50.0/3956.547/COS(RADIANS(@input_lat)));");

if($result = mysql_query("SELECT
      *,
      fn_distance_cosine(lat, lon, @input_lat, @input_lon) AS distance_in_miles,
      COUNT(*) AS store_number_count
    FROM stores
    JOIN items_stores
    ON stores.store_number=items_stores.store_number
    WHERE `lat` BETWEEN @min_latitude AND @max_latitude
      AND `lon` BETWEEN @min_longitude AND @max_longitude
    GROUP BY stores.store_code
    HAVING store_code_count > 1
    ORDER BY distance_in_miles
    LIMIT 10;
    ")){  
        while ($r = mysql_fetch_assoc($result)){
        $rows[] = $r;
    }
}else{
    //failed.
    echo (mysql_error ());
}

print json_encode($rows);
4

3 に答える 3

3

ストアドプロシージャを実行できない場合は、そのセキュリティ権限も持たないため、関数も実行できない可能性があります。

オプション#1-独自のDBAにSQLステートメントを検証させてから、ストアドプロシージャを格納するためにデータベースに変更を加えます。

オプション#2-他のオプションは、そのコードをデータベースからPHPに移動することです。そうです、それをPHPに移動することはできますが、データベースエンジンに移動させるほど高速でも効率的でもありません。

于 2012-09-24T18:48:28.307 に答える
2

いいえ、匿名関数を持つことはできません。クライアントがこの関数を追加するための適切なアクセス許可を付与できない場合、なぜクライアントは関数を作成するように要求したのでしょうか。DBユーザーアカウントで関数をインストールできない場合は、SQLに基づいてこの関数を作成できる適切なユーザーアカウントを持っている人がいることを確認してください。

また、なぜストアドプロシージャの代わりに関数なのですか?次のように、実行しているすべてのロジックを1回の呼び出しで複数のDBクエリに配置できます。

call give_me_my_data(lat, long)

必要なデータを取得するために、dbベースのロジックとphpベースのロジック(多くの不要なクエリを含む)を使用して、クリーンアップするストアドプロシージャを定義するのではなく、奇妙に思えます。単一のクエリのみを作成するPHPコード。

于 2012-09-24T18:55:16.570 に答える
0

同じmysqlサーバーで別のデータベースを取得できますか?次に、そこでプロシージャを宣言し、データベース名を明示的にプレフィックスとして付けることで、クエリでそれを使用できる場合があります。それが実際に機能するかどうかは完全にはわかりませんが、機能すると思います。

于 2012-09-24T18:53:17.687 に答える