此函数应接受viewname并在视图的最后一条记录上返回日期。有人能告诉我,我在这里缺少什么吗?
我在存储过程中调用该函数并出现此错误:
只能在函数内执行函数和一些扩展存储过程。
我的查询:
ALTER FUNCTION [dbo].[udf_GetLastDate] (@ViewName nvarchar(4000))
RETURNS date
AS
BEGIN
DECLARE @SQLCommand nvarchar(4000);
DECLARE @LastTransDate date;
SET @SQLCommand = 'SELECT @LastTransDate=LAST(TRANSDATE) FROM' + @ViewName;
EXECUTE sp_executesql @sqlCommand
RETURN @LastTransDate;
end
答案 0 :(得分:2)
问题是您正在尝试从函数执行Dynamic-SQL。你根本做不到。周期。
<强> Dynamic SQL in User-Defined Functions
强>:
这很简单:你不能在T-SQL编写的使用定义函数中使用动态SQL。这是因为你不允许这样做 UDF中可以改变数据库状态的任何东西(如UDF可能的那样) 作为查询的一部分被调用)。既然你可以做任何动态的事情 SQL,包括更新,很明显为什么动态SQL不是 允许的。
我在新闻组上看过不止一个帖子,人们一直在反对这一点。但是如果你想使用动态 UDF中的SQL,退出并重做您的设计。你遇到了障碍, 在SQL 2000中没有任何出路。
在SQL 2005及更高版本中,您可以将您的功能实现为CLR 功能。回想一下,CLR的所有数据访问都是动态SQL。 (你是安全保护的,所以如果你执行更新操作 你的功能,你会被抓住。)尽管有一个警告:数据 标量UDF的访问通常会带来性能问题。如果你 说
SELECT ... FROM tbl WHERE dbo.MyUdf(somecol)= @value
和MyUdf执行数据访问,您或多或少地创建了一个隐藏的 光标。
考虑将函数更改为存储过程:
CREATE PROCEDURE [dbo].[mysp_GetLastDate]
@ViewName SYSNAME
AS
BEGIN
DECLARE @SQLCommand NVARCHAR(MAX) =
N'SELECT MAX(TRANSDATE) FROM' + QUOTENAME(@ViewName);
EXECUTE [dbo].[sp_executesql]
@sqlCommand;
END
另请注意,SQL Server
没有LAST
功能。如果您需要最新TRANSDATE
使用MAX()
或SELECT TOP 1 TRANSADATE FROM ... ORDER BY some_column DESC