如何在SQL中生成随机的十六进制颜色?

26

对我来说这是一个相当困难的话题,因为SQL不是我的强项;)

我必须将随机十六进制颜色插入到数据库行中。我该怎么做?是否可能创建一个能够产生数字的函数?


哪个数据库?(MySQL,Oracle,PostgreSQL,...) - Super Mario
是的,使用哪个数据库? - The Impaler
我认为它是MySQL,因为他在发布几天后对第一个答案做出了关于MySQL的回应。 - jbrahy
11个回答

34
SET [Color] =  '#' +  CONVERT(VARCHAR(max), CRYPT_GEN_RANDOM(3), 2)

22

下面是用于MySQL的逻辑,封装在一个函数内进行说明。非常易于使用。

mysql> select random_color();
+----------------+
| random_color() |
+----------------+
| #8F50B4        |
+----------------+
1 row in set (0.00 sec)

它可以被多次调用,每次调用时它都会有不同的颜色。

CREATE FUNCTION `random_color`() RETURNS char(7) CHARSET latin1 DETERMINISTIC
BEGIN
 DECLARE str CHAR(7);
 SET str = concat('#',SUBSTRING((lpad(hex(round(rand() * 10000000)),6,0)),-6));
 RETURN str;
END;

这将在MySQL中为您提供六位十六进制数字代码

SELECT concat('#',SUBSTRING((lpad(hex(round(rand() * 10000000)),6,0)),-6))

这是一个很棒的东西,它可以给你增量颜色。

SELECT *, 
       concat('#',SUBSTRING((lpad(hex(@curRow := @curRow + 10),6,0)),-6)) AS color 
FROM table 
       INNER JOIN (SELECT @curRow := 5426175) color_start_point

4

以下方法适用于MySQL:

mysql> SELECT CONCAT('#',LPAD(CONV(ROUND(RAND()*16777215),10,16),6,0)) AS color;
+---------+
| color   |
+---------+
| #0E74A9 |
+---------+
1 row in set (0.00 sec)

简要说明:

  • 16777215是最大的24位无符号整数,即:224-1
  • 乘以RAND()ROUND()后将得到RGB颜色范围内的随机无符号整数:(0, 224-1)
  • 然后,将其从十进制转换为十六进制
  • LPAD()进行左侧填零
  • 最后,CONCAT()可获取'#'字符

2
with cte1 as (
select round(round(rand(),1)*15,0) as hex1,
 round(round(rand(),1)*15,0) as hex2,
 round(round(rand(),1)*15,0) as hex3,
 round(round(rand(),1)*15,0) as hex4,
 round(round(rand(),1)*15,0) as hex5,
 round(round(rand(),1)*15,0) as hex6
),
cte2 as (
select case when hex1 = 10 then 'A' 
when hex1 = 11 then 'B'
when hex1 = 12 then 'C'
when hex1 = 13 then 'D'
when hex1 = 14 then 'E'
when hex1 = 15 then 'F'
else str(hex1) end as hex1h,
case when hex2 = 10 then 'A' 
when hex2 = 11 then 'B'
when hex2 = 12 then 'C'
when hex2 = 13 then 'D'
when hex2 = 14 then 'E'
when hex2 = 15 then 'F'
else str(hex2) end as hex2h,
case when hex3 = 10 then 'A' 
when hex3 = 11 then 'B'
when hex3 = 12 then 'C'
when hex3 = 13 then 'D'
when hex3 = 14 then 'E'
when hex3 = 15 then 'F'
else str(hex3) end as hex3h,
case when hex4 = 10 then 'A' 
when hex4 = 11 then 'B'
when hex4 = 12 then 'C'
when hex4 = 13 then 'D'
when hex4 = 14 then 'E'
when hex4 = 15 then 'F'
else str(hex4) end as hex4h,
case when hex5 = 10 then 'A' 
when hex5 = 11 then 'B'
when hex5 = 12 then 'C'
when hex5 = 13 then 'D'
when hex5 = 14 then 'E'
when hex5 = 15 then 'F'
else str(hex5) end as hex5h,
case when hex6 = 10 then 'A' 
when hex6 = 11 then 'B'
when hex6 = 12 then 'C'
when hex6 = 13 then 'D'
when hex6 = 14 then 'E'
when hex6 = 15 then 'F'
else str(hex6) end as hex6h from cte1)

select '#'+ltrim(hex1h)+ltrim(hex2h)+ltrim(hex3h)+ltrim(hex4h)+ltrim(hex5h)+ltrim(hex6h) from cte2

