动态视图中的动态SQL返回记录的字段值

时间:2015-10-23 17:49:07

标签: sql sql-server tsql dynamic-sql

此函数应接受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

1 个答案:

答案 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