前回は、練習用のデータベース sql_practice に、架空の検査値を記録する表 measurements を作りました。列は6つ(id、measured_on、item_name、value_text、value_num、unit)で、中身はまだ空っぽです。
今回は、この表にデータを入れます。使う命令は INSERT です。数値にできない「(-)」のような結果の入れ方と、必須の列を入れ忘れたときにどうなるかも試します。
また、中で bash を打ってしまった
今回の練習でも、第1回で書いた失敗をもう一度やってしまいました。MariaDB の中に入れたことに気づかず、入るためのコマンドを、中でもう一度打ったのです。
MariaDB [sql_practice]> mysql -u practice -p sql_practice -e "SELECT DATABASE();"
-> ^C
-> exit
-> q
-> ;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'mysql -u practice -p sql_practice -e "SELECT DATABASE();"
exit
q' at line 1
MariaDB [sql_practice]>Ctrl + C(^C)も exit も q も、「SQL の続き」として受け取られ、最後の ; でようやく1つの命令として終わりました。中身はでたらめなので ERROR 1064(書き方の誤り)になりますが、何も変わっていません。行頭が MariaDB [sql_practice]> に戻ったので、そのまま練習を続けました。
第1回で書いたとおり、行頭の表示で、今どこにいるかを確かめるのが大事だと、改めて感じました。
INSERT は「構造体に値を入れて、配列に足す」
C で、前回の構造体に値を入れて、配列の空いているところに足すと、次のようになります。
struct measurement m = {
.measured_on = DATE(2026, 9, 1),
.item_name = "血糖",
.value_text = "98",
.value_num = FIXED(98.000),
.unit = "mg/dL",
};
records[count++] = m; /* id は、足した順の通し番号 */SQL では、これを INSERT の1行で頼みます。
| C でやること | SQL の INSERT |
|---|---|
| どの配列に足すか | INSERT INTO measurements |
| どのメンバに入れるか | (measured_on, item_name, …) と列の名前を並べる |
| 入れる値 | VALUES (‘2026-09-01’, ‘血糖’, …) と、列と同じ順に並べる |
| 通し番号 count++ | id は書かない。AUTO_INCREMENT で自動で振られる |
(DATE() と FIXED() は、説明のための書き方です。前回の date_t、fixed_t と同じく、実際の C にはこの名前の型や関数はありません)
データを入れる
① 練習用のユーザーで入る
$ mysql -u practice -p sql_practiceパスワードを入れると、行頭が MariaDB [sql_practice]> に変わります。ここから先は、すべて MariaDB の中で打ちます。
② 1行だけ入れる
INSERT INTO measurements (measured_on, item_name, value_text, value_num, unit)
VALUES ('2026-09-01', '血糖', '98', 98, 'mg/dL');結果の例:
Query OK, 1 row affected (0.005 sec)1 row affected は「1行に影響した」、つまり1行入った、という意味です。
書き方の決まりは、次のとおりです。
- INSERT INTO measurements:
「measurements の表に入れる」という意味 - (measured_on, item_name, value_text, value_num, unit):
値を入れる列の名前。id は書かない(AUTO_INCREMENT で自動で振られる) - VALUES (…):
入れる値。かっこの中の列と、同じ順番で並べる - ‘2026-09-01’、’血糖’、’98’:
日付と文字は ‘ ‘(シングルクォート)で囲む。value_text は文字の列なので、数字でも ’98’ と囲む - 98:
value_num は数値の列なので、囲まずにそのまま書く
③ まとめて何行も入れる
1回の INSERT で、何行もまとめて入れられます。VALUES のあとに、( ) の組を , で区切って並べます。
INSERT INTO measurements (measured_on, item_name, value_text, value_num, unit) VALUES
('2026-09-01', 'CRP', '0.05', 0.05, 'mg/dL'),
('2026-09-01', '尿蛋白', '(-)', NULL, NULL),
('2026-10-01', '血糖', '104', 104, 'mg/dL'),
('2026-10-01', 'CRP', '0.03未満', 0.03, 'mg/dL'),
('2026-10-01', '尿蛋白', '(+-)', NULL, NULL);結果の例:
Query OK, 5 rows affected
Records: 5 Duplicates: 0 Warnings: 0- Records: 5:
入れようとした行の数 - Duplicates: 0:
重複して入らなかった行の数 - Warnings: 0:
値を切り詰めたり、型を合わせたりして、注意が出た行の数。0 なら、書いたとおりに入っている
④ 入ったデータを見る
SELECT * FROM measurements;結果の例:
+----+-------------+-----------+------------+-----------+-------+
| id | measured_on | item_name | value_text | value_num | unit |
+----+-------------+-----------+------------+-----------+-------+
| 1 | 2026-09-01 | 血糖 | 98 | 98.000 | mg/dL |
| 2 | 2026-09-01 | CRP | 0.05 | 0.050 | mg/dL |
| 3 | 2026-09-01 | 尿蛋白 | (-) | NULL | NULL |
| 4 | 2026-10-01 | 血糖 | 104 | 104.000 | mg/dL |
| 5 | 2026-10-01 | CRP | 0.03未満 | 0.030 | mg/dL |
| 6 | 2026-10-01 | 尿蛋白 | (+-) | NULL | NULL |
+----+-------------+-----------+------------+-----------+-------+
6 rows in set (0.000 sec)SELECT * は「全部の列を見る」という意味です。くわしくは次回あつかいます。
id は 1 から 6 まで、入れた順に自動で振られています。value_num は、前回 DECIMAL(10,3) にしたので、98 も 98.000 と、小数点以下3桁で表示されます。

