プログラミング言語でSQLite始め

SQLの経験がほぼない状態だけど、
Node.js、C<span>#</span>、Python3、HSP3でのSQLiteの扱い方を学んだ。
(一応SQL文のみでの動作も)

Node.jsはなんとなくTypeScriptで書いているので、各自動かす場合は型表記を削除すること。
(多分まとめのPromiseだけ)

# 実行環境
* Windows10 64bit
* Sqlite 3.33.0 2020-08-14
* TypeScript Version 4.0.3
* Node.js v12.18.4
* .NET Core 3.1.402
* Python 3.8.3
* HSP : Hot Soup Processor ver3.5

# 使用ライブラリ
## Node.js
[node-sqlite3](https://github.com/mapbox/node-sqlite3/wiki/API)
下記でインストール。

```sh
> npm i sqlite3
```

## C<span>#</span>
[Microsoft.Data.Sqlite](https://docs.microsoft.com/ja-jp/dotnet/standard/data/sqlite/?tabs=netcore-cli)

```sh
> dotnet add package Microsoft.Data.Sqlite
```

[System.Data.SQLiteとは派生の関係にあり、大よそのAPI機能は一致していそう。](https://docs.microsoft.com/ja-jp/dotnet/standard/data/sqlite/compare)

## Python
[sqlite3](https://docs.python.org/ja/3/library/sqlite3.html)
標準ライブラリなので追加インストール不要。

## HSP
[sqlele](http://spn.php.xdomain.jp/hsp_sqlele.htm)
標準ライブラリなので追加インストール不要。

# データベースの初期化
データベースを開いて、
テーブルがなければテーブルを作って(CREATE)、
アイテムを追加して(INSERT)、
データベースを閉じる。

「ID」列は自動採番(AUTOINCREMENT)を設定。

## SQL
```bash:コマンド
> sqlite3 sqlitest.db < sqlitest.sql
```

```sql
CREATE TABLE IF NOT EXISTS DMCARDS (
	ID INTEGER PRIMARY KEY AUTOINCREMENT,
	NAME TEXT,
	COLOR TEXT,
	COST INTEGER,
	POWER INTEGER
);

INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ラ・ウラ・ギガ','光',1,2000)
INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('アクア・ガード','水',1,2000)
INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ボーン・スライム','闇',1,1000)
INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ブレイズ・クロー','火',1,1000)
INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('スナイプ・モスキート','自然',1,2000)
```

## Node.js
```ts
const sqlite=require("sqlite3");

var db=new sqlite.Database("../sqlitest.db",err=>{
	db.serialize(()=>{
		db.run(`CREATE TABLE IF NOT EXISTS DMCARDS (
			ID INTEGER PRIMARY KEY AUTOINCREMENT,
			NAME TEXT,COLOR TEXT,
			COST INTEGER,
			POWER INTEGER
		)`);

		db.run("INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ラ・ウラ・ギガ','光',1,2000)");
		db.run("INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('アクア・ガード','水',1,2000)");
		db.run("INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ボーン・スライム','闇',1,1000)");
		db.run("INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ブレイズ・クロー','火',1,1000)");
		db.run("INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('スナイプ・モスキート','自然',1,2000)");

		db.close();
	});
});
```

## C<span>#</span>
```cs
using System;
using Microsoft.Data.Sqlite;

class Program{
	static void Main(){
		using(var db=new SqliteConnection("Data Source=../sqlitest.db")){
			db.Open();
			var sql=db.CreateCommand();

			sql.CommandText=@"CREATE TABLE IF NOT EXISTS DMCARDS (
				ID INTEGER PRIMARY KEY AUTOINCREMENT,
				NAME TEXT,
				COLOR TEXT,
				COST INTEGER,
				POWER INTEGER
			)";
			sql.ExecuteNonQuery();

			sql.CommandText="INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ラ・ウラ・ギガ','光',1,2000)";
			sql.ExecuteNonQuery();
			sql.CommandText="INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('アクア・ガード','水',1,2000)";
			sql.ExecuteNonQuery();
			sql.CommandText="INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ボーン・スライム','闇',1,1000)";
			sql.ExecuteNonQuery();
			sql.CommandText="INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ブレイズ・クロー','火',1,1000)";
			sql.ExecuteNonQuery();
			sql.CommandText="INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('スナイプ・モスキート','自然',1,2000)";
			sql.ExecuteNonQuery();
		}
	}
}
```

## Python
```py
import sqlite3

with sqlite3.connect("../sqlitest.db") as db:
	db.row_factory=sqlite3.Row
	sql=db.cursor()

	sql.execute("""CREATE TABLE IF NOT EXISTS DMCARDS (
		ID INTEGER PRIMARY KEY AUTOINCREMENT,
		NAME TEXT,COLOR TEXT,
		COST INTEGER,
		POWER INTEGER
	)""")

	sql.execute("INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ラ・ウラ・ギガ','光',1,2000)")
	sql.execute("INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('アクア・ガード','水',1,2000)")
	sql.execute("INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ボーン・スライム','闇',1,1000)")
	sql.execute("INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ブレイズ・クロー','火',1,1000)")
	sql.execute("INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('スナイプ・モスキート','自然',1,2000)")
```

## HSP
```clj
#runtime "hsp3cl"
#include "sqlele.hsp"

sql_open "../sqlitest.db"

makeTable={"CREATE TABLE IF NOT EXISTS DMCARDS (
	ID INTEGER PRIMARY KEY AUTOINCREMENT,
	NAME TEXT,COLOR TEXT,
	COST INTEGER,
	POWER INTEGER
)"}
sql_q makeTable

sql_q "INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ラ・ウラ・ギガ','光',1,2000)"
sql_q "INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('アクア・ガード','水',1,2000)"
sql_q "INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ボーン・スライム','闇',1,1000)"
sql_q "INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ブレイズ・クロー','火',1,1000)"
sql_q "INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('スナイプ・モスキート','自然',1,2000)"

sql_close
```

# データベースの表示
データベースを開いて、
テーブルを全部表示して(SELECT)、
データベースを閉じる。

## SQL
```sql
SELECT * FROM DMCARDS;
```

## Node.js
```ts
const sqlite=require("sqlite3");

var db=new sqlite.Database("../sqlitest.db",err=>{
	db.serialize(()=>{
		console.log("ID,NAME,COLOR,COST,POWER");
		db.each("SELECT * FROM DMCARDS",(err,row)=>{
			console.log(`${row["ID"]},${row["NAME"]},${row["COLOR"]},${row["COST"]},${row["POWER"]}`);
		});

		db.close();
	});
});
```

## C<span>#</span>
```cs
using System;
using Microsoft.Data.Sqlite;

class Program{
	static void Main(){
		using(var db=new SqliteConnection("Data Source=../sqlitest.db")){
			db.Open();
			var sql=db.CreateCommand();

			sql.CommandText="SELECT * FROM DMCARDS";
			using(var row=sql.ExecuteReader()){
				Console.WriteLine("ID,NAME,COLOR,COST,POWER");
				while(row.Read()){
					Console.WriteLine($"{row["ID"]},{row["NAME"]},{row["COLOR"]},{row["COST"]},{row["POWER"]}");
				}
			}
		}
	}
}
```

## Python
```py
import sqlite3

with sqlite3.connect("../sqlitest.db") as db:
	db.row_factory=sqlite3.Row
	sql=db.cursor()

	print("ID,NAME,COLOR,COST,POWER")
	for row in sql.execute("SELECT * FROM DMCARDS"):
		print(f'{row["ID"]},{row["NAME"]},{row["COLOR"]},{row["COST"]},{row["POWER"]}')

```

## HSP
```clj
#runtime "hsp3cl"
#include "sqlele.hsp"

sql_open "../sqlitest.db"

mes "ID,NAME,COLOR,COST,POWER"
sdim rows
sql_q "SELECT * FROM DMCARDS",rows
repeat stat
	mes sql_v("ID",rows)+","+sql_v("NAME",rows)+","+sql_v("COLOR",rows)+","+sql_i("COST",rows)+","+sql_i("POWER",rows)
	sql_next rows
loop

sql_close
```

# テータベースの変更
データベースを開いて、
テーブルを変更して(UPDATE)、
データベースを閉じる。

## SQL
```sql
UPDATE DMCARDS SET COLOR='白' WHERE COLOR='光';
UPDATE DMCARDS SET COLOR='青' WHERE COLOR='水';
UPDATE DMCARDS SET COLOR='黒' WHERE COLOR='闇';
UPDATE DMCARDS SET COLOR='赤' WHERE COLOR='火';
UPDATE DMCARDS SET COLOR='緑' WHERE COLOR='自然';
```

## Node.js
```ts
const sqlite=require("sqlite3");

var db=new sqlite.Database("../sqlitest.db",err=>{
	db.serialize(()=>{
		db.run("UPDATE DMCARDS SET COLOR='白' WHERE COLOR='光'");
		db.run("UPDATE DMCARDS SET COLOR='青' WHERE COLOR='水'");
		db.run("UPDATE DMCARDS SET COLOR='黒' WHERE COLOR='闇'");
		db.run("UPDATE DMCARDS SET COLOR='赤' WHERE COLOR='火'");
		db.run("UPDATE DMCARDS SET COLOR='緑' WHERE COLOR='自然'");

		db.close();
	});
});
```
　
## C<span>#</span>
```cs
using System;
using Microsoft.Data.Sqlite;

class Program{
	static void Main(){
		using(var db=new SqliteConnection("Data Source=../sqlitest.db")){
			db.Open();
			var sql=db.CreateCommand();

			sql.CommandText="UPDATE DMCARDS SET COLOR='白' WHERE COLOR='光'";
			sql.ExecuteNonQuery();
			sql.CommandText="UPDATE DMCARDS SET COLOR='青' WHERE COLOR='水'";
			sql.ExecuteNonQuery();
			sql.CommandText="UPDATE DMCARDS SET COLOR='黒' WHERE COLOR='闇'";
			sql.ExecuteNonQuery();
			sql.CommandText="UPDATE DMCARDS SET COLOR='赤' WHERE COLOR='赤'";
			sql.ExecuteNonQuery();
			sql.CommandText="UPDATE DMCARDS SET COLOR='緑' WHERE COLOR='自然'";
			sql.ExecuteNonQuery();
		}
	}
}
```

## Python
```py
import sqlite3

with sqlite3.connect("../sqlitest.db") as db:
	db.row_factory=sqlite3.Row
	sql=db.cursor()

	sql.execute("UPDATE DMCARDS SET COLOR='白' WHERE COLOR='光'")
	sql.execute("UPDATE DMCARDS SET COLOR='青' WHERE COLOR='水'")
	sql.execute("UPDATE DMCARDS SET COLOR='黒' WHERE COLOR='闇'")
	sql.execute("UPDATE DMCARDS SET COLOR='赤' WHERE COLOR='火'")
	sql.execute("UPDATE DMCARDS SET COLOR='緑' WHERE COLOR='自然'")
```

## HSP
```clj
#runtime "hsp3cl"
#include "sqlele.hsp"

sql_open "../sqlitest.db"

sql_q "UPDATE DMCARDS SET COLOR='白' WHERE COLOR='光'"
sql_q "UPDATE DMCARDS SET COLOR='青' WHERE COLOR='水'"
sql_q "UPDATE DMCARDS SET COLOR='黒' WHERE COLOR='闇'"
sql_q "UPDATE DMCARDS SET COLOR='赤' WHERE COLOR='火'"
sql_q "UPDATE DMCARDS SET COLOR='緑' WHERE COLOR='自然'"

sql_close
```

# データベースの削除
データベースを開いて、
テーブルが存在すればテーブルを破壊して(DROP)、
データベースを閉じる。

## SQL
```sql
DROP TABLE IF EXISTS DMCARDS;
```

## Node.js
```ts
const sqlite=require("sqlite3");

var db=new sqlite.Database("../sqlitest.db",err=>{
	db.serialize(()=>{
		db.run("DROP TABLE IF EXISTS DMCARDS");

		db.close();
	});
});
```
　
## C<span>#</span>
```cs
using System;
using Microsoft.Data.Sqlite;

class Program{
	static void Main(){
		using(var db=new SqliteConnection("Data Source=../sqlitest.db")){
			db.Open();
			var sql=db.CreateCommand();

			sql.CommandText="DROP TABLE IF EXISTS DMCARDS";
			sql.ExecuteNonQuery();
		}
	}
}
```

## Python
```py
import sqlite3

with sqlite3.connect("../sqlitest.db") as db:
	db.row_factory=sqlite3.Row
	sql=db.cursor()

	sql.execute("DROP TABLE IF EXISTS DMCARDS")
```

## HSP
```clj
#runtime "hsp3cl"
#include "sqlele.hsp"

sql_open "../sqlitest.db"

sql_q "DROP TABLE IF EXISTS DMCARDS"

sql_close
```

# データベース操作まとめ
関数化してここまでのデータベース操作をまとめた。
(SQL文除く。SQLiteでは関数を使えない?)

## SQL
```sql
--データベースを削除
DROP TABLE IF EXISTS DMCARDS;

--データベース(テーブル)を初期化
CREATE TABLE IF NOT EXISTS DMCARDS (
	ID INTEGER PRIMARY KEY AUTOINCREMENT,
	NAME TEXT,COLOR TEXT,
	COST INTEGER,
	POWER INTEGER
);
INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ラ・ウラ・ギガ','光',1,2000);
INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('アクア・ガード','水',1,2000);
INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ボーン・スライム','闇',1,1000);
INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ブレイズ・クロー','火',1,1000);
INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('スナイプ・モスキート','自然',1,2000);

--データベースを表示
SELECT * FROM DMCARDS;
SELECT '--------------------------------------';

--データベースを変更
UPDATE DMCARDS SET COLOR='白' WHERE COLOR='光';
UPDATE DMCARDS SET COLOR='青' WHERE COLOR='水';
UPDATE DMCARDS SET COLOR='黒' WHERE COLOR='闇';
UPDATE DMCARDS SET COLOR='赤' WHERE COLOR='火';
UPDATE DMCARDS SET COLOR='緑' WHERE COLOR='自然';

--データベースを表示
SELECT * FROM DMCARDS;
```

## Node.js
```ts
const sqlite=require("sqlite3");

//データベース(テーブル)を初期化
function makeDB():Promise<void>{
	return new Promise(resolve=>{
		var db=new sqlite.Database("../sqlitest.db",err=>{
			db.serialize(()=>{
				db.run(`CREATE TABLE IF NOT EXISTS DMCARDS (
					ID INTEGER PRIMARY KEY AUTOINCREMENT,
					NAME TEXT,COLOR TEXT,
					COST INTEGER,
					POWER INTEGER
				)`);

				db.run("INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ラ・ウラ・ギガ','光',1,2000)");
				db.run("INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('アクア・ガード','水',1,2000)");
				db.run("INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ボーン・スライム','闇',1,1000)");
				db.run("INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ブレイズ・クロー','火',1,1000)");
				db.run("INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('スナイプ・モスキート','自然',1,2000)");

				db.close(resolve);
			});
		});
	});
}

//データベースを更新
function updateDB():Promise<void>{
	return new Promise(resolve=>{
		var db=new sqlite.Database("../sqlitest.db",err=>{
			db.serialize(()=>{
				db.run("UPDATE DMCARDS SET COLOR='白' WHERE COLOR='光'");
				db.run("UPDATE DMCARDS SET COLOR='青' WHERE COLOR='水'");
				db.run("UPDATE DMCARDS SET COLOR='黒' WHERE COLOR='闇'");
				db.run("UPDATE DMCARDS SET COLOR='赤' WHERE COLOR='火'");
				db.run("UPDATE DMCARDS SET COLOR='緑' WHERE COLOR='自然'");

				db.close(resolve);
			});
		});
	});
}

//データベースを削除
function dropDB():Promise<void>{
	return new Promise(resolve=>{
		var db=new sqlite.Database("../sqlitest.db",err=>{
			db.serialize(()=>{
				db.run("DROP TABLE IF EXISTS DMCARDS");

				db.close(resolve);
			});
		});
	});
}

//データベースを変更
function viewDB():Promise<void>{
	return new Promise(resolve=>{
		var db=new sqlite.Database("../sqlitest.db",err=>{
			db.serialize(()=>{
				console.log("ID,NAME,COLOR,COST,POWER");
				db.each("SELECT * FROM DMCARDS",(err,row)=>{
					console.log(`${row["ID"]},${row["NAME"]},${row["COLOR"]},${row["COST"]},${row["POWER"]}`);
				});

				db.close(resolve);
			});
		});
	});
}

(async function(){
	await dropDB();
	await makeDB();
	await viewDB();
	await updateDB();
	await viewDB();
})();
```
　
## C<span>#</span>
```cs
using System;
using Microsoft.Data.Sqlite;

class Program{
	//データベース(テーブル)を初期化
	static void makeDB(){
		using(var db=new SqliteConnection("Data Source=../sqlitest.db")){
			db.Open();
			var sql=db.CreateCommand();

			sql.CommandText=@"CREATE TABLE IF NOT EXISTS DMCARDS (
				ID INTEGER PRIMARY KEY AUTOINCREMENT,
				NAME TEXT,
				COLOR TEXT,
				COST INTEGER,
				POWER INTEGER
			)";
			sql.ExecuteNonQuery();

			sql.CommandText="INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ラ・ウラ・ギガ','光',1,2000)";
			sql.ExecuteNonQuery();
			sql.CommandText="INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('アクア・ガード','水',1,2000)";
			sql.ExecuteNonQuery();
			sql.CommandText="INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ボーン・スライム','闇',1,1000)";
			sql.ExecuteNonQuery();
			sql.CommandText="INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ブレイズ・クロー','火',1,1000)";
			sql.ExecuteNonQuery();
			sql.CommandText="INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('スナイプ・モスキート','自然',1,2000)";
			sql.ExecuteNonQuery();
		}
	}

	//データベースを変更
	static void updateDB(){
		using(var db=new SqliteConnection("Data Source=../sqlitest.db")){
			db.Open();
			var sql=db.CreateCommand();

			sql.CommandText="UPDATE DMCARDS SET COLOR='白' WHERE COLOR='光'";
			sql.ExecuteNonQuery();
			sql.CommandText="UPDATE DMCARDS SET COLOR='青' WHERE COLOR='水'";
			sql.ExecuteNonQuery();
			sql.CommandText="UPDATE DMCARDS SET COLOR='黒' WHERE COLOR='闇'";
			sql.ExecuteNonQuery();
			sql.CommandText="UPDATE DMCARDS SET COLOR='赤' WHERE COLOR='赤'";
			sql.ExecuteNonQuery();
			sql.CommandText="UPDATE DMCARDS SET COLOR='緑' WHERE COLOR='自然'";
			sql.ExecuteNonQuery();
		}
	}

	//データベースを削除
	static void dropDB(){
		using(var db=new SqliteConnection("Data Source=../sqlitest.db")){
			db.Open();
			var sql=db.CreateCommand();

			sql.CommandText="DROP TABLE IF EXISTS DMCARDS";
			sql.ExecuteNonQuery();
		}
	}

	//データベースを表示
	static void viewDB(){
		using(var db=new SqliteConnection("Data Source=../sqlitest.db")){
			db.Open();
			var sql=db.CreateCommand();

			sql.CommandText="SELECT * FROM DMCARDS";
			using(var row=sql.ExecuteReader()){
				Console.WriteLine("ID,NAME,COLOR,COST,POWER");
				while(row.Read()){
					Console.WriteLine($"{row["ID"]},{row["NAME"]},{row["COLOR"]},{row["COST"]},{row["POWER"]}");
				}
			}
		}
	}

	static void Main(){
		dropDB();
		makeDB();
		viewDB();
		updateDB();
		viewDB();
	}
}
```

## Python
```py
import sqlite3

#データベース(テーブル)を初期化
def makeDB():
	with sqlite3.connect("../sqlitest.db") as db:
		db.row_factory=sqlite3.Row
		sql=db.cursor()

		sql.execute("""CREATE TABLE IF NOT EXISTS DMCARDS (
			ID INTEGER PRIMARY KEY AUTOINCREMENT,
			NAME TEXT,COLOR TEXT,
			COST INTEGER,
			POWER INTEGER
		)""")

		sql.execute("INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ラ・ウラ・ギガ','光',1,2000)")
		sql.execute("INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('アクア・ガード','水',1,2000)")
		sql.execute("INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ボーン・スライム','闇',1,1000)")
		sql.execute("INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ブレイズ・クロー','火',1,1000)")
		sql.execute("INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('スナイプ・モスキート','自然',1,2000)")

#データベースを変更
def updateDB():
	with sqlite3.connect("../sqlitest.db") as db:
		db.row_factory=sqlite3.Row
		sql=db.cursor()

		sql.execute("UPDATE DMCARDS SET COLOR='白' WHERE COLOR='光'")
		sql.execute("UPDATE DMCARDS SET COLOR='青' WHERE COLOR='水'")
		sql.execute("UPDATE DMCARDS SET COLOR='黒' WHERE COLOR='闇'")
		sql.execute("UPDATE DMCARDS SET COLOR='赤' WHERE COLOR='火'")
		sql.execute("UPDATE DMCARDS SET COLOR='緑' WHERE COLOR='自然'")

#データベースを削除
def dropDB():
	with sqlite3.connect("../sqlitest.db") as db:
		db.row_factory=sqlite3.Row
		sql=db.cursor()

		sql.execute("DROP TABLE IF EXISTS DMCARDS")

#データベースを表示
def viewDB():
	with sqlite3.connect("../sqlitest.db") as db:
		db.row_factory=sqlite3.Row
		sql=db.cursor()

		print("ID,NAME,COLOR,COST,POWER")
		for row in sql.execute("SELECT * FROM DMCARDS"):
			print(f'{row["ID"]},{row["NAME"]},{row["COLOR"]},{row["COST"]},{row["POWER"]}')

if __name__=="__main__":
	dropDB()
	makeDB()
	viewDB()
	updateDB()
	viewDB()
```

## HSP
```clj
#runtime "hsp3cl"
#include "sqlele.hsp"

#module Program
	;データベース(テーブル)を初期化
	#deffunc makeDB
		sql_open "../sqlitest.db"

		makeTable={"CREATE TABLE IF NOT EXISTS DMCARDS (
			ID INTEGER PRIMARY KEY AUTOINCREMENT,
			NAME TEXT,COLOR TEXT,
			COST INTEGER,
			POWER INTEGER
		)"}
		sql_q makeTable

		sql_q "INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ラ・ウラ・ギガ','光',1,2000)"
		sql_q "INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('アクア・ガード','水',1,2000)"
		sql_q "INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ボーン・スライム','闇',1,1000)"
		sql_q "INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('ブレイズ・クロー','火',1,1000)"
		sql_q "INSERT INTO DMCARDS (NAME,COLOR,COST,POWER) VALUES ('スナイプ・モスキート','自然',1,2000)"

		sql_close
	return

	;データベースを変更
	#deffunc updateDB
		sql_open "../sqlitest.db"

		sql_q "UPDATE DMCARDS SET COLOR='白' WHERE COLOR='光'"
		sql_q "UPDATE DMCARDS SET COLOR='青' WHERE COLOR='水'"
		sql_q "UPDATE DMCARDS SET COLOR='黒' WHERE COLOR='闇'"
		sql_q "UPDATE DMCARDS SET COLOR='赤' WHERE COLOR='火'"
		sql_q "UPDATE DMCARDS SET COLOR='緑' WHERE COLOR='自然'"

		sql_close
	return

	;データベースを削除
	#deffunc dropDB
		sql_open "../sqlitest.db"

		sql_q "DROP TABLE IF EXISTS DMCARDS"

		sql_close
	return

	;データベースを表示
	#deffunc viewDB
		sql_open "../sqlitest.db"

		mes "ID,NAME,COLOR,COST,POWER"
		sdim rows
		sql_q "SELECT * FROM DMCARDS",rows
		repeat stat
			mes sql_v("ID",rows)+","+sql_v("NAME",rows)+","+sql_v("COLOR",rows)+","+sql_i("COST",rows)+","+sql_i("POWER",rows)
			sql_next rows
		loop

		sql_close
	return

	#deffunc main
		dropDB
		makeDB
		viewDB
		updateDB
		viewDB
	return
#global

main
```

# 感想とか補足
以上、SQLiteを試してみた結果でした。

INSERTとかUPDATEはループで注ぎ込んだ方が見栄えが綺麗な気がするけど、動作の確認が主なので今回はひたすら愚直に。
最後のまとめも関数毎にデータベース開いて閉じているのも意味はないはず。

言語に関する感想はライブラリの使用によるところが近い。多分。
特にSELECT文は返り値があるためライブラリの仕様の違いがよく目立つ。

## SQL
普通の手続き型言語と全然書き方が違って慣れない…
if文があってfor文があって関数があってというのが、普通の言語だけどSQLでは違う考え方を要求されるのが難しい。

SQLにおけるSELECT文はprint文であり、foreach文のようである感じでよくわかってない。
多分、filterを掛けてmap処理してるのがイメージなのかな。

## Node.js
非同期が最大の敵。
db.serialize()の外での取り扱いにしなければならない。
あとはdb.closeはdb.serialize()に突っ込んでも同期化されないっぽいので注意する。

おそらく、SELECT文専用だと思われるdb.each()は便利。
どこかでbreakできないので不便といわれているのも見たけれど。
(その時はdb.all()を使うといいみたい)

## C<span>#</span>
とにかく冗長。
SQL文の入力と実行が必ず分離されるのがしんどい。
あとはSQLに値を与える方法としてパラメーターという方法があるけど、
かえって冗長になりそうだったので今回は使うのをやめた。

## Python
かなり簡潔で書きやすいと思った。
SELECT文の返り値の処理だけは最初戸惑ったけど…
(普通にやってるとタプルが返ってくる
db.commit()はなぜか使わなくても大丈夫だった。

## HSP
もしかしたら一番シンプル。
唯一オブジェクト指向でない言語なので同時に複数のデータベースを開くことができないのがおそらく難点。

SELECT文は受け取った値を自力でイテレーターを回す感じ。
(VBA,VBSのDir()とかが近いかもしれない)

あとは「#cmpopt init 1」を使うとコケるのでそれは注意。