我在1990年创建了一个表(是的,27年前),它有一个代理PK和许多重复的行。我正在将表从Access迁移到SQL Server,并且我已经删除了代理键字段,但我正在尝试弄清楚如何从两个可包含空值的源列中包含计算列。 这对我有用:
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
这样的静态值,但我无法正确理解语法。
我尝试在转换为isnull(date,'')
之前添加varchar
,转换后添加分隔符,但是它们不起作用,我也尝试添加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之外使用脚本执行此操作,因为据我所知,这种类型的赋值存在错误。我也理解在从date转换为varchar时必须提供样式。
请告诉我如何附加这些字段值,以便我可以将计算列用作PK的一部分。
谢谢,
-Beth
答案 0 :(得分:1)
我建议在此表上使用代理键,并使用唯一索引进行补充。 (以及用下划线替换列名中的空格)
对于您的计算列,我认为这就是您的目标:
, 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 |
+----+-----------------+-------------+--------+--------------------+-----------------------+--------+---------------------+