我在scalar function
中创建了一个SQL Server 2008
,而我在几个表中的计算列中也是如此。现在我想在不丢弃表的情况下改变函数。但它引发了一个错误:
无法改变&#d ;.boetStatus'因为它被对象引用 '订单'
是否可以改变功能?或者我先删除并创建所有可靠的表,然后更改函数?
这是我的功能:
CREATE FUNCTION [dbo].[GetStatus]
(
@FromDate datetime,
@ToDate datetime
)
RETURNS tinyint
AS
BEGIN
declare @ret tinyint;
if(@FromDate<=GETDATE() and (@ToDate>=GETDATE() or @ToDate is null))
set @ret= 1
else
set @ret= 0
return @ret
END
它在表中提到:
CREATE TABLE [dbo].[Order](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](200) NOT NULL,
[EffectiveFromDate] [datetime] NOT NULL,
[EffectiveToDate] [datetime] NULL,
[Status] AS ([dbo].[GetStatus]([EffectiveFromDate],[EffectiveToDate]))
)
答案 0 :(得分:0)
这是设计的。您应首先删除所有默认值/约束,然后更改您的函数并添加这些约束。无需放弃表格。
但你可以通过以下技巧解决这个问题:
添加将调用实际功能的中间函数; 改变计算列以调用中间函数而不是实际函数。
示例:
CREATE FUNCTION dbo.fnActual ( @p INT )
RETURNS INT
AS
BEGIN
RETURN @p + 1
END
GO
CREATE FUNCTION dbo.fnIntermediate ( @p INT )
RETURNS INT
AS
BEGIN
RETURN dbo.fnActual(@p)
END
GO
CREATE TABLE TestTable(id INT, fn AS dbo.fnIntermediate(id))
GO
插入一些值:
INSERT INTO dbo.TestTable VALUES ( 1 )
SELECT * FROM dbo.TestTable --selects 2
--throws exception
ALTER FUNCTION dbo.fnIntermediate ( @p INT )
RETURNS INT
AS
BEGIN
RETURN dbo.fnActual(@p)
END
GO
--succseeds
ALTER FUNCTION dbo.fnActual ( @p INT )
RETURNS INT
AS
BEGIN
RETURN @p + 2
END
GO
SELECT * FROM dbo.TestTable --selects 3
答案 1 :(得分:0)
ALTER TABLE [dbo].[Order]
DROP COLUMN [Status]
GO
ALTER FUNCTION [dbo].[GetStatus] ...
GO
ALTER TABLE [dbo].[Order]
ADD [Status] AS ([dbo].[GetStatus]([EffectiveFromDate],[EffectiveToDate]))
GO
甚至
ALTER TABLE [dbo].[Order]
DROP COLUMN [Status]
GO
ALTER TABLE [dbo].[Order]
ADD [Status] AS CAST(CASE WHEN [EffectiveFromDate] <= GETDATE() AND ([EffectiveToDate] >= GETDATE() OR [EffectiveToDate] IS NULL) THEN 1 ELSE 0 END as tinyint)
GO