0

私はこれに似た構造を持っています:

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」の使用が無効です。

DUH。それを完全に忘れました。

これが私の質問です。これと同様に、ストアドプロシージャをインライン関数として使用する方法はありますか?たぶん、これはすべて一緒に悪いアプローチですか?

私は自分が持っているテーブルで立ち往生しているのでしょうか、それとも次の番号を取得するためにシーケンスを使用するのでしょうか?

4

1 に答える 1

0

これは悪い考えです。副作用のある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 言語標準には、述語が適用される順序を規定するものは何もありません。

于 2013-02-08T19:46:08.283 に答える