【问题标题】:want to generate coupon code 5 digit number [duplicate]想要生成优惠券代码5位数[重复]
【发布时间】:2015-06-15 10:27:16
【问题描述】:

我想使用 SQL 数据库创建优惠券代码生成器,但我不知道如何生成 1000 个随机数而不重复它们。所以有人可以帮助我,这很重要。谢谢

【问题讨论】:

  • 是sqlite还是sql server?这是两件不同的事情。
  • 对于 Zohar Peled,我正在使用 SQL,但由于某种原因它无法正常工作,所以我开始使用 SQLlite。
  • 每次需要选择单个值还是多个值?

标签: sql-server sqlite


【解决方案1】:

关系数据库表中的记录本质上是无序的。 因此,您可以简单地创建一个包含 @First@Last (在您的情况下为 0 和 9999)之间的所有值的表,然后在从该表中选择时使用随机顺序。您也可以在数据库表中使用一个简单的 int,然后在从表中选择数据时对其进行格式化。

由于我的主数据库是 Sql server,而且我没有使用 sqlite 的经验,我将在我的代码示例中使用 Sql Server 语法,并留给你找到 sqllite 等效项。

首先,创建表:

CREATE TABLE Tbl 
(
    IntValue int PRIMARY KEY,
    IsUsed bit NOT NULL DEFAULT 0
)

然后,用 0 到 9999 之间的数字填充它:

;With CTE AS (
    SELECT 0 As IntValue
    UNION ALL
    SELECT  IntValue + 1
    FROM CTE
    WHERE IntValue + 1 < 10000
)

INSERT INTO Tbl (IntValue)
SELECT IntValue
FROM CTE
OPTION(MAXRECURSION 0)

然后,你想每次选择多个值,所以我会写一个这样的存储过程:

CREATE PROCEDURE stp_GetCouponCodes
(
    @Number int = 5 -- or whatever number is default
)
AS
BEGIN
  DECLARE @UsedValues AS TABLE
  (
      IntValue int
  )

  BEGIN TRY

  BEGIN TRANSACTION

  INSERT INTO @UsedValues 
  SELECT TOP(@Number) IntValue
  FROM Tbl
  WHERE IsUsed = 0
  ORDER BY NEWID()

  UPDATE Tbl
  SET IsUsed = 1
  FROM Tbl 
  INNER JOIN 
  @UsedValues uv ON(Tbl.IntValue = uv.IntValue)

  SELECT RIGHT('00000' + CAST(IntValue as varchar), 5)
  FROM @UsedValues 

  COMMIT TRANSACTION
  END TRY

  BEGIN CATCH
     IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION
  END CATCH
END

然后,当您想要生成优惠券时,只需使用您想要的优惠券数量执行存储过程:

EXEC stp_GetCouponCodes 10;

See working fiddle example here.

【讨论】:

  • Zohar peled,谢谢兄弟的帮助。
【解决方案2】:

下面的代码使用一种快速的方法,根据提供的字母表生成 100 个随机的 5 个字符的字符串。您仍然需要执行重复检查,但这应该可以帮助您开始。

DECLARE @Quantity INT = 1000
DECLARE @Alphabet VARCHAR(100) = '0123456789'
DECLARE @Length INT = LEN(@Alphabet)
DECLARE @Top INT = SQRT(@Quantity) + 1
;WITH CTE AS (
    SELECT TOP (@Top) *
    FROM sys.objects
)
SELECT TOP (@Quantity)
    SUBSTRING(@Alphabet, ABS(CHECKSUM(NEWID())) % @Length + 1, 1)
    + SUBSTRING(@Alphabet, ABS(CHECKSUM(NEWID())) % @Length + 1, 1)
    + SUBSTRING(@Alphabet, ABS(CHECKSUM(NEWID())) % @Length + 1, 1)
    + SUBSTRING(@Alphabet, ABS(CHECKSUM(NEWID())) % @Length + 1, 1)
    + SUBSTRING(@Alphabet, ABS(CHECKSUM(NEWID())) % @Length + 1, 1)
    AS [Code]
FROM CTE X
    CROSS JOIN CTE Y

【讨论】:

  • 但这适用于 SQL Server 还是 SQLlite。
  • 我为 SQL Server 测试了它。可能必须更改 CTE 生成 100 个字符的方法 - 我不记得 sys.objects 在 sql-lite 中是否可用。将在几分钟后更新。
  • 还是谢谢。
  • 好的,那就不更新了……抱歉错过了sqllite标签
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-22
  • 2011-06-01
  • 2018-05-11
  • 1970-01-01
  • 2014-12-24
  • 2014-11-26
相关资源
最近更新 更多