【问题标题】:Random value in computed columns计算列中的随机值
【发布时间】:2020-04-10 08:15:51
【问题描述】:

我有以下创建表格的脚本:

CREATE TABLE [dbo].[Persons] 
(
    [Id]            INT IDENTITY(1,1) NOT NULL,
    [Name]          NVARCHAR(250)     NOT NULL,
    [Surname]       NVARCHAR(250)     NOT NULL,
    [NumberOfNotes] INT               NOT NULL,
    [TotalCash]     FLOAT             NULL,
    [Result] AS ([NumberOfNotes] * [TotalCash] * (RAND()*(100-30)+30)),

    CONSTRAINT [PK_Persons] PRIMARY KEY ([Id] ASC)
);

在我插入新记录时,唯一可能的两种情况是:

  • 使用 [Name]、[Surname]、[NumberOfNotes]、[Result] 插入新记录
  • 使用 [Name]、[Surname]、[NumberOfNotes]、[TotalCash] 插入新记录

所以我在创建过程中必须满足以下两个条件

  1. 如果我不插入它,我应该能够插入一个新记录,其中 [Result] 被计算出来。计算公式是 [NumberOfNotes] * [TotalCash] * SomeRandomNumber 并且我确信在这种情况下 [TotalCash] 将永远存在,因为公式永远不会为空。但是,如果我改为手动插入 [Result],那么它将插入我的值而不是计算的值(在这种情况下,[TotalCash] 可以为空)。
  2. SomeRandomNumber 对于每条记录都是固定的。到目前为止,我尝试了 (RAND()*(100-30)+30)) 因为我想要一个介于 30 和 100 之间的随机数,但它会随着我在记录上运行的每个选择而不断变化。相反,如果我将其播种为 (RAND(Id)*(100-30)+30)),则多条记录是相同的。

【问题讨论】:

  • 因此,如果您不添加结果,您可以实现一个“插入后”触发器,如果​​结果列为 NULL,该触发器将修改它。对于兰德的事情,我想我不理解你。它的变化似乎有什么问题?
  • @Tarta 。 . .这看起来就像你之前的问题,答案是一样的。 . .将种子添加到rand()

标签: sql sql-server tsql sql-insert calculated-columns


【解决方案1】:

如果您希望能够实际写入Result 列,则不能使用计算列。

我建议为Result 设置一个常规列,并使用视图来实现显示逻辑,例如:

create view PersonsView as
select
    Id,
    Name,
    Surname,
    NumberOfNotes,
    TotalCash,
    coalesce(Result, NumberOfNotes * TotalCash * rand(Id) * (100 - 30) + 30) Result
from [dbo].[Persons] 

【讨论】:

    【解决方案2】:

    第二个条件不能使用计算列完成,除非计算列声明为persisted
    但是对于要持久化的计算列,它必须基于确定性函数 - 而Rand 是非确定性的。

    但是,您可以做的是使用触发器来计算列:

    CREATE TRIGGER tr_Persons_InsteadOfInsert
    ON dbo.Persons
    INSTEAD OF INSERT
    AS
    
    INSERT INTO dbo.Persons (Name, SurName, NumberOfNotes, TotalCach, Result)
    SELECT  Name
          , SurName
          , NumberOfNotes
          , TotalCach
          , CASE WHEN TotalCach IS NOT NULL AND Result IS NULL THEN  
              [NumberOfNotes] * [TotalCash] * (RAND()*(100-30)+30)
            ELSE 
                Result
            END)
    FROM Inserted
    
    GO
    

    当然,这意味着Result 列必须是常规列,而不是计算列,我猜您希望它为float - 所以您必须更改此列的定义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-20
      • 2019-10-29
      • 1970-01-01
      • 1970-01-01
      • 2019-03-18
      • 1970-01-01
      • 1970-01-01
      • 2012-12-28
      相关资源
      最近更新 更多