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

发布于 2024-10-08 01:00:08 字数 1492 浏览 4 评论 0原文

我创建了一个用户定义函数,它根据另一个表中的某些值返回 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

这非常简单:你不能使用动态SQL来自用 T-SQL 编写的使用定义函数。这是因为您不允许在 UDF 中执行任何可能更改数据库状态的操作(因为 UDF 可能作为查询的一部分被调用)。由于您可以通过动态 SQL 执行任何操作(包括更新),因此不允许动态 SQL 的原因显而易见。

来源:动态 SQL 的诅咒与祝福

I have made a User-Defined Function that returns a WHERE statement based on some values in another table.

WHERE dbo.tblGeneralLedgerEntry.accountID = 1210

Then I use a stored procedure to construct and execute the SELECT statement:

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

Everything runs successfully but I am getting empty results. When I just execute the statement without using the function I will get results, so I know that is not the problem.

Stored procedure (@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 )

Using MS-SQL with Access 2010 in an ADP.

What am I doing wrong?

Thanks!

EDIT

The reason it was not working is apperantly is because it is not supposed to:

Dynamic SQL in User-Defined Functions

This very simple: you cannot use dynamic SQL from used-defined functions written in T-SQL. This is because you are not permitted do anything in a UDF that could change the database state (as the UDF may be invoked as part of a query). Since you can do anything from dynamic SQL, including updates, it is obvious why dynamic SQL is not permitted.

Source:The Curse and Blessings of Dynamic SQL

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

神也荒唐 2024-10-15 01:00:08

斯特凡;

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

例如

DECLARE @sql_select nvarchar(1000)

IF (@reportID = 10000) BEGIN
选择@sql_select=
'SELECT dbo.tblGeneralLedgerEntry.*, dbo.tblJournalAccountHead.description 作为标题 ' +
'来自 dbo.tblGeneralLedgerEntry ' +
'内连接 dbo.tblJournalAccountHead ON dbo.tblGeneralLedgerEntry.documentReference = dbo.tblJournalAccountHead.documentReference ' + dbo.reportWhere(@reportID)
结束

执行(@sql)

-亚伦
MCITP:DBA

Stefan;

I think that you have that backwards. UDF are allowed in dynamic-SQL. Dynamic-SQL is not allowed in UDFs.

For example

DECLARE @sql_select nvarchar(1000)

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

EXEC ( @sql )

-Aaron
MCITP: DBA

疯狂的代价 2024-10-15 01:00:08

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

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

使用 as:

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

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

I do not understand in your question, where the stored procedure, where the function, how they are supposed to be. I think there is enough of a function that returns a table value, for example:

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

Using as:

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

In this case the UDF dbo.ReportWhere must return an integer scalar value

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文