我有一个表值函数A,它调用表值函数B和C.函数B和C作为迁移的一部分被更新(更改),但是表A没有因此而更新。如何在不改变的情况下重建A?
示例(为方便起见,仅添加了回滚)SQL Fiddle:
BEGIN TRANSACTION
SET NOCOUNT ON;
CREATE TABLE DOGS
(
Id UNIQUEIDENTIFIER PRIMARY KEY,
Name NVARCHAR(255) NOT NULL,
Age INT NOT NULL,
)
INSERT INTO DOGS VALUES (NEWID(), 'Rocky', 12);
INSERT INTO DOGS VALUES (NEWID(), 'Sammy', 2);
INSERT INTO DOGS VALUES (NEWID(), 'Porthos', 5);
CREATE TABLE CATS
(
Id UNIQUEIDENTIFIER PRIMARY KEY,
Name NVARCHAR(255) NOT NULL,
Age INT NOT NULL,
)
INSERT INTO CATS VALUES (NEWID(), 'Mr. T', 15);
INSERT INTO CATS VALUES (NEWID(), 'Old Timer', 37);
INSERT INTO CATS VALUES (NEWID(), 'Mittens', 1);
SET NOCOUNT OFF;
GO
CREATE FUNCTION [GetCatsYoungerThan]
(
@age INT
)
RETURNS TABLE AS
RETURN (
SELECT Name FROM CATS WHERE Age < @age
);
GO
CREATE FUNCTION [GetDogsYoungerThan]
(
@age INT
)
RETURNS TABLE AS
RETURN (
SELECT Name FROM DOGS WHERE Age < @age
);
GO
CREATE FUNCTION [GetAnimalsYoungerThan]
(
@age INT
)
RETURNS TABLE AS
RETURN (
SELECT * FROM [GetCatsYoungerThan](@age)
UNION
SELECT * FROM [GetDogsYoungerThan](@age)
);
GO
ALTER FUNCTION [dbo].[GetDogsYoungerThan]
(
@age INT
)
RETURNS TABLE AS
RETURN (
SELECT Name, Age FROM DOGS WHERE Age < @age
);
GO
ALTER FUNCTION [dbo].[GetCatsYoungerThan]
(
@age INT
)
RETURNS TABLE AS
RETURN (
SELECT Name, Age FROM CATS WHERE Age < @age
);
GO
EXEC sp_recompile '[GetAnimalsYoungerThan]';
--results
SELECT * FROM [GetAnimalsYoungerThan](15);
--Shows expected results
SELECT * FROM [GetCatsYoungerThan](15)
UNION
SELECT * FROM [GetDogsYoungerThan](15)
ROLLBACK TRANSACTION
结果:
Name
-------
Mittens
Porthos
Rocky
Sammy
预期结果:
Name Age
-----------
Mittens 1
Porthos 5
Rocky 12
Sammy 2
我的期望是sp_recompile
会导致函数被重新编译;但是,要么没有发生,要么不足以更新A返回的值。
我最初的计划是使用以下代码重新编译数据库中的所有对象,但需要sp_recompile
才能工作。
DECLARE @ObjectName NVARCHAR(MAX);
DECLARE MY_CURSOR CURSOR
LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR
SELECT [ROUTINE_SCHEMA] + '.' + [ROUTINE_NAME] AS [NAME]
FROM information_schema.routines
WHERE [ROUTINE_SCHEMA] = 'my_domain';
OPEN MY_CURSOR
FETCH NEXT FROM MY_CURSOR INTO @ObjectName
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'Recompiling ' + @ObjectName + '...';
EXEC sp_recompile @ObjectName;
FETCH NEXT FROM MY_CURSOR INTO @ObjectName;
END
CLOSE MY_CURSOR
DEALLOCATE MY_CURSOR
先谢谢你的帮助。
答案 0 :(得分:2)
这是使用p2
的结果以及执行TVF早期架构绑定的结果。
您可以通过运行获得所需的结果:
SELECT *
有效地将架构重新绑定到TVF,没有sp_refreshsqlmodule <tvf-name>
的详细程度
但从长远来看,请尽量避免使用ALTER x...
。