2012-09-24 78 views
2

我为使用存储过程的客户端编写了一个查询。原来他们不能授予我的用户对数据库的写权限,所以我不能存储我的过程。我可以将我的存储过程转变为查询中的匿名函数,以保持不使用存储过程的功能?MySQL中的匿名函数?

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

回答

3

如果您不能执行存储过程,您可能无法执行功能,或者因为它们不具有该功能的安全权限。

选项1 - 让自己的DBA审核SQL语句,然后修改数据库以容纳存储过程。

选项#2 - 您的其他选项是将该代码移出数据库并移入PHP。所以是的,你可以将它转移到PHP中,但它不会像数据库引擎那样快或有效。

0

你可以在同一个mysql服务器上获得一个单独的数据库吗?然后你可以在那里声明这个过程,然后在你的查询中用明确的数据库名称作为前缀来使用它。我不完全确定它是否会实际工作,但我猜想它确实有效。

1

不,你不能有匿名功能。如果您的客户无法授予您适当的权限来添加此功能,那么他们为什么要求您写一个?如果您的数据库用户帐户无法安装该功能,那么肯定有人拥有适当的用户帐户,可以根据您的SQL为您创建此功能。

另外为什么一个函数而不是存储过程?你可以把所有你正在做的逻辑在几个DB查询在一个单一的调用,比如:

call give_me_my_data(lat, long)

这似乎很奇怪,你会使用一些基于数据库的逻辑和一些基于PHP的逻辑(用不必要的查询数量)来获取您需要的数据,而不是一路走下去,并定义一个存储过程来清理您的PHP代码,从而只进行一次查询。