数値にできない結果は、NULL で入れる
尿蛋白の「(-)」や「(+-)」は、数値にできません。そこで、value_text には用紙のとおり ‘(-)’ を入れ、value_num と unit には NULL を入れています。
| 書き方 | 意味 | C でいうと |
|---|---|---|
| NULL | 値がない(空) | NULL を入れたポインタ |
| ‘NULL’ | 「N・U・L・L」という4文字の文字列 | “NULL” という文字列 |
NULL は ‘ ‘ で囲みません。囲むと、ただの文字になってしまいます。表示でも、NULL は「値がない」という意味で NULL と出ます。
「0.03未満」はどう入れたか
CRP の「0.03未満」は、value_text には ‘0.03未満’ と用紙のとおりに入れ、value_num には 0.03 を入れました。グラフに点を打つための数値としては、境目の 0.03 を使う、という決め方です。
ただし、value_num の 0.030 だけを見ると、「ちょうど 0.03」なのか「0.03未満」なのかは分かりません。前回、結果を value_text と value_num の2つの列で持つことにしたのは、こういう値の元の意味を、value_text に残しておくためです。
必須の列を入れ忘れると
前回、value_text は NOT NULL(必ず値を入れる)にしました。わざと value_text を入れずに INSERT してみます。
INSERT INTO measurements (measured_on, item_name) VALUES ('2026-10-01', 'テスト');
SELECT COUNT(*) FROM measurements;結果の例:
ERROR 1364 (HY000): Field 'value_text' doesn't have a default value
+----------+
| COUNT(*) |
+----------+
| 6 |
+----------+
1 row in set (0.000 sec)エラーは「value_text に初期値(default value)がない」という意味です。必ず値を入れる列なのに、値も初期値もないので、入れられなかったということです。
SELECT COUNT(*) は、表の行の数を数える命令です(第5回でくわしくあつかいます)。6 のままなので、エラーになった行は、途中まで入ったりせずに、まったく入っていません。
組み込みでいえば、必須の項目が欠けたコマンドフレームを、受け側がはじいて、メモリに何も書かなかった、という動きです。中途半端なデータが残らないので安心です。
やり直したいときは
練習で入れたデータを全部消して、最初からやり直したいときは、次の命令で表を空にできます。
TRUNCATE TABLE measurements;- TRUNCATE TABLE 表の名前:
表の形(列の定義)は残したまま、中の行を全部消す。id の番号も、次は 1 から振り直しになる
私も、この記事の練習の途中で入れるデータを決め直したので、一度 TRUNCATE で空にしてから、上の ②・③ を入れ直しています。ただし、元に戻すことはできないので、練習用のデータベース以外では使わないようにしています。
まとめと次回予告
| この回で覚えたこと | C でいうと |
|---|---|
| INSERT INTO 表 (列…) VALUES (値…) で1行入れる | 構造体に値を入れて、配列に足す |
| VALUES のあとに ( ) を , で並べると、まとめて入れられる | 配列にまとめてコピーする |
| 文字と日付は ‘ ‘ で囲み、数値はそのまま書く | 文字列リテラルと数値リテラル |
| id は書かずに、自動で振らせる | 通し番号のカウンタ count++ |
| 値がないところは NULL(囲まない) | NULL を入れたポインタ |
| 必須の列が欠けると、行ごと入らない | 欠けたフレームは、受け側ではじく |
表に6行のデータが入りました。次回は、このデータを「見る・絞り込む・並べる」です。SELECT で必要な列だけを見たり、WHERE で日付や項目を絞り込んだり、ORDER BY で並べ替えたりします。
→ データベース編 第4回:見る・絞り込む・並べる
この記事は、シリーズ「組み込みエンジニアの Web 開発入門」の1本です。ほかの回は、シリーズの目次からどうぞ。



コメント