1
以下是适用于2012年及以后所有版本的SQL Server函数,它可以生成十六进制格式的随机HTML颜色代码,例如#AABB00。同时也需要提供一个视图。
该函数让您可以选择避免浅色或深色颜色,这对于生成不会产生太多冲突的背景和前景颜色(即在深色背景上显示深色文本)非常有用。
CREATE FUNCTION dbo.Get_Random_Colour (@intStyle tinyint = 0)  
RETURNS varchar(7)

/*
* Purpose:      Returns the HTML colour code for a random colour
* Inputs:       @intStyle - 0: does not filter the colour range
*                           1: avoid dark colours
*                           2: avoid light colours
*/

AS  
BEGIN 

DECLARE @c1 char(2), @c2 char(2), @c3 char(2)
DECLARE @i1 tinyint, @i2 tinyint, @i3 tinyint
DECLARE @strResult As varchar(255)
DECLARE @intLow tinyint = 0
DECLARE @intHigh tinyint = 255

IF @intStyle = 1
    SET @intLow = 80

IF @intStyle = 2
    SET @intHigh = 140


--Generate random numbers
SELECT @i1 = CAST(ROUND((@intHigh-@intLow) * RandNumber + @intLow,0) as int) from dbo.vRandNumber
SELECT @i2 = CAST(ROUND((@intHigh-@intLow) * RandNumber + @intLow,0) as int) from dbo.vRandNumber
SELECT @i3 = CAST(ROUND((@intHigh-@intLow) * RandNumber + @intLow,0) as int) from dbo.vRandNumber

--Convert them to hex format
SELECT @c1 = FORMAT(@i1, 'X')
SELECT @c2 = FORMAT(@i2, 'X')
SELECT @c3 = FORMAT(@i3, 'X')

--Pad them to two characters
SELECT @strResult = '#' 
    + REPLICATE('0', 2-LEN(@c1)) + @c1
    + REPLICATE('0', 2-LEN(@c2)) + @c2
    + REPLICATE('0', 2-LEN(@c3)) + @c3



RETURN @strResult

END
GO

以下是该函数所依赖的视图:

CREATE VIEW [dbo].[vRandNumber]
AS
SELECT RAND() as RandNumber

1
我不确定你使用的是哪种数据库管理系统,但这个解决方案适用于SQL Server,并且如果你知道相应的语法和函数,它也可以应用于其他不同的DBMS。
十六进制颜色基本上是一个十六进制的VARBINARY值,几乎所有的DBMS都支持它。你只需要正确的转换来绑定它到你的需求。
例如,如果我们将字符串"foo"强制转换为VARBINARY,它将返回值0x666F6F,如果我们再次将其转换为VARCHAR,它将返回"foo"。
SELECT CAST('foo' AS VARBINARY) 
-- Returns : 0x666F6F

SELECT CAST(0x666F6F AS VARCHAR)
-- Returns : foo

因此,即使输出不同,相应的数据类型具有相同的值。这也适用于颜色(十六进制到RGB,RGB到十六进制,十六进制到二进制等)。
现在,您知道十六进制颜色使用VARBINARY数据类型,这将是我们解决方案的目标。
首先要做的是使用RGB值(另一种INT值的数据类型)生成VARBINARY。 RGB值是代表红色,绿色和蓝色的三个不同值。每个值的最小数字为0,最大数字为255。因此,如果我们执行RGB(0,0,0),这将返回#000000(黑色),而RGB(255,255,255)则返回#FFFFFF(白色)。
哦,我忘了,在此转换中您不需要任何特殊方程式,因为DBMS已经处理了这个问题。
因此,您的第一个目标是编写一个函数,该函数接受RGB值(最小为0,最大为255),然后将其转换为十六进制VARBINARY,从而给出十六进制颜色。
要将RGB转换为十六进制,您需要知道每2个十六进制代表一个RGB值。例如#BA55D3对应于rgb(186,85,211)。它的实际十六进制值为:
  • R = 0xBA
  • G = 0x55
  • B = 0xD3
其中:
  • 0xBA = 186
  • 0x55 = 85
  • 0xD3 = 211
因此,从每个十六进制颜色中,您需要将其分成三组两个值以表示RGB值。
如果将0xBA强制转换为INT,则会给出186,这是红色部分的值。
 SELECT 
    CAST(0xBA AS INT) 
    -- Returns : 186 

同样的事情也适用于其余部分。
现在,我们需要函数来为我们完成这项工作,为此,我创建了一个函数,只需将三个整数值转换为VARBINARY,以便于将其转换回varchar并将输出格式化为十六进制颜色值。
CREATE FUNCTION RGBToHex
(
        @R          INT,
        @G          INT,
        @B          INT
)
RETURNS VARCHAR(7)
AS
BEGIN
DECLARE 
        @VarR       VARBINARY,
        @VarG       VARBINARY,
        @VarB       VARBINARY,

        @Result     VARCHAR(7)

