ID列または HANAシーケンスの使用は許可されていませんが、手動でテーブルの一意の自動インクリメント キーを生成する必要があります。これは、一意のカウンターをテーブルに格納TABLEKEYS
し、実行ごとにインクリメントする、安全で単純なキー生成手順です。
CREATE PROCEDURE NewKey
( IN SeqName NVARCHAR( 32),
OUT NewKey BIGINT
)
AS rec_exists INT;
row_num INT;
BEGIN
SELECT SUM(1) INTO rec_exists
FROM ( SELECT TOP 1 1 FROM TABLEKEYS WHERE "Name" = :SeqName ) T;
IF :rec_exists IS NULL THEN
SELECT COALESCE(SUM(1),0) INTO row_num FROM TABLEKEYS;
INSERT INTO TABLEKEYS("Code", "Name", "U_CurrentKey")
VALUES (row_num, :SeqName, -1 );
END IF;
UPDATE TABLEKEYS SET "U_CurrentKey" = "U_CurrentKey" + 1
WHERE "Name" = :SeqName;
SELECT "CurrentKey" INTO NewKey FROM TABLEKEYS
WHERE "Name" = :SeqName;
END;
100 の同時接続から集中的に呼び出された場合でも、どのような状況でも 2 つの同一のキーを返さないように、信頼性を高めるにはどうすればよいですか? MSSQL Server では、その本体をトランザクションでラップし、最初のクエリでロック ヒントをテーブルに適用する必要がありますが、HANA での類似物については知りません。HANA で、テーブルの行が厳密に順次アクセスされるようにする方法はありますか?
Lars によって提案され、Business One ユーザー定義テーブルに適応した修正を含む私の手順:
CREATE PROCEDURE GTGetNewKeyInt
( IN TableName NVARCHAR( 32),
OUT NewKey BIGINT
)
AS cur_key INT;
row_num INT;
row_num_txt VARCHAR(8);
BEGIN
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
END;
SELECT "U_CurrentKey" INTO cur_key FROM "@GTTABLEKEYS"
WHERE "Name" = :TableName
FOR UPDATE;
END;
IF :cur_key IS NULL THEN
LOCK TABLE "@GTTABLEKEYS" IN EXCLUSIVE MODE;
SELECT COALESCE(SUM(1),0) INTO row_num FROM "@GTTABLEKEYS";
row_num_txt = LPAD( CAST( row_num AS varchar ), 8, '0' );
NewKey = 0;
INSERT INTO "@GTTABLEKEYS"("Code", "Name", "U_CurrentKey")
VALUES (row_num_txt, :TableName, :NewKey );
ELSE
NewKey = :cur_key + 1;
UPDATE "@GTTABLEKEYS" SET "U_CurrentKey" = :NewKey
WHERE "Name" = :TableName;
END IF;
END;