Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 Transact-SQL (2000)
 Only functions and extended stored procedures can

Author  Topic 

henrikop
Constraint Violating Yak Guru

280 Posts

Posted - 2006-01-12 : 07:56:51
I try to make a function, it works in Query Analyzer but I get the error : Only functions and extended stored procedures can be executed from within a function.

I need a function that returns a scalar. However the scalar is the result of dynamic SQL. How do I get a function to return a value from dynamic SQL?

Here's some background: I made a table "DataOjects" for every row in dataobjects there's another row in another table with the same guid. So I have a tblPerson, a table tblCar, a table tblFile, all these table have a column with a value that i call a "friendly name". Now, if I have a key from tblDataObject I need to find a friendly name with it. 237267-ABGFD = 'Henri' 36256FA-GH = 'Kia Sportage' etc. Because users can make their own tables I have to use dynamic SQL.

Now if I want a query with all the DataObjects and their friendly names, I recon I need a function to return the friendly name of each dataobject.


ALTER FUNCTION [dbo].[fGetDataObjectTitle] (@guid AS UNIQUEIDENTIFIER)
RETURNS VARCHAR(1000) AS
BEGIN
DECLARE @sql AS NVARCHAR (2000), @DataObjectTypeId UNIQUEIDENTIFIER, @DataTableName NVARCHAR(200), @Title NVARCHAR (1000), @Result NVARCHAR(1000)

SELECT TOP 1 @DataTableName = dt.SQLName, @Title = CASE WHEN dtf1.IsFriendlyName = 1 THEN dtf1.SQLName ELSE dtf2.SQLName END
FROM tblDataObject dob
JOIN tblDataObjectType dot ON dot.guid = dob.DataObjectTypeId
JOIN tblDataTable dt ON dt.guid = dot.DataTableId
LEFT JOIN tblDataTableField dtf1 ON dtf1.DataTableId = dt.guid AND dtf1.IsFriendlyName = 1
LEFT JOIN tblDataTableField dtf2 ON dtf2.DataTableId = dt.guid AND dtf2.SQLName = 'Title'
WHERE dob.guid = @guid

IF @DataTableName IS NULL OR @Title IS NULL
RETURN ''

SET @sql = ' SELECT @Result = ' + @Title + ' FROM ' + @DataTableName + ' WHERE DataObjectId = @guid '

EXEC sp_executesql @sql, N'@guid uniqueidentifier, @Result NVARCHAR (1000) OUT', @guid = @guid, @Result=@Result OUT

RETURN @Result
END



But I keep getting that error....

Can anyone help?



Henri
~~~~
The envious praises me unknowingly

madhivanan
Premature Yak Congratulator

22864 Posts

Posted - 2006-01-12 : 07:59:14
You cant execute Dynamic SQL inside function. Instead use stored procedure to do it

Madhivanan

Failing to plan is Planning to fail
Go to Top of Page

henrikop
Constraint Violating Yak Guru

280 Posts

Posted - 2006-01-12 : 08:22:59
Okee, but how do I make this query :

SELECT guid, dbo.someFunction(guid) FROM tblDataObject

to return

673827 Henri
723877 Kia Sportage
2ggy28 Towermodel

whereby Henri, Kia Sportage, Towemodel are coming from different tables and tablecolumns (It's dynamic). Can I change a function for a stored procedure scalar?

Henri
~~~~
The envious praises me unknowingly
Go to Top of Page

jsmith8858
Dr. Cross Join

7423 Posts

Posted - 2006-01-12 : 09:12:48
I think the error message you are getting is pretty clear:

Only functions and extended stored procedures can be executed from within a function.

SQL Server does not support what you are trying to do.

What you are tryign to do strongly indicates a bad database design if table and/or column names are variable and dynamic SQL is used. In addition, you should never use a UDF in place of JOINS, which is appears that you are doing. If you need assistance, step back and let us know what you are trying to accomplish and we can help you come up with a better way.
Go to Top of Page

henrikop
Constraint Violating Yak Guru

280 Posts

Posted - 2006-01-12 : 09:33:46
It's not that I use it in a join. There's always a tention between "Dynamics" and securtiy, performance, etc.
However, what i did is I made a metadata column (a column not filled by any user), and with a trigger and a sproc I fill this column and change it by every change. The good thing is that I shifted the performance hit at the point of saving data (instead of the performance hit at query time). Bad thing is that I have a redundancy and a possible intigrity problem so I made a job who checks the metadata consistancy when the database load is low.

However, it's a pity that functions cannot use dynamic sql or sprocs...

Henri
~~~~
The envious praises me unknowingly
Go to Top of Page

druer
Constraint Violating Yak Guru

314 Posts

Posted - 2006-01-12 : 14:42:28
Understanding you have 3 different tables that you need to Join to, to get the results. Would it be possible for you to use a UNION ALL to try and pull from all 3 tables (only 1 will probably get the hit unless I'm missing something) inside of your function instead of dynamic sql to pick the table. It will be a performance hit, but assuming you have good indexes the other 2 tables (which don't contain the data you want) should be negligible hits against you. Just a thought.
Go to Top of Page
   

- Advertisement -