我有类似的东西
create function Answers_Index(@id int, @questionID int)
returns int
as begin
return (select count([ID]) from [Answers] where [ID] < @id and [ID_Question] = @questionID)
end
go
create table Answers
(
[ID] int not null identity(1, 1),
[ID_Question] int not null,
[Text] nvarchar(100) not null,
[Index] as [dbo].[Answers_Index]([ID], [ID_Question]),
)
go
insert into Answers ([ID_Question], [Text]) values
(1, '1: first'),
(2, '2: first'),
(1, '1: second'),
(2, '2: second'),
(2, '2: third')
select * from [Answers]
哪种方法效果很好,但它往往会减慢查询速度。如何使列Index
保持不变?我试过以下:
create table Answers
(
[ID] int not null identity(1, 1),
[ID_Question] int not null,
[Text] nvarchar(100) not null,
)
go
create function Answers_Index(@id int, @questionID int)
returns int
with schemabinding
as begin
return (select count([ID]) from [dbo].[Answers] where [ID] < @id and [ID_Question] = @questionID)
end
go
alter table Answers add [Index] as [dbo].[Answers_Index]([ID], [ID_Question]) persisted
go
insert into Answers ([ID_Question], [Text]) values
(1, '1: first'),
(2, '2: first'),
(1, '1: second'),
(2, '2: second'),
(2, '2: third')
select * from [Answers]
但是会引发以下错误:Computed column 'Index' in table 'Answers' cannot be persisted because the column does user or system data access.
或者我应该忘记它并使用[Index] int not null default(0)
并将其填入on insert
触发器中?
编辑:谢谢,最终解决方案:
create trigger [TRG_Answers_Insert]
on [Answers]
for insert, update
as
update [Answers] set [Index] = (select count([ID]) from [Answers] where [ID] < a.[ID] and [ID_Question] = a.[ID_Question])
from [Answers] a
inner join [inserted] i on a.ID = i.ID
go
答案 0 :(得分:4)
您可以将列更改为普通列,然后在使用触发器对该行进行INSERT / UPDATE时更新其值。
create table Answers
(
[ID] int not null identity(1, 1),
[ID_Question] int not null,
[Text] nvarchar(100) not null,
[Index] Int null
)
CREATE TRIGGER trgAnswersIU
ON Answers
FOR INSERT,UPDATE
AS
DECLARE @id int
DECLARE @questionID int
SELECT @id = inserted.ID, @questionID = inserted.ID_question
UPDATE Answer a
SET Index = (select count([ID]) from [Answers] where [ID] < @id and [ID_Question] = @questionID)
WHERE a.ID = @id AND a.ID_question = @questionID
GO
NB *这不完全正确,因为它在UPDATE上无法正常工作,因为我们没有“插入”表来引用获取ID和questionid。有一种解决方法,但我现在无法记住它:(
答案 1 :(得分:0)
计算列仅存储要执行的计算公式。这就是为什么从表中查询计算列时速度会变慢的原因。如果要将值保存到实际的表列,那么使用触发器是正确的。