Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Executing dynamic SQL in a SQLServer 2005 function

Tags:

I will preface this question by saying, I do not think it is solvable. I also have a workaround, I can create a stored procedure with an OUTPUT to accomplish this, it is just easier to code the sections where I need this checksum using a function.

This code will not work because of the Exec SP_ExecuteSQL @SQL calls. Anyone know how to execute dynamic SQL in a function? (and once again, I do not think it is possible. If it is though, I'd love to know how to get around it!)

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 
like image 613
AJD Avatar asked Sep 29 '08 20:09

AJD


People also ask

Can we execute dynamic SQL in function?

You can't execute dynamic sql in user defined functions. Only functions and some extended stored procedures can be executed from within a function.

How do I run a dynamic SQL query in SQL Server?

Executing dynamic SQL using sp_executesql sp_executesql is an extended stored procedure that can be used to execute dynamic SQL statements in SQL Server. we need to pass the SQL statement and definition of the parameters used in the SQL statement and finally set the values to the parameters used in the query.

What are the three ways that dynamic SQL can be executed?

What are the three ways that Dynamic SQL can be executed? Writing a query with parameters. Using EXEC. Using sp_executesql.


1 Answers

It "ordinarily" can't be done as SQL Server treats functions as deterministic, which means that for a given set of inputs, it should always return the same outputs. A stored procedure or dynamic sql can be non-deterministic because it can change external state, such as a table, which is relied on.

Given that in SQL server functions are always deterministic, it would be a bad idea from a future maintenance perspective to attempt to circumvent this as it could cause fairly major confusion for anyone who has to support the code in future.

like image 88
Rob Avatar answered Sep 30 '22 04:09

Rob