执行存储过程内联,类似于 UDF?
Posted
技术标签:
【中文标题】执行存储过程内联,类似于 UDF?【英文标题】:Execute a Stored Procedure Inline, similar to a UDF? 【发布时间】:2013-02-07 12:38:56 【问题描述】:我有一个类似这样的结构:
Company
(
CompanyID
CompanyLastTransactionNo
)
Transaction
(
TransactionID
CompanyID
CompanyTransactionNo
TransactionAmount
)
那么我有一个程序可以执行以下操作:
INSERT INTO Transaction
(CompanyID, CompanyTransactionNo, TransactionAmount)
SELECT
CompanyID,
fn_GetNextCompanyTrancationNo(CompanyID),
TransactionAmount
FROM
LoadingTable
CREATE FUNCTION [dbo].[fn_GetNextCompanyTrancationNo]
(
@CompanyID CHAR(10)
)
RETURNS INT
AS
BEGIN
DECLARE @trxno int
DECLARE @trxnoNew int
SELECT @trxno = CompanyLastTransactionNo
FROM dbo.Company
WHERE ID = @CompanyID;
SET @trxnoNew = @trxno + 1;
UPDATE dbo.Company
SET CompanyLastTransactionNo = @trxnoNew
WHERE CompanyID = @CompanyID;
RETURN @trxno
END
编译时我得到:
消息 443,级别 16,状态 15,过程 fns_fn_GetNextCompanyTrancationNo,第 19 行 在函数中无效使用副作用运算符“UPDATE”。
呃。完全忘记了。
所以这是我的问题,有没有办法将存储过程用作内联函数,类似于这个?也许这是一个不好的方法?
我有点卡在我的表上,或者我会使用一个序列来获取下一个数字?
【问题讨论】:
您提到序列:您使用的是 SQL Server 2012 吗? 不,使用 2008 R2。是的,我知道序列要到 2012 年才可用。但我应该澄清一下。现在是 2008R2。 【参考方案1】:这是个坏主意。具有副作用的 UDF 的问题是您无法控制在 select 语句的上下文中何时/如何调用它。
考虑以下几点:
CREATE TABLE t (id INT )
INSERT INTO t (id) values (1)
INSERT INTO t (id) values (2)
INSERT INTO t (id) values (3)
INSERT INTO t (id) values (4)
INSERT INTO t (id) values (5)
INSERT INTO t (id) values (6)
INSERT INTO t (id) values (7)
INSERT INTO t (id) values (8)
INSERT INTO t (id) values (9)
INSERT INTO t (id) values (10)
SELECT id, dbo.myUDF() FROM t WHERE t.id <= 3 and dbo.myUDF() = @someValue
myUDF() 被调用了多少次? 10? 3? 13?还是20?
具体来说,SQL 语言标准中没有规定应用谓词的顺序。
【讨论】:
嗯。我希望这样做,坦率地说,如果这是在 UDF 中禁止副作用的唯一原因,这是一个可怕的原因。任何 SQL 实现中都有各种各样的东西以未定义的顺序执行,我们使用它们。我想做的只是SELECT id, dbo.myUDF(id) FROM t
。我会用一个过程循环执行它,但这会更干净。以上是关于执行存储过程内联,类似于 UDF?的主要内容,如果未能解决你的问题,请参考以下文章