{"id":15075243,"url":"https://github.com/aergoio/sqlite-stored-procedures","last_synced_at":"2025-08-24T16:14:52.764Z","repository":{"id":143671991,"uuid":"176647907","full_name":"aergoio/sqlite-stored-procedures","owner":"aergoio","description":"Stored Procedures for SQLite","archived":false,"fork":false,"pushed_at":"2025-01-08T05:40:42.000Z","size":14051,"stargazers_count":71,"open_issues_count":1,"forks_count":3,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-13T08:41:10.277Z","etag":null,"topics":["sqlite","sqlite3","stored-procedures"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aergoio.png","metadata":{"files":{"readme":"README-ja.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-03-20T03:45:44.000Z","updated_at":"2025-04-03T06:57:08.000Z","dependencies_parsed_at":"2025-01-17T11:09:58.540Z","dependency_job_id":null,"html_url":"https://github.com/aergoio/sqlite-stored-procedures","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/aergoio/sqlite-stored-procedures","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aergoio%2Fsqlite-stored-procedures","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aergoio%2Fsqlite-stored-procedures/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aergoio%2Fsqlite-stored-procedures/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aergoio%2Fsqlite-stored-procedures/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aergoio","download_url":"https://codeload.github.com/aergoio/sqlite-stored-procedures/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aergoio%2Fsqlite-stored-procedures/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271901696,"owners_count":24841121,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-24T02:00:11.135Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["sqlite","sqlite3","stored-procedures"],"created_at":"2024-09-25T03:49:37.553Z","updated_at":"2025-08-24T16:14:52.729Z","avatar_url":"https://github.com/aergoio.png","language":"C","funding_links":[],"categories":["other"],"sub_categories":[],"readme":"\u003ca href=\"https://aergo.io\"\u003e\u003cimg height=\"20%\" width=\"20%\" src=\"https://user-images.githubusercontent.com/7624275/225525458-5aaf74d3-286c-483d-ad2a-9eadc9dbe9ac.png\"\u003e\u003c/a\u003e\nが提供する：\n\n# SQLiteのストアドプロシージャ\n\n\u003cp align=\"right\"\u003e\u003ca href=\"https://github.com/aergoio/sqlite-stored-procedures/blob/master/README.md\"\u003eEnglish\u003c/a\u003e | \u003ca href=\"https://github.com/aergoio/sqlite-stored-procedures/blob/master/README-zh.md\"\u003e中文\u003c/a\u003e | \u003ca href=\"https://github.com/aergoio/sqlite-stored-procedures/blob/master/README-ru.md\"\u003eРусский\u003c/a\u003e\u003c/p\u003e\n\n例の手順：\n\n```\nCREATE PROCEDURE add_new_sale(@products) BEGIN \n INSERT INTO sales (time) VALUES (datetime('now'));\n SET @sale_id = last_insert_rowid();\n FOREACH @prod_id, @qty, @price IN @products DO \n   INSERT INTO sale_items (sale_id, prod_id, qty, price) VALUES (@sale_id, @prod_id, @qty, @price);\n END LOOP;\n RETURN @sale_id;\nEND;\n```\n\nそして、それを呼び出す方法：\n\n```sql\nCALL add_new_sale(ARRAY( ARRAY('DJI Avata',1,1168.00), ARRAY('iPhone 14',1,799.90), ARRAY('iWatch',2,249.99) ));\n```\n\n\n## でも、なぜ？\n\n確かに、ほとんどの場合、SQLiteはこれを必要としません。なぜなら、アプリケーションはローカルデータベース上で\nSQLコマンドを直接実行できるからです！\n\nしかし、ストアドプロシージャは、**レプリケートされたSQLite**を使用する場合に便利であり、主に\nレプリカが異なるプログラミング言語で使用される場合です。\n\nこの機能は、SQLiteデータベースの最も\n安全なレプリケーションである[AergoLite](https://aergolite.aergo.io/)に追加されます。手順は、この場合ほとんどスマート\nコントラクトとして機能します。\n\nもう1つの潜在的な使用法は、`node-sqlite3`を使用したNode.jsで、一部の種類の\nトランザクションが管理しにくい場合です。\n\n\n## サポートされているコマンド\n\n以下のコマンドが利用可能です：\n\n- DECLARE\n- SET\n- IF .. ELSEIF .. ELSE .. END IF\n- LOOP .. BREAK .. CONTINUE .. END LOOP\n- FOREACH .. BREAK .. CONTINUE .. END LOOP\n- CALL\n- RETURN\n- RAISE EXCEPTION\n\n\n## DECLARE\n\n`DECLARE` ステートメントは、変数を宣言するために使用されます。変数はプロシージャにローカルであり、プロシージャの外部からは見えません。\n\n```sql\nDECLARE @variable {affinity}\n```\n\n親和性はオプションです。指定された場合、次のいずれかになります。\n\n- `TEXT`\n- `INTEGER`\n- `REAL`\n- `BLOB`\n\n親和性は、変数が式で使用されるときに、変数の値を指定された親和性に変換するために使用されます。\n\n現在のバージョンでは、親和性が必要ない場合は変数を宣言する必要はありません。\n新しい変数を作成するには、`SET` コマンドを使用してください。\n\n\n## SET\n\n`SET` ステートメントは、1つ以上の変数に値を割り当てるために使用されます。\n\nこの形式があります。\n\n```\nSET @variable = {expression};\nSET @variable1 [, @variable2...] = {SQL command};\nSET @variable = ({SQL command});\n```\n\n最初の形式は、変数に値を割り当てるために使用されます。値は式の結果です。\n\n2番目の形式は、SQLコマンドの結果を1つ以上の変数に割り当てるために使用されます。SQLコマンドは単一の行を返さなければなりません。返された列ごとに1つの変数が必要です。\n\n3番目の形式（SQLコマンドの周りに括弧を使用）は、複数の行の結果を1つの変数に割り当てるために使用されます。\n\nサポートされているSQLコマンドは次のとおりです。\n\n- `SELECT`\n- `INSERT` with `RETURNING` clause\n- `UPDATE` with `RETURNING` clause\n- `DELETE` with `RETURNING` clause\n- `CALL`\n\n以下はいくつかの例です。\n\n```sql\nSET @value = 12.5;\nSET @arr = ARRAY(11, 2.5, 'hello!', x'6120622063');\nSET @result = @qty * @price;\nSET @name, @price = SELECT name, price FROM products WHERE id = 123;\nSET @ids = (SELECT id FROM products WHERE price \u003e 250);\nSET @users = (UPDATE users SET active=1 WHERE active=0 RETURNING id, name);\n```\n\n\n## IFブロック\n\n`IF`文は、条件が真の場合に一連の文を実行するために使用されます。\n\n次の形式を持っています。\n\n```sql\nIF {expression} THEN\n...\nELSEIF {expression} THEN\n...\nELSE\n...\nEND IF;\n```\n\n`ELSEIF`と`ELSE`節はオプションです。\n\nネストされた`IF`ブロックがサポートされています。\n\n\n## LOOP\n\nループは、一連の文を複数回実行するために使用されます。\n\n`LOOP`文は次の形式を持っています。\n\n```sql\nLOOP\n...\nEND LOOP;\n```\n\nネストされたループがサポートされています。\n\n`BREAK`文は、ループを終了するために使用されます。\n\n`IF`文と一緒に使用することが一般的です。\n\n```sql\nLOOP\n  ...\n  IF {expression} THEN\n    BREAK;\n  END IF;\n  ...\nEND LOOP;\n```\n\nネストされたループから脱出するには、脱出するループの数を指定します。\n\n```sql\nLOOP\n  ...\n  LOOP\n    ...\n    BREAK 2;   -- 外側のループから脱出\n    ...\n  END LOOP;\n  ...\nEND LOOP;\n```\n\n`CONTINUE`文は、ループの残りをスキップして次の反復を開始するために使用されます。\n\n親ループで続行するには、降りるレベルを指定します。\n\n```sql\nLOOP\n  ...\n  LOOP\n    ...\n    CONTINUE 2;  -- 外側のループで実行を続行\n    ...\n  END LOOP;\n  ...\nEND LOOP;\n```\n\n\n## FOREACH\n\n`FOREACH`文は、値のリストを繰り返し処理するために使用されます。\n\nこの形式があります:\n\n```\nFOREACH @variable [, @variable2...] IN {input} DO\n...\nEND LOOP;\n```\n\n入力は以下のいずれかになります:\n\n- 配列リテラル\n- 配列変数\n- SELECT\n- RETURNING句を含むINSERT\n- RETURNING句を含むUPDATE\n- RETURNING句を含むDELETE\n- CALL\n\nいくつかの例を示します:\n\n* 配列リテラルを使用した場合\n\n```\nCREATE OR REPLACE PROCEDURE sum_array() BEGIN\n SET @sum = 0;\n FOREACH @item IN ARRAY(11,22,33) DO\n   SET @sum = @sum + @item;\n END LOOP;\n RETURN @sum;\nEND\n```\n\n* 配列変数を使用した場合\n\n```\nCREATE OR REPLACE PROCEDURE sum_array(@arr) BEGIN\n SET @sum = 0;\n FOREACH @item IN @arr DO\n   SET @sum = @sum + @item;\n END LOOP;\n RETURN @sum;\nEND\n```\n\nもっと役に立つ例:\n\n```\nCREATE PROCEDURE add_new_sale(@products) BEGIN \n INSERT INTO sales (time) VALUES (datetime('now'));\n SET @sale_id = last_insert_rowid();\n FOREACH @prod_id, @qty, @price IN @products DO \n   INSERT INTO sale_items (sale_id, prod_id, qty, price) VALUES (@sale_id, @prod_id, @qty, @price);\n END LOOP;\n RETURN @sale_id;\nEND;\n```\n\n* SELECTを使用した場合\n\n```\nFOREACH @id, @sale_id, @prod, @qty, @price IN SELECT * FROM sale_items DO\n  ...\nEND LOOP;\n```\n\n各変数を指定する代わりに、`FOREACH VALUE`を使用することができます:\n\n```\nFOREACH VALUE IN SELECT * FROM sale_items DO\n  ...\nEND LOOP;\n```\n\n`BREAK`および`CONTINUE`文がサポートされており、ネストされた`FOREACH`ループも使用できます\n\n\n## CALL\n\nストアドプロシージャを呼び出すために使用されます。\n\nこの形式があります：\n\n```sql\nCALL {procedure_name} ([{expression} [, {expression}...]]);\n```\n\n引数は次のいずれかになります：\n\n- リテラル値\n- 変数\n- ARRAYリテラル\n\nいくつかの例を示します：\n\n```sql\nCALL compute(11, 22);\nCALL compute(@val1, @val2);\nCALL add_new_sale(ARRAY( ARRAY('iphone 14',1,1234.00), ARRAY('ipad',1,2345.90), ARRAY('iwatch',2,499.99) ));\n```\n\n`CALL`文は、`SELECT`文と同様に、プロシージャによって返される結果を返します。\n\nプロシージャ内で実行すると、返された値を変数に割り当てることができます：\n\n```sql\nSET @sale_id = CALL add_new_sale(ARRAY( ARRAY('iphone 14',1,1234.00), ARRAY('ipad 12',1,2345.90) ));\n```\n\n\n## RETURN\n\nストアドプロシージャの実行を停止するために使用されます。\n\nまた、呼び出し元に値を返すこともできます。\n\n返される値は次のいずれかになります：\n\n- リテラル値\n- 変数\n- 式\n\nいくつかの例を示します：\n\n```sql\nRETURN 11;\nRETURN @var1, @var2;\nRETURN @var1 + @var2;\nRETURN 11, @var1 + @var2;\n```\n\n\n## RAISE EXCEPTION\n\nストアドプロシージャの実行を停止し、データベースへのすべての書き込みをロールバックし、エラーメッセージを返すために使用されます。\n\nいくつかの例を示します：\n\n```sql\nRAISE EXCEPTION 'some error message';\nRAISE EXCEPTION 'some error message %s %s', @var1, @var2;\n```\n\n\n\n\n## ステータス\n\nこれはベータ版のソフトウェアです。すべてのテストが通っています。バグが見つかった場合は、報告してください。\n\nファイル[test.c](test/test.c)でいくつかの例を確認できます。\n\n\n## ビルドとインストール\n\n```\nmake\nsudo make install\n```\n\n\n## テストの実行\n\n```\nmake test\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faergoio%2Fsqlite-stored-procedures","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faergoio%2Fsqlite-stored-procedures","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faergoio%2Fsqlite-stored-procedures/lists"}