当前位置:  开发笔记 > 编程语言 > 正文

在SQLServer 2005函数中执行动态SQL

如何解决《在SQLServer2005函数中执行动态SQL》经验,为你挑选了2个好方法。

我将在这个问题的序言中说,我不认为它是可以解决的.我也有一个解决方法,我可以用OUTPUT创建一个存储过程来实现这一点,使用一个函数编码我需要这个校验和的部分更容易.

由于Exec SP_ExecuteSQL @SQL调用,此代码无效.任何人都知道如何在函数中执行动态SQL?(再一次,我认为这是不可能的.如果是的话,我很想知道怎么绕过它!)

Create Function Get_Checksum
(
    @DatabaseName      varchar(100),
    @TableName         varchar(100)
)
RETURNS FLOAT
AS
BEGIN

 Declare @SQL        nvarchar(4000)
 Declare @ColumnName varchar(100)
 Declare @i          int
 Declare @Checksum   float
 Declare @intColumns table (idRecord int identity(1,1), ColumnName varchar(255))
 Declare @CS         table (MyCheckSum bigint)

 Set @SQL = 
        'Insert Into @IntColumns(ColumnName)' + Char(13) + 
        'Select Column_Name' + Char(13) +
        'From   ' + @DatabaseName + '.Information_Schema.Columns (NOLOCK)' + Char(13) +
        'Where  Table_Name = ''' + @TableName + '''' + Char(13) +
        '       and Data_Type = ''int''' 

 -- print @SQL

 exec sp_executeSql @SQL

 Set @SQL = 
        'Insert Into @CS(MyChecksum)' + Char(13) + 
        'Select '

 Set @i = 1

 While Exists(
       Select 1
       From   @IntColumns
       Where  IdRecord = @i)
 begin
       Select @ColumnName = ColumnName
       From   @IntColumns
       Where  IdRecord = @i

       Set @SQL = @SQL + Char(13) + 
            CASE WHEN @i = 1 THEN 
                 '    Sum(Cast(IsNull(' + @ColumnName + ',0) as bigint))'
                 ELSE
                 '    + Sum(Cast(IsNull(' + @ColumnName + ',0) as bigint))'
            END

       Set @i = @i + 1
 end

 Set @SQL = @SQL + Char(13) + 
      'From ' + @DatabaseName + '..' + @TableName + ' (NOLOCK)'

 -- print @SQL

 exec sp_executeSql @SQL

 Set @Checksum = (Select Top 1 MyChecksum From @CS)

 Return isnull(@Checksum,0)

END
GO

Rob.. 15

它"通常"无法完成,因为SQL Server将函数视为确定性,这意味着对于给定的输入集,它应始终返回相同的输出.存储过程或动态sql可以是非确定性的,因为它可以更改依赖的外部状态,例如表.

鉴于在SQL服务器中,函数总是具有确定性,从未来的维护角度来看,试图规避这一点并不是一个坏主意,因为它可能会给将来必须支持代码的任何人带来相当大的混淆.



1> Rob..:

它"通常"无法完成,因为SQL Server将函数视为确定性,这意味着对于给定的输入集,它应始终返回相同的输出.存储过程或动态sql可以是非确定性的,因为它可以更改依赖的外部状态,例如表.

鉴于在SQL服务器中,函数总是具有确定性,从未来的维护角度来看,试图规避这一点并不是一个坏主意,因为它可能会给将来必须支持代码的任何人带来相当大的混淆.


SQL服务器函数当然不总是确定性的,getdate()例如是非确定性的(取决于语言)......

2> 小智..:

这是解决方案

解决方案1: 从Function返回动态字符串

Declare @SQLStr varchar(max) 
DECLARE @tmptable table ()
set @SQLStr=dbo.function()
insert into @tmptable
Exec (@SQLStr)

select * from @tmptable

解决方案2: 通过传递参数调用嵌套函数.

推荐阅读
大大炮
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有