Groups | Blog | Home
all groups > sql server (alternate) > june 2004 >

sql server (alternate) : howto: calling sp_executesql from a function ?


Clausmeyer
6/30/2004 3:03:41 PM
I want to execute a dynamically generated sql-statement
from inside an user-defined-function. Calling functions and
extended stored-procs is allowed so I tried sp_executesql
as well as sp_prepare/sp_execute ....

but both fail with an error 'only functions and extended stored-procs
may be called from inside a function.'

any idea where I might be wrong ?

thx in advance,
Joerg


--
*************************************************************
Joerg Clausmeyer
Medizinische Informatik und Datenmanagement

CHARITE - Universitätsmedizin Berlin
*************************************************************

Erland Sommarskog
6/30/2004 9:47:18 PM
Clausmeyer (jcl@charite.de) writes:
[quoted text, click to view]

You cannot use dynamic SQL from a function, neither can you call
stored procedures.

Functions in SQL Server are designed from the perspective that may not
change state in the database, therefore you are quite restricted in
what you can do.

If you post more about your actual business problem, you may get
suggestions on how to address it.


--
Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se

Books Online for SQL Server SP3 at
Clausmeyer
7/1/2004 2:27:10 PM

[quoted text, click to view]

thanks for replying,
I'm a bit confused now. Both my docs and the errormessage I get
tell me, that it is allowed to call functions and extended procs from
a function.
sp_executesql is an extended proc, or am I wrong?


[quoted text, click to view]

the function itself is called from a rather complex select-statement.
It shall take 2 params identifying row and column of a fixed table,
build a select-statement and return the selected value.
simplified code below:


CREATE FUNCTION dbo.udf_GetDataValue
(
@RowId int,
@Column varchar(50)
)
RETURNS varchar(50)
AS
BEGIN

declare @sql nvarchar(255)
declare @value varchar(50)

select @sql = 'select ' + @Column + ' from t_OPs where [Id] = ' +
convert(varchar(20), @RowId)
exec [master].dbo.sp_executesql @sql

RETURN
(@value)

END


--
*************************************************************
Joerg Clausmeyer
Medizinische Informatik und Datenmanagement

CHARITE - Universitätsmedizin Berlin
*************************************************************

Erland Sommarskog
7/1/2004 9:46:00 PM
Clausmeyer (jcl@charite.de) writes:
[quoted text, click to view]

Maybe it is. It is still not permitted, and for a very good reason.

[quoted text, click to view]

And if your dynamic SQL had performed updates or deletes on the
tables involved in the querey, what had you expected to happen?

As for the problem, what's wrong with:

SELECT @retval = CASE @column
WHEN 'col1' THEN col1
WHEN 'col2' THEN col2
...
END
FROM tbl
WHERE rowid = @rowid

However, I like to add a few more comments.

1) Beware that UDF can severly affect your performance, since the query
might be in practice be converted to a cursor begind the scenes.

2) The fact that want to do such a thing, indicates that your data
model is flawed. Maybe the column names you pass into the query
should have been key values in a table with a two-column key (@rowid,
@column)

3) Beware that if an error occurs in a user-defined function, there is
no way to catch it. The statement that calls the UDF will be terminated,
but @@error will be 0, so you don't if things well or not. Had your
dynamic SQL solution been possible, and you had feed it a invalid
column name, you would not have known.

4) 'select ' + @Column + ' from t_OPs where [Id] = ' +
convert(varchar(20), @RowId) is better written:

SELECT @sql = 'select ' + @Column + ' from t_OPs where [Id] =
convert(varchar(20), @RowId)
EXEC sp_executesql @sql, N'int @RowId', @RowId = @RowId


--
Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se

Books Online for SQL Server SP3 at
AddThis Social Bookmark Button