作为 PK 的一部分,包含日期和数字的计算列可以为空,但不能同时为空
Calculated column with date and number, either but not both can be null, as part of PK
我有一个 table 创建于 1990 年(是的,27 年前),它有一个代理 PK 和很多重复的行。我正在将 table 从 Access 迁移到 SQL 服务器,并且我已经删除了代理键字段,但我试图弄清楚如何从两个源列中包含一个计算列,这可以包含空值。
这对我有用:
CREATE TABLE [dbo].[ActionHistory]
(
[Position Number] [int] NOT NULL,
[SSN] [nvarchar](11) NOT NULL,
[Action] [nvarchar](10) NOT NULL,
[EffectiveSalaryKey] AS (CONVERT([varchar](20), [Action Effective Date], 20) + ';' +
CONVERT([varchar](20), isnull([Salary], ''), 0)) PERSISTED NOT NULL,
[Action Effective Date] [datetime] NULL,
[Salary] [money] NULL,
...,
[entered] [datetime] NULL
CONSTRAINT [DF_ActionHistory_entered] DEFAULT (getdate()),
CONSTRAINT [PK_ActionHistory]
PRIMARY KEY CLUSTERED ([Position Number] ASC, [SSN] ASC, [Action] ASC, [EffectiveSalaryKey] ASC)
...
)
但它不允许我输入无效日期的行。
我想做一些事情,比如将空日期转换为键字段的空白,甚至是像 1/1/1900 00:00:00
这样的静态值,但我无法获得正确的语法。
我尝试在转换为 varchar
之前添加 isnull(date,'')
,在转换之后,以及在附加定界符之后添加,但它们没有用,我也尝试添加 isnull(date,'1900-01-01 00:00:00')
但这也没有用。
当我尝试时:
[EffectiveSalaryKey] AS
(
CONVERT(
[varchar](20),isnull([Action Effective Date],''),20
)
它说:
Computed column 'EffectiveSalaryKey' in table 'ActionHistory' cannot be persisted because the column is non-deterministic.
我正在 GUI 之外使用脚本来执行此操作,据我所知,此类分配存在一个错误。我也明白从日期转换为 varchar 时必须提供样式。
请告诉我应该如何附加这些字段值,以便我可以将计算列用作 PK 的一部分。
谢谢,
-贝丝
我建议在此 table 上也使用代理键,并补充唯一索引。 (连同用下划线替换列名中的空格)
对于您的计算列,我认为这就是您所追求的:
, effectivesalarykey as (
isnull(convert(varchar(20),[action_effective_date],20)+ ';','')
+ isnull(convert(varchar(20),salary),'0')
) persisted not null
第一个isnull
中的第一个''
可以改成任何你喜欢的
, effectivesalarykey as (
isnull(convert(varchar(20),[action_effective_date],20)+ ';','1900-01-01 00:00:00;')
+ isnull(convert(varchar(20),salary),'0')
) persisted not null
rextester:http://rextester.com/SBA4540
create table dbo.actionhistory(
id int not null identity(1,1)
, position_number int not null
, ssn nvarchar(11) not null
, action nvarchar(10) not null
, effectivesalarykey as (
isnull(convert(varchar(20),[action_effective_date],20)+ ';','')
+ isnull(convert(varchar(20),salary),'0')
) persisted not null
,
[action_effective_date] datetime null
, salary money null
, entered datetime null constraint df_actionhistory_entered default (getdate())
, constraint pk_actionhistory primary key clustered (id)
);
create unique nonclustered index ix_actionhistory_position_ssn_action_effectivesalarykey
on dbo.actionhistory (
position_number asc
, ssn asc
, action asc
, effectivesalarykey asc )
insert into dbo.actionhistory (position_number,ssn,action) values
(1,'000-00-0000','Test')
select *
from dbo.actionhistory;
结果:
+----+-----------------+-------------+--------+--------------------+-----------------------+--------+---------------------+
| id | position_number | ssn | action | effectivesalarykey | action_effective_date | salary | entered |
+----+-----------------+-------------+--------+--------------------+-----------------------+--------+---------------------+
| 1 | 1 | 000-00-0000 | Test | 0 | NULL | NULL | 13.02.2017 20:35:21 |
+----+-----------------+-------------+--------+--------------------+-----------------------+--------+---------------------+
我有一个 table 创建于 1990 年(是的,27 年前),它有一个代理 PK 和很多重复的行。我正在将 table 从 Access 迁移到 SQL 服务器,并且我已经删除了代理键字段,但我试图弄清楚如何从两个源列中包含一个计算列,这可以包含空值。 这对我有用:
CREATE TABLE [dbo].[ActionHistory]
(
[Position Number] [int] NOT NULL,
[SSN] [nvarchar](11) NOT NULL,
[Action] [nvarchar](10) NOT NULL,
[EffectiveSalaryKey] AS (CONVERT([varchar](20), [Action Effective Date], 20) + ';' +
CONVERT([varchar](20), isnull([Salary], ''), 0)) PERSISTED NOT NULL,
[Action Effective Date] [datetime] NULL,
[Salary] [money] NULL,
...,
[entered] [datetime] NULL
CONSTRAINT [DF_ActionHistory_entered] DEFAULT (getdate()),
CONSTRAINT [PK_ActionHistory]
PRIMARY KEY CLUSTERED ([Position Number] ASC, [SSN] ASC, [Action] ASC, [EffectiveSalaryKey] ASC)
...
)
但它不允许我输入无效日期的行。
我想做一些事情,比如将空日期转换为键字段的空白,甚至是像 1/1/1900 00:00:00
这样的静态值,但我无法获得正确的语法。
我尝试在转换为 varchar
之前添加 isnull(date,'')
,在转换之后,以及在附加定界符之后添加,但它们没有用,我也尝试添加 isnull(date,'1900-01-01 00:00:00')
但这也没有用。
当我尝试时:
[EffectiveSalaryKey] AS
(
CONVERT(
[varchar](20),isnull([Action Effective Date],''),20
)
它说:
Computed column 'EffectiveSalaryKey' in table 'ActionHistory' cannot be persisted because the column is non-deterministic.
我正在 GUI 之外使用脚本来执行此操作,据我所知,此类分配存在一个错误。我也明白从日期转换为 varchar 时必须提供样式。
请告诉我应该如何附加这些字段值,以便我可以将计算列用作 PK 的一部分。
谢谢,
-贝丝
我建议在此 table 上也使用代理键,并补充唯一索引。 (连同用下划线替换列名中的空格)
对于您的计算列,我认为这就是您所追求的:
, effectivesalarykey as (
isnull(convert(varchar(20),[action_effective_date],20)+ ';','')
+ isnull(convert(varchar(20),salary),'0')
) persisted not null
第一个isnull
中的第一个''
可以改成任何你喜欢的
, effectivesalarykey as (
isnull(convert(varchar(20),[action_effective_date],20)+ ';','1900-01-01 00:00:00;')
+ isnull(convert(varchar(20),salary),'0')
) persisted not null
rextester:http://rextester.com/SBA4540
create table dbo.actionhistory(
id int not null identity(1,1)
, position_number int not null
, ssn nvarchar(11) not null
, action nvarchar(10) not null
, effectivesalarykey as (
isnull(convert(varchar(20),[action_effective_date],20)+ ';','')
+ isnull(convert(varchar(20),salary),'0')
) persisted not null
,
[action_effective_date] datetime null
, salary money null
, entered datetime null constraint df_actionhistory_entered default (getdate())
, constraint pk_actionhistory primary key clustered (id)
);
create unique nonclustered index ix_actionhistory_position_ssn_action_effectivesalarykey
on dbo.actionhistory (
position_number asc
, ssn asc
, action asc
, effectivesalarykey asc )
insert into dbo.actionhistory (position_number,ssn,action) values
(1,'000-00-0000','Test')
select *
from dbo.actionhistory;
结果:
+----+-----------------+-------------+--------+--------------------+-----------------------+--------+---------------------+
| id | position_number | ssn | action | effectivesalarykey | action_effective_date | salary | entered |
+----+-----------------+-------------+--------+--------------------+-----------------------+--------+---------------------+
| 1 | 1 | 000-00-0000 | Test | 0 | NULL | NULL | 13.02.2017 20:35:21 |
+----+-----------------+-------------+--------+--------------------+-----------------------+--------+---------------------+