我将在这个问题的序言中说,我不认为它是可以解决的。我也有一个解决方法,我可以使用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
答案 0 :(得分:15)
它“通常”无法完成,因为SQL Server将函数视为确定性的,这意味着对于给定的一组输入,它应始终返回相同的输出。存储过程或动态sql可以是非确定性的,因为它可以更改依赖的外部状态,例如表。
鉴于在SQL服务器中,函数总是具有确定性,从未来的维护角度来看,试图规避这一点并不是一个坏主意,因为它可能会对将来必须支持代码的任何人造成相当大的混淆。
答案 1 :(得分:2)
您可以通过调用扩展存储过程解决此问题,并解决所有随之而来的麻烦和安全问题。
http://decipherinfosys.wordpress.com/2008/07/16/udf-limitations-in-sql-server/
http://decipherinfosys.wordpress.com/2007/02/27/using-getdate-in-a-udf/
答案 2 :(得分:0)
因为函数必须与查询优化器很好地协作,所以对它们有很多限制。 This link指的是一篇深入讨论UDF局限性的文章。
答案 3 :(得分:0)
谢谢大家的回复。
Ron:仅供参考,使用它会引发错误。
我同意不按照我原先的意图做最好的解决方案,我决定走另一条路。我的两个选择是在存储过程中使用sum(cast(BINARY_CHECKSUM(*) as float))
或输出参数。在单元测试每个单元的速度之后,我决定使用sum(cast(BINARY_CHECKSUM(*) as float))
来获得每个表数据的可比校验和值。