【问题标题】:How can I change the value of a primary key of a table to be a random number?如何将表的主键值更改为随机数?
【发布时间】:2016-06-23 07:40:32
【问题描述】:

我有这张桌子:

CREATE TABLE [dbo].[Word] (
    [WordId]        INT            NOT NULL,
    [Name]          VARCHAR (20)   NOT NULL,
    [StatusId]      INT            DEFAULT ((1)) NULL,
    [Syllables]     VARCHAR (20)   NULL,
    [Ascii]         AS             (ascii([Name])) PERSISTED,
    [CategoryId]    INT            DEFAULT ((1)) NOT NULL,
    [GroupId]       INT            DEFAULT ((1)) NOT NULL,
    [LessonId]      INT            DEFAULT ((1)) NOT NULL,
    [CreatedBy]     INT            DEFAULT ((1)) NOT NULL,
    [CreatedDate]   DATETIME       DEFAULT (getdate()) NOT NULL,
    [ModifiedBy]    INT            DEFAULT ((1)) NOT NULL,
    [ModifiedDate]  DATETIME       DEFAULT (getdate()) NOT NULL,
    [Version]       ROWVERSION     NULL,
    PRIMARY KEY CLUSTERED ([WordId] ASC),
    CONSTRAINT [FK_WordLesson] FOREIGN KEY ([LessonId]) REFERENCES [dbo].[Lesson] ([LessonId]),
    CONSTRAINT [FK_WordWordCategory] FOREIGN KEY ([CategoryId]) REFERENCES [dbo].[WordCategory] ([WordCategoryId]),
    CONSTRAINT [FK_WordWordGroup] FOREIGN KEY ([GroupId]) REFERENCES [dbo].[WordGroup] ([WordGroupId])
);


GO
CREATE NONCLUSTERED INDEX [Word_Category_IX]
    ON [dbo].[Word]([CategoryId] ASC);


GO
CREATE NONCLUSTERED INDEX [Word_Group_IX]
    ON [dbo].[Word]([GroupId] ASC);


GO
CREATE NONCLUSTERED INDEX [Word_Lesson_IX]
    ON [dbo].[Word]([LessonId] ASC);

如何将 WordId 的值更改为介于 1 和 INT 列最大值之间的随机数?

请注意,我知道随机数有可能被使用两次,但它是测试数据,所以我不太担心。

【问题讨论】:

  • 但是你为什么要这样做呢?您要解决的实际问题是什么?
  • 为什么需要它是一个随机数?这是 PK,所以您要确保您没有创建重复项。这正是标识列的用途。还有,你说说INT列的最大值,是哪个INT列?
  • 根据定义,主键不应该是唯一的(即使在测试数据中)?
  • 是否要将主键“更改”为随机数?或者你希望它在插入行时是一个随机数?
  • @lopushen 是的,主键必须是唯一的。只有当他创建了一个复合主键(例如(WorldId, SomeOtherColumn))时,他才能在WorldId 中有重复项。

标签: sql-server


【解决方案1】:

我将建议一种与您目前正在走的路线不同的方法。

只需使用一个标识列,它是内置的,因为该字段是您需要确保不会重复的主键。代码如下所示。

CREATE TABLE [dbo].[Word] (
[WordId]        INT            IDENTITY(1,1) NOT NULL,

它会给你一个从 1 开始的值,每次输入新的数据行时递增 1。

另外,查看您的代码,您将字段 StatusId 设为可为空但具有默认值,您确定不希望将其作为 NOT NULL 字段吗?

有关信息,您可以使用此计算来获得小于给定 int 值的随机数;

DECLARE @RandomInt int; SET @RandomInt = 42

SELECT
@RandomInt Number
,ROUND(RAND()*@RandomInt,0) RandomLessThanInt

你会得到这样的答案;

Number  RandomLessThanInt
42      15

它显然会在每次运行时发生变化。您必须确保该数字不存在,否则您将试图违反 PK 约束并且插入将失败。

如果您已经在表格中填充了数据,那么您可以这样做

UPDATE TableName
SET FieldName = ROUND(RAND()*FieldName,0)

【讨论】:

  • 感谢 Rich,但我不再使用 IDENTITY,因为我需要将其作为随机数进行测试。昨天它正在使用 IDENTITY。只是不知道今天如何更改为随机。
  • @SamanthaJ 我刚刚更新了答案以包含您可以在您的桌子上运行的更新语句。可能需要几次尝试,具体取决于您是否得到相互冲突的值。
猜你喜欢
  • 2017-02-20
  • 1970-01-01
  • 1970-01-01
  • 2016-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多