[英]Problems while creating a MySQL function
我有一个PHP函数来创建那些著名的整数AlphaID表示,如下所示:
function alphaID( $input ) {
$index = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$base = strlen( $index );
$input += pow( $base, 4 );
$output = '';
for( $i = floor( log( $input, $base ) ); $i >= 0; $i-- ) {
$bcp = bcpow( $base, $i );
$start = floor( $input / $bcp ) % $base;
$output .= substr( $index, $start, 1 );
$input = $input - ( $start * $bcp );
}
return $output;
}
例如,对PHP_MAX_INT常量(2147483647)提供的最大整数进行编码将返回cwuCBb
但是我认为整个应用程序的速度有点太慢,所以我尝试创建一个MYSQL函数,因此,从理论上讲,一旦数据在查询时为我准备好了,我就不会浪费用PHP进行这种转换的性能。
MySQL手册并不完全友好,但是到处搜索时我发现:
DROP FUNCTION IF EXISTS ENCODE_ALPHAID;
DELIMITER $$
CREATE FUNCTION ENCODE_ALPHAID( input integer ) RETURNS CHAR( 6 ) DETERMINISTIC
BEGIN
DECLARE output CHAR( 6 );
DECLARE letters CHAR( 62 );
DECLARE base TINYINT( 2 );
DECLARE iterator TINYINT( 2 );
DECLARE bcp CHAR( 9 );
DECLARE start TINYINT( 2 );
SET output = '';
SET letters = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
SET base = CHAR_LENGTH( letters );
SET input = input + POW( base, 4 );
SET iterator = FLOOR( LOG( base, input ) );
ENCODING: LOOP
SET bcp = POW( base, iterator );
SET start = FLOOR( input / bcp ) % base + 1;
SET output = CONCAT( output, SUBSTR( letters, start, 1 ) );
SET input = input - ( start * bcp );
SET iterator = iterator-1;
IF iterator < 0 THEN LEAVE ENCODING; END IF;
END LOOP ENCODING;
RETURN output;
END $$
DELIMITER ;
但是当我通过我使用的MySQL管理器( DBNinja )运行它时,显然没有任何反应。 运行查询后,它显示0行受影响,并且我不确定这是否是预期的输出。
正确与否,该函数无法正常工作,因为当我尝试在查询中使用它时:
SELECT ENCODE_ALPHAID( `c`.`cid` ) from `table` c WHERE `c.user` = 1
我首先收到一条说table的错误消息。ENCODE_ALPHAID不存在。 然后我注意到,实际上,我是在另一个我尝试使用的数据库中创建该函数的。
但是我在适当的数据库中再次创建了它,但是出现了同样的错误。
所以这是问题:
更新
显然,未创建函数的问题就在DBNinja的一端,因为我直接在MySQL控制台中运行了该语句,尽管输出状态相同( 受影响的0行) ,但我仍能够在一条语句中有效地使用该函数,因此函数毕竟是创建的。
但是,例程本身有问题,因为当我对其进行测试时,结果字符串是...“一个领先”。
例如,如果我运行以下PHP代码:
echo alphaID( 2 );
它将产生baaac ,但是MySQL函数返回baaad ,它将是整数3的AlphaID表示形式
不仅这是错误的,而且我认为当达到最大值2147483647时,它也可能会溢出使用的INT类型。
Bruno,从MySQL版本开始,您不见了:
循环结束条件应为:
如果迭代器<0,则离开编码; 万一;
使用CONCAT时,请确保不要使用CONCAT NULL(应初始化参数)
例程始终在一个数据库中创建。 您可以通过在查询中包括数据库名称来调用它们中的任何一个(如果有特权):
call mydb.ENCODE_ALPHAID( 2147483647 );
同样,在声明变量时,您可能希望使用前缀,以免变量与可能的列名/保留字混淆。 例如,使用“ v_output”代替“输出”。
好像您缺少END IF; 不要将保留字用于变量。 如果您想采用邪恶的方式,请确保将其引用为.ie`table``,。 请注意反斜线-不是单引号。 在我的机器上,此代码返回null:
CREATE DEFINER=`root`@`localhost` FUNCTION `ENCODE_ALPHAID`(`input` INT)
RETURNS CHAR(6) DETERMINISTIC NO SQL SQL SECURITY DEFINER
BEGIN
DECLARE output CHAR(6);
DECLARE `index` CHAR(62);
DECLARE base TINYINT(2);
DECLARE iterator TINYINT( 2 );
DECLARE bcp CHAR( 9 );
DECLARE start TINYINT( 2 ); SET `index` = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
SET base = CHAR_LENGTH( `index` );
SET iterator = FLOOR( LOG( base, input ) );
ENCODING: LOOP
SET bcp = POW( base, iterator );
SET start = FLOOR( input / bcp ) % base;
SET output = CONCAT( output, SUBSTR( `index`, start, 1 ) );
SET input = input - ( start * bcp );
SET iterator = iterator-1;
IF iterator >= 0 THEN LEAVE ENCODING;
END IF;
END LOOP ENCODING;
RETURN output;
END;
PS:在背面打勾,用一个。 我不知道如何逃避降价促销。 eaid
是我使用的eaid
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.