繁体   English   中英

创建MySQL函数时出现问题

[英]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不存在。 然后我注意到,实际上,我是在另一个我尝试使用的数据库中创建该函数的。

但是我在适当的数据库中再次创建了它,但是出现了同样的错误。

所以这是问题:

  1. 我做错了什么? 这是我第一次尝试做类似的事情,但我不确定
  2. 我的PHP代码实现是有效的MySQL对应版本吗? 我有想念吗?
  3. 我可以将此功能设为“全局”吗? 我的意思是,可用于任何我需要的数据库吗? 因为对于我正在处理的应用程序,为了使所涉及的两个子系统保持分离,所以我创建了两个数据库。

更新

显然,未创建函数的问题就在DBNinja的一端,因为我直接在MySQL控制台中运行了该语句,尽管输出状态相同( 受影响0行) ,但我仍能够在一条语句中有效地使用该函数,因此函数毕竟是创建的。

但是,例程本身有问题,因为当我对其进行测试时,结果字符串是...“一个领先”。

例如,如果我运行以下PHP代码:

echo alphaID( 2 );

它将产生baaac ,但是MySQL函数返回baaad ,它将是整数3的AlphaID表示形式

不仅这是错误的,而且我认为当达到最大值2147483647时,它也可能会溢出使用的INT类型。

Bruno,从MySQL版本开始,您不见了:

  1. $ input + = pow($ base,4);
  2. PHP中的SUBSTR从0开始,在MySQL中从1开始。
  3. 循环结束条件应为:

    如果迭代器<0,则离开编码; 万一;

  4. 使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM