Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何对巨大的二进制列执行位操作_Mysql_Sql_Binary_Hex - Fatal编程技术网

Mysql 如何对巨大的二进制列执行位操作

Mysql 如何对巨大的二进制列执行位操作,mysql,sql,binary,hex,Mysql,Sql,Binary,Hex,我在mysql表中有一个字段,称为“调色板”。它的行为就像一个rgb十六进制代码,但不是3种颜色,我有12种。如果我不计算“0x”的2个字符,那么这个二进制字段的长度是24。问题是我似乎无法对它们执行位运算,好像程序认为它们太大了 我想围绕这些行做一些事情(我将使它变小以便于理解):mysql中的0x123456和0x00FF00,并获得0x003400。但这似乎根本不起作用,因为这不是我得到的价值 我希望得到一个精确的值,但大多数时候我得到的是0(即使有明确的值)或0的相反值(当十六进制只填充

我在mysql表中有一个字段,称为“调色板”。它的行为就像一个rgb十六进制代码,但不是3种颜色,我有12种。如果我不计算“0x”的2个字符,那么这个二进制字段的长度是24。问题是我似乎无法对它们执行位运算,好像程序认为它们太大了

我想围绕这些行做一些事情(我将使它变小以便于理解):mysql中的0x123456和0x00FF00,并获得0x003400。但这似乎根本不起作用,因为这不是我得到的价值


我希望得到一个精确的值,但大多数时候我得到的是0(即使有明确的值)或0的相反值(当十六进制只填充了“F”s)。

如果唯一的问题是您无法使用长十六进制字符串,您可以为此实现SP

DELIMITER $$

CREATE FUNCTION `bfunc`(
    `op` VARCHAR(3),
    `v1` VARCHAR(26) CHARSET latin1,
    `v2` VARCHAR(26) CHARSET latin1
)
RETURNS varchar(26) CHARSET latin1
DETERMINISTIC
BEGIN
    SET @r = '';
    SET @r1 = REVERSE(TRIM(LEADING '0x' FROM v1));
    SET @l1 = LENGTH(@r1);

    SET @r2 = REVERSE(TRIM(LEADING '0x' FROM v2));
    SET @l2 = LENGTH(@r2);

    SET @l = IF(@l1 > @l2, @l1, @l2);
    SET @i = 1;
    WHILE @i < @l DO
        SET @c1 = SUBSTR(@r1, @i, 1);
        SET @c2 = SUBSTR(@r2, @i, 1);
        SET @b1 = CONV(IF(@c1 = '', 0, @c1), 16, 10);
        SET @b2 = CONV(IF(@c2 = '', 0, @c2), 16, 10);
        SET @b = '';
        CASE op
            WHEN 'AND' THEN SET @b = @b1 & @b2;
            WHEN 'OR'  THEN SET @b = @b1 | @b2;
            WHEN 'XOR' THEN SET @b = @b1 ^ @b2;
        END CASE;

        SET @r = CONCAT(@r, HEX(@b));

        SET @i = @i + 1;
    END WHILE;

    RETURN REVERSE(@r);
END
$$

DELIMITER ;
=> 03400000000000000000000


当然,对于生产环境,您需要对其进行优化,并不是在“每字符”的基础上进行逐位计算,而是在“每8字符”的基础上进行逐位计算。

如果唯一的问题是无法使用长十六进制字符串,您可以为此实现SP

DELIMITER $$

CREATE FUNCTION `bfunc`(
    `op` VARCHAR(3),
    `v1` VARCHAR(26) CHARSET latin1,
    `v2` VARCHAR(26) CHARSET latin1
)
RETURNS varchar(26) CHARSET latin1
DETERMINISTIC
BEGIN
    SET @r = '';
    SET @r1 = REVERSE(TRIM(LEADING '0x' FROM v1));
    SET @l1 = LENGTH(@r1);

    SET @r2 = REVERSE(TRIM(LEADING '0x' FROM v2));
    SET @l2 = LENGTH(@r2);

    SET @l = IF(@l1 > @l2, @l1, @l2);
    SET @i = 1;
    WHILE @i < @l DO
        SET @c1 = SUBSTR(@r1, @i, 1);
        SET @c2 = SUBSTR(@r2, @i, 1);
        SET @b1 = CONV(IF(@c1 = '', 0, @c1), 16, 10);
        SET @b2 = CONV(IF(@c2 = '', 0, @c2), 16, 10);
        SET @b = '';
        CASE op
            WHEN 'AND' THEN SET @b = @b1 & @b2;
            WHEN 'OR'  THEN SET @b = @b1 | @b2;
            WHEN 'XOR' THEN SET @b = @b1 ^ @b2;
        END CASE;

        SET @r = CONCAT(@r, HEX(@b));

        SET @i = @i + 1;
    END WHILE;

    RETURN REVERSE(@r);
END
$$

DELIMITER ;
=> 03400000000000000000000


当然,对于生产环境,您需要对其进行优化,并不是在“每字符”的基础上进行位运算,而是在“每8字符”的基础上进行位运算。

0x123456&0x00FF00=>0x003400是正确的,不是吗?你是说这是错误的吗?您是否期待0x12FF56?这就是按位or运算符。我的意思是,这就是我所期望的。但是我得到的值可能会有很大的差异。我可以得到类似0x000000或0xFFFFFF的东西。我的字段看起来像0x12341234123412341234412341234,对大十六进制值的按位操作似乎有问题。您是如何存储这些长十六进制值的?作为文本还是VARCHAR?我尝试了很多组合。我试着使用varchar、binary(26)、varbinary、bigint、decimal(30,0)。我还尝试在每种类型中强制转换它们,但它总是返回一个断开的值(我知道它将返回一个int,但一旦我将其转换回hex,它就不适合)。可能是因为它存储在一个字段中或有96位,这就是问题所在?我现在正在运行一些测试,我不会每天处理这些长的十六进制,请稍等。0x123456&0x00FF00=>0x003400是正确的,不是吗?你是说这是错误的吗?您是否期待0x12FF56?这就是按位or运算符。我的意思是,这就是我所期望的。但是我得到的值可能会有很大的差异。我可以得到类似0x000000或0xFFFFFF的东西。我的字段看起来像0x12341234123412341234412341234,对大十六进制值的按位操作似乎有问题。您是如何存储这些长十六进制值的?作为文本还是VARCHAR?我尝试了很多组合。我试着使用varchar、binary(26)、varbinary、bigint、decimal(30,0)。我还尝试在每种类型中强制转换它们,但它总是返回一个断开的值(我知道它将返回一个int,但一旦我将其转换回hex,它就不适合)。也许问题在于它存储在字段中或有96位?我现在正在运行一些测试,我不是每天都处理这些长的十六进制数,请稍等。好吧,那么,你的解决方案更快了,还是我刚才做的“黑客”更优了?我所做的是使它成为一个没有“0x”的varchar,然后我做了一个子字符串。在大量的行上它会变慢吗?我认为你的“原生”解决方案会更快。好吧,那么,你的解决方案是更快,还是我刚才做的“黑客”更优化?我所做的是使它成为一个没有“0x”的varchar,然后我做了一个子字符串。在大量的行上它会变慢吗?我认为您的“本机”解决方案会更快。