sql >> データベース >  >> RDS >> Mysql

カスタムMySQL関数を作成しますか?

    アプリケーションでこのMySQL関数を宣言すると、データベースサーバーが再起動されるまでデータベースに残ります。

    mysql_query("CREATE FUNCTION Distance(LAT_A INT, LON_A INT, LAT_B INT, LON_B INT, )
    RETURNS INT
    READS SQL DATA
    DETERMINISTIC
    BEGIN
    DECLARE radius, deltaLat, deltaLon, result, distance BIGINT;
    SET radius=3956;
    SET deltaLat=LAT_B-LAT_A;
    SET deltaLon=LON_B-LON_A;
    SET result=POW(SIN(deltaLat/2), 2) + (COS(LAT_A) * COS(LAT_B) * POW(SIN(deltaLon/2.0), 2));
    SET distance=radius * 2 * ATAN2(SQRT(result), SQRT(1 - result));
    RETURN distance;
    END");
    

    これは、MySQLの数学関数 を使用します。 。この処理をデータベースにオフロードするのは高速で効率的です(データがネットワークを通過する必要はなく、必要な結果のみが返されます)。

    これを宣言したら、次のように使用できます:

    $query = "SELECT lat, lon FROM zipcodes WHERE Distance(lat, lon, 0, 0) < 20";
    mysql_query($query);
    

    ただし、データベースが再起動すると、以前に宣言された関数またはプロシージャはすべて失われます。 MySQLエラー1305を処理することが可能です(Function functionName does not exist )アプリケーションレベルで優雅に。

    データベースエラーハンドラの場合:

    switch (mysql_errno()):
        case 1305:
            if (false === $database->_declareStoredProcedureFlag) {
                 if ($c = preg_match_all("/FUNCTION [a-zA-Z0-9]+\." .
                     "([a-zA-Z0-9_]*) does not exist/is",
                     mysql_error(), $matches)
                 ) {
                     $storedFunctionName = $matches[1][0];
                     $database->_declareStoredProcedureFlag = true;
                     if (true === $database->declareStoredFunction($storedFunctionName)) {
                         $result = mysql_query($query);
                     }
                 }
             }
             break;
        ...
    


    1. SQLLIKEとINを一緒に使用する

    2. SQL Serverの2つの日付間の時間差(10進数)を計算するにはどうすればよいですか?

    3. INSERT INTO...SELECTすべての列を詳細化せずに

    4. MySQL INSERTステートメントは巨大なテーブルで遅くなりますか?