我有一个简单的用例,我正在创建一个表,用一些基本信息填充它并创建一个表值函数,在这种情况下,如果名称为'Apple',则只返回一行.
Select * from FruitTable Where Name = 'Apple'
Run Code Online (Sandbox Code Playgroud)
一切正常,直到我决定不再需要Active列,然后从表中删除它.重新运行该功能后,我收到此错误
-- Use the function it fails Msg 4502, Level 16, State 1, Line 1
-- View or function 'GetApples' has more column names specified than columns defined.
Select * from GetApples()
Run Code Online (Sandbox Code Playgroud)
我环顾四周,看看如果一个表被更改,这是一个带有视图的事件,但是使用这个函数我从FruitTable中选择*并且预计如果对Fruit表做了任何更改,无论是添加还是删除列Select*将会有益的未来,因为我不必定义结果表的列结构.
此外,我只是在函数上执行了一个SP_Help,并注意到它看起来像即使我做了一个select*,实际上存储了关于列的元数据.
SP_Help GetApples
--Column_name Type
--Id int
--Name varchar
--Active bit
Run Code Online (Sandbox Code Playgroud)
所以我有两个问题.
有没有办法从函数中删除列,或者在Alter之后以某种方式刷新函数?
鉴于我在表值函数中使用select*遇到了这些问题,最好是实际定义结果表列结构,还是用select*做我想做的事情,不需要太多保养什么时候改变基础表?
谢谢
这是测试SQL
-- Create the Simple Table Fill in Some Values
Create Table FruitTable(Id int, Name varchar(50), Active bit)
Insert Into FruitTable values
(1 , 'Apple', 1),
(2 , 'Pear', 0),
(3 , 'Orange', 0)
GO
-- Create a Basic Function
Create Function GetApples()
Returns Table
As
Return(
Select * from FruitTable Where Name = 'Apple'
)
GO
-- Use the function it works and returns
--Id Name Active
--1 Apple 1
Select * from GetApples()
Go
-- Drop Active
Alter Table FruitTable Drop Column [Active]
GO
-- Use the function it fails Msg 4502, Level 16, State 1, Line 1
-- View or function 'GetApples' has more column names specified than columns defined.
Select * from GetApples()
Go
Run Code Online (Sandbox Code Playgroud)
小智 6
我认为你应该使用刷新模块系统功能,如下所示.
EXEC sys.sp_refreshsqlmodule 'dbo.GetApples';
Run Code Online (Sandbox Code Playgroud)