例の手順:
CREATE PROCEDURE add_new_sale(@products) BEGIN
INSERT INTO sales (time) VALUES (datetime('now'));
SET @sale_id = last_insert_rowid();
FOREACH @prod_id, @qty, @price IN @products DO
INSERT INTO sale_items (sale_id, prod_id, qty, price) VALUES (@sale_id, @prod_id, @qty, @price);
END LOOP;
RETURN @sale_id;
END;
そして、それを呼び出す方法:
CALL add_new_sale(ARRAY( ARRAY('DJI Avata',1,1168.00), ARRAY('iPhone 14',1,799.90), ARRAY('iWatch',2,249.99) ));
確かに、ほとんどの場合、SQLiteはこれを必要としません。なぜなら、アプリケーションはローカルデータベース上で SQLコマンドを直接実行できるからです!
しかし、ストアドプロシージャは、レプリケートされたSQLiteを使用する場合に便利であり、主に レプリカが異なるプログラミング言語で使用される場合です。
この機能は、SQLiteデータベースの最も 安全なレプリケーションであるAergoLiteに追加されます。手順は、この場合ほとんどスマート コントラクトとして機能します。
もう1つの潜在的な使用法は、node-sqlite3
を使用したNode.jsで、一部の種類の
トランザクションが管理しにくい場合です。
以下のコマンドが利用可能です:
- DECLARE
- SET
- IF .. ELSEIF .. ELSE .. END IF
- LOOP .. BREAK .. CONTINUE .. END LOOP
- FOREACH .. BREAK .. CONTINUE .. END LOOP
- CALL
- RETURN
- RAISE EXCEPTION
DECLARE
ステートメントは、変数を宣言するために使用されます。変数はプロシージャにローカルであり、プロシージャの外部からは見えません。
DECLARE @variable {affinity}
親和性はオプションです。指定された場合、次のいずれかになります。
TEXT
INTEGER
REAL
BLOB
親和性は、変数が式で使用されるときに、変数の値を指定された親和性に変換するために使用されます。
現在のバージョンでは、親和性が必要ない場合は変数を宣言する必要はありません。
新しい変数を作成するには、SET
コマンドを使用してください。
SET
ステートメントは、1つ以上の変数に値を割り当てるために使用されます。
この形式があります。
SET @variable = {expression};
SET @variable1 [, @variable2...] = {SQL command};
SET @variable = ({SQL command});
最初の形式は、変数に値を割り当てるために使用されます。値は式の結果です。
2番目の形式は、SQLコマンドの結果を1つ以上の変数に割り当てるために使用されます。SQLコマンドは単一の行を返さなければなりません。返された列ごとに1つの変数が必要です。
3番目の形式(SQLコマンドの周りに括弧を使用)は、複数の行の結果を1つの変数に割り当てるために使用されます。
サポートされているSQLコマンドは次のとおりです。
SELECT
INSERT
withRETURNING
clauseUPDATE
withRETURNING
clauseDELETE
withRETURNING
clauseCALL
以下はいくつかの例です。
SET @value = 12.5;
SET @arr = ARRAY(11, 2.5, 'hello!', x'6120622063');
SET @result = @qty * @price;
SET @name, @price = SELECT name, price FROM products WHERE id = 123;
SET @ids = (SELECT id FROM products WHERE price > 250);
SET @users = (UPDATE users SET active=1 WHERE active=0 RETURNING id, name);
IF
文は、条件が真の場合に一連の文を実行するために使用されます。
次の形式を持っています。
IF {expression} THEN
...
ELSEIF {expression} THEN
...
ELSE
...
END IF;
ELSEIF
とELSE
節はオプションです。
ネストされたIF
ブロックがサポートされています。
ループは、一連の文を複数回実行するために使用されます。
LOOP
文は次の形式を持っています。
LOOP
...
END LOOP;
ネストされたループがサポートされています。
BREAK
文は、ループを終了するために使用されます。
IF
文と一緒に使用することが一般的です。
LOOP
...
IF {expression} THEN
BREAK;
END IF;
...
END LOOP;
ネストされたループから脱出するには、脱出するループの数を指定します。
LOOP
...
LOOP
...
BREAK 2; -- 外側のループから脱出
...
END LOOP;
...
END LOOP;
CONTINUE
文は、ループの残りをスキップして次の反復を開始するために使用されます。
親ループで続行するには、降りるレベルを指定します。
LOOP
...
LOOP
...
CONTINUE 2; -- 外側のループで実行を続行
...
END LOOP;
...
END LOOP;
FOREACH
文は、値のリストを繰り返し処理するために使用されます。
この形式があります:
FOREACH @variable [, @variable2...] IN {input} DO
...
END LOOP;
入力は以下のいずれかになります:
- 配列リテラル
- 配列変数
- SELECT
- RETURNING句を含むINSERT
- RETURNING句を含むUPDATE
- RETURNING句を含むDELETE
- CALL
いくつかの例を示します:
- 配列リテラルを使用した場合
CREATE OR REPLACE PROCEDURE sum_array() BEGIN
SET @sum = 0;
FOREACH @item IN ARRAY(11,22,33) DO
SET @sum = @sum + @item;
END LOOP;
RETURN @sum;
END
- 配列変数を使用した場合
CREATE OR REPLACE PROCEDURE sum_array(@arr) BEGIN
SET @sum = 0;
FOREACH @item IN @arr DO
SET @sum = @sum + @item;
END LOOP;
RETURN @sum;
END
もっと役に立つ例:
CREATE PROCEDURE add_new_sale(@products) BEGIN
INSERT INTO sales (time) VALUES (datetime('now'));
SET @sale_id = last_insert_rowid();
FOREACH @prod_id, @qty, @price IN @products DO
INSERT INTO sale_items (sale_id, prod_id, qty, price) VALUES (@sale_id, @prod_id, @qty, @price);
END LOOP;
RETURN @sale_id;
END;
- SELECTを使用した場合
FOREACH @id, @sale_id, @prod, @qty, @price IN SELECT * FROM sale_items DO
...
END LOOP;
各変数を指定する代わりに、FOREACH VALUE
を使用することができます:
FOREACH VALUE IN SELECT * FROM sale_items DO
...
END LOOP;
BREAK
およびCONTINUE
文がサポートされており、ネストされたFOREACH
ループも使用できます
ストアドプロシージャを呼び出すために使用されます。
この形式があります:
CALL {procedure_name} ([{expression} [, {expression}...]]);
引数は次のいずれかになります:
- リテラル値
- 変数
- ARRAYリテラル
いくつかの例を示します:
CALL compute(11, 22);
CALL compute(@val1, @val2);
CALL add_new_sale(ARRAY( ARRAY('iphone 14',1,1234.00), ARRAY('ipad',1,2345.90), ARRAY('iwatch',2,499.99) ));
CALL
文は、SELECT
文と同様に、プロシージャによって返される結果を返します。
プロシージャ内で実行すると、返された値を変数に割り当てることができます:
SET @sale_id = CALL add_new_sale(ARRAY( ARRAY('iphone 14',1,1234.00), ARRAY('ipad 12',1,2345.90) ));
ストアドプロシージャの実行を停止するために使用されます。
また、呼び出し元に値を返すこともできます。
返される値は次のいずれかになります:
- リテラル値
- 変数
- 式
いくつかの例を示します:
RETURN 11;
RETURN @var1, @var2;
RETURN @var1 + @var2;
RETURN 11, @var1 + @var2;
ストアドプロシージャの実行を停止し、データベースへのすべての書き込みをロールバックし、エラーメッセージを返すために使用されます。
いくつかの例を示します:
RAISE EXCEPTION 'some error message';
RAISE EXCEPTION 'some error message %s %s', @var1, @var2;
これはベータ版のソフトウェアです。すべてのテストが通っています。バグが見つかった場合は、報告してください。
ファイルtest.cでいくつかの例を確認できます。
make
sudo make install
make test