执行动态SQL的一个SQLServer 2005功能(Executing dynamic SQL i

2019-07-20 11:36发布

我会说前言这个问题,我不认为这是可以解决的。 我也有一个解决办法,我可以创建与输出实现这个存储过程,它只是更容易代码,我需要使用此功能校验的章节。

此代码将不会因为一起工作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

Answer 1:

它“通常”不能作为SQL Server将用作确定性,这意味着对于一个给定的输入,它应该总是返回相同的输出来完成。 存储过程或动态SQL可以是非确定性的,因为它可以改变外部状态,如表,这是依靠。

鉴于在SQL服务器功能始终是确定的,这将是从未来的维护角度来看一个坏主意,试图绕过这个,因为它会导致任何人谁也支持未来的代码相当大的混乱。



Answer 2:

下面是解

方案1:从函数返回的动态字符串,然后

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

select * from @tmptable

解决方案2:通过使参数调用嵌套函数。



Answer 3:

你可以通过调用扩展存储过程,所有的服务员麻烦和安全问题,解决这个问题。

http://decipherinfosys.wordpress.com/2008/07/16/udf-limitations-in-sql-server/

http://decipherinfosys.wordpress.com/2007/02/27/using-getdate-in-a-udf/



Answer 4:

因为功能必须与查询优化器发挥很好上面有不少的限制。 此链接指的是深入讨论了UDF的局限性的文章。



Answer 5:

谢谢大家的答复。

罗恩:仅供参考,使用将抛出一个错误。

我同意,没有做什么,我本来打算是最好的解决办法,我决定去一个不同的路线。 我的两个选择是使用sum(cast(BINARY_CHECKSUM(*) as float))或输出参数中的存储过程。 之后的每一个单元测试速度,我决定去sum(cast(BINARY_CHECKSUM(*) as float))以获得每个表的数据可比较的校验和值。



文章来源: Executing dynamic SQL in a SQLServer 2005 function