执行从 UDF 返回的语句时出现问题 - 没有结果集

Posted

技术标签:

【中文标题】执行从 UDF 返回的语句时出现问题 - 没有结果集【英文标题】:Problem with executing statement returned from an UDF - no result set 【发布时间】:2010-12-19 16:46:58 【问题描述】:

我创建了一个用户定义函数,它根据另一个表中的某些值返回 WHERE 语句。

WHERE dbo.tblGeneralLedgerEntry.accountID = 1210

然后我使用存储过程来构造和执行SELECT语句:

SELECT dbo.tblGeneralLedgerEntry.*, dbo.tblJournalAccountHead.description As header
FROM dbo.tblGeneralLedgerEntry
INNER JOIN dbo.tblJournalAccountHead ON dbo.tblGeneralLedgerEntry.documentReference = dbo.tblJournalAccountHead.documentReference
WHERE dbo.tblGeneralLedgerEntry.accountID = 1210

一切都运行成功,但我得到的结果是空的。当我只执行语句而不使用函数时,我会得到结果,所以我知道这不是问题。

存储过程(@reportID = 10000)

DECLARE @sql_select nvarchar(1000)

IF (@reportID = 10000) BEGIN 
    SET @sql_select = 
        'SELECT dbo.tblGeneralLedgerEntry.*, dbo.tblJournalAccountHead.description As header ' +
        'FROM dbo.tblGeneralLedgerEntry ' + 
        'INNER JOIN dbo.tblJournalAccountHead ON dbo.tblGeneralLedgerEntry.documentReference = dbo.tblJournalAccountHead.documentReference '
END

DECLARE @sql nvarchar(4000) = @sql_select + dbo.reportWhere(@reportID)

EXEC ( @sql )

在 ADP 中将 MS-SQL 与 Access 2010 结合使用。

我做错了什么?

谢谢!

编辑

它不起作用的原因显然是因为它不应该:

用户定义函数中的动态 SQL

这很简单:您不能从用 T-SQL 编写的使用定义函数中使用动态 SQL。这是因为不允许您在 UDF 中执行任何可能更改数据库状态的操作(因为 UDF 可能作为查询的一部分被调用)。由于您可以从动态 SQL 中执行任何操作,包括更新,因此很明显为什么不允许使用动态 SQL。

Source:The Curse and Blessings of Dynamic SQL

【问题讨论】:

【参考方案1】:

斯特凡;

我认为你有倒退。动态 SQL 中允许使用 UDF。 UDF 中不允许使用 Dynamic-SQL。

例如

声明@sql_select nvarchar(1000)

IF (@reportID = 10000) 开始 选择@sql_select = '选择 dbo.tblGeneralLedgerEntry.*, dbo.tblJournalAccountHead.description 作为标题 ' + '来自 dbo.tblGeneralLedgerEntry ' + '在 dbo.tblGeneralLedgerEntry.documentReference = dbo.tblJournalAccountHead.documentReference' + dbo.reportWhere(@reportID) 上的内部加入 dbo.tblJournalAccountHead 结束

执行(@sql)

-亚伦 MCITP:数据库管理员

【讨论】:

【参考方案2】:

我不明白你的问题,存储过程在哪里,函数在哪里,它们应该如何。我认为有足够的函数返回一个表值,例如:

CREATE FUNCTION dbo.fn_MyFunc(@AccountID int)
returns @Result Table(field1 f1type, ..., Header varchar(50))
as
BEGIN

Insert into @Result(field1 f1type, ..., Header varchar(50))
SELECT dbo.tblGeneralLedgerEntry.*, dbo.tblJournalAccountHead.description As header
FROM dbo.tblGeneralLedgerEntry
INNER JOIN dbo.tblJournalAccountHead ON dbo.tblGeneralLedgerEntry.documentReference = dbo.tblJournalAccountHead.documentReference
WHERE dbo.tblGeneralLedgerEntry.accountID = @AccountID

Return

END

用作:

select * from dbo.fn_MyFunc(dbo.reportWhere(@reportID))

在这种情况下,UDF dbo.ReportWhere 必须返回一个整数标量值

【讨论】:

感谢您的回复,发现动态SQL中不允许使用UDF。

以上是关于执行从 UDF 返回的语句时出现问题 - 没有结果集的主要内容,如果未能解决你的问题,请参考以下文章

在 BigQuery Java UDF 中对数组进行累积求和时出现问题

显示结果中的 Pig Udf

将 pyspark pandas_udf 与 AWS EMR 一起使用时出现“没有名为‘pandas’的模块”错误

方法 my_udf 有返回语句;需要结果类型

通过 jdbc 客户端使用 hive udf 时出现奇怪的错误

如何创建一个接受查询字符串并返回查询结果集的 UDF