SELECT 
     @VarR  = CONVERT(VARBINARY, @R) * 1 , 
     @VarG  = CONVERT(VARBINARY, @G) * 1 , 
     @VarB  = CONVERT(VARBINARY, @B) * 1

SET @Result = '#' + SUBSTRING(Convert(VARCHAR(MAX),@VarR, 1), 3, 2) + SUBSTRING(Convert(VARCHAR(MAX),@VarG, 1), 3, 2) + SUBSTRING(Convert(VARCHAR(MAX),@VarB, 1), 3, 2)


    RETURN @Result

END

例子:
SELECT 
    RGBToHex(186,85,211)
-- Returns : #BA55D3

现在,这个函数已经准备好使用了,我们只需要一种方法来随机生成三个整数,以获得每次随机的颜色,考虑RGB的最小值和最大值(0-255)。
在SQL Server中,我使用递归查询为简单起见,您可以使用自己的查询方法或函数。
;WITH CTE AS (
    SELECT 
        ABS(CHECKSUM(NewId())) % 256 AS R , 
        ABS(CHECKSUM(NewId())) % 256 AS G ,
        ABS(CHECKSUM(NewId())) % 256 AS B
)   
SELECT 
    dbo.RGBToHex(R,G,B)
FROM CTE 

在上面的查询中,我已经为每列设置了0-255之间的随机数,然后将这些值放入函数中生成新的颜色。
如果您需要一个反转函数,以取色的十六进制值并返回RGB值,您可以使用此函数:
CREATE FUNCTION HexToRGB
(
        @Hex        VARCHAR(7)   
)
RETURNS VARCHAR(100)
AS
BEGIN
DECLARE 

        @VarH       VARCHAR(6), 
        @R          INT, 
        @G          INT, 
        @B          INT,
        @Result     VARCHAR(100)

SET @VarH = (CASE WHEN LEFT(@Hex, 1) = '#' THEN SUBSTRING(@Hex, 2,6) ELSE @Hex END)

SELECT
    @R  =   CONVERT(INT, CONVERT(VARBINARY, '0x' +  SUBSTRING(@VarH, 1,2), 1) ),
    @G  =   CONVERT(INT, CONVERT(VARBINARY, '0x' +  SUBSTRING(@VarH, 3,2), 1) ),
    @B  =   CONVERT(INT, CONVERT(VARBINARY, '0x' +  SUBSTRING(@VarH, 5,2), 1) )

SET @Result = 'rgb('    + CAST(@R AS VARCHAR(3) ) + ',' + CAST(@G AS VARCHAR(3) )   +  ','  +   CAST(@B AS VARCHAR(3) )     + ')' 

    RETURN @Result

END

1
如果您正在使用MySQL。
select concat("#", conv(round(rand() * 255), 10, 16), conv(round(rand() * 255), 10, 16), conv(round(rand() * 255), 10, 16));

不总是在#后面产生6个字符的输出。 - Wotuu

1
这是一个针对 PostgreSQL 的解决方案。
SELECT concat('#',lpad(to_hex(round(random() * 10000000)::int4),6,'0'))

我使用以下代码将随机颜色设置为表格的Color字段:

UPDATE "MyTable" SET "Color" = concat('#',lpad(to_hex(round(random() * 10000000)::int8),6,'0'));

0

两个问题:我需要十六进制格式 - 如何随机字母?如何将其更改为函数返回6位数字而不是随机每个数字? - Mr Jedi
你能否查找字符串函数 HEX 来进行转换? - Ed Heal

0
我为BigQuery解决了这个问题。使用一个名为"section"的INT列:
SELECT section
, ifNull(concat('#'
    , format('%X', mod(section, 256))
    , format('%X', mod(div(section, 256), 256))
    , format('%X', mod(div(div(section, 256), 256), 256))
    ), '#000000' #black=default
  ) as html_color
FROM StopTimes;

而且作为一个额外的好处,由于section是一个字符串列,它看起来像这样:
SELECT section, ifNull(concat('#'
    , format('%X', mod(abs(farm_fingerprint(section)), 256))
    , format('%X', mod(abs(div(farm_fingerprint(section), 256)), 256))
    , format('%X', mod(abs(div(div(farm_fingerprint(section), 256), 256)), 256))
    ), '#000000' #black=default
  ) as html_color
FROM StopTimes;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接