※※※※※※※※※※※※※※※※※※※※※
Qiitaと同様の投稿内容となっております。
ご容赦ください。
※※※※※※※※※※※※※※※※※※※※※
C#でSQLiteを扱うプログラムを書いていて、お偉いさんにもらった指摘からどう改良していけばいいかで詰んでるお話。
何をするのか
現存するテーブル「TABLE」に、
・ID:テーブル内の最高値の次の番号
・NAME:TextBoxから入力
・POINT1~3:NumericUpDownから入力
をINSERTでレコードとして追加していくだけなので、単純といえば単純。
とりあえず組んでみた
lang
1/// <summary> 2/// レコードを追加 3/// </summary> 4private void recordAdd() 5{ 6 // 宣言 7 SQLiteConnection cn = null; 8 9 try 10 { 11 // DB接続文字列 12 string connectionString = string.Format("Data Source={0};Version=3;", Application.StartupPath + @"\result.db"); 13 14 // DB Open 15 cn = new SQLiteConnection(connectionString); 16 cn.Open(); 17 18 SQLiteCommand cmd = cn.CreateCommand(); 19 cmd.CommandText = string.Format("INSERT INTO TABLE(ID, NAME, POINT1, POINT2, POINT3) SELECT MAX(ID) + 1, {0}, {1}, {2}, {3} FROM TABLE;", 20 "'" + this.textBox_Name.Text + "'", 21 this.numericUpDown_Point1.Value.ToString(), 22 this.numericUpDown_Point2.Value.ToString(), 23 this.numericUpDown_Point3.Value.ToString()); 24 cmd.ExecuteNonQuery(); 25 } 26 finally 27 { 28 // DBクローズ 29 if (cn != null) 30 { 31 cn.Close(); 32 } 33 } 34}
…とまあ、こんな感じで。実行中も特にエラーは起きなかったので、これで提出すると…。
お偉いさんからの返事
SQLiteはプライマリーキーに数字が割り当てられている>と自動で一番大きな値+1をしてID発行するようになっている。
データがない場合MAXはnullになることを考慮しているかは不明だが、たまたまうまく動作している原因となっている。
nullを考慮したSQLもしくはプログラムを組んでほしい(他のDBでも同じようなSQLを書いてしまうのを防ぐため)。
…どゆこと?
MAX(ID) + 1
と書くのがよろしくないのか…?
テーブルが空であるときにIDの最高値を見てもnullだから、SQLiteはともかく他のDBで同様に動作する保証はないので、
他のDBでも問題なく動作しそうなコードに改良しろ、ということか…。
当然、INSERTするIDはDBから取得して決定するのが普通だろうから、
DBの中身が空であるかどうかを判定すればいいのか。
で、どっちをいじるべきかな…と迷いだす。
ちょっと考えればif文とかで強引に組めるんだろうけど、SQL文ちょっといじるだけで突破できるならそうしたいよねっていう。
…どなたかご教授ください…(;꒪ ω꒪)
追記 3/18 11:30
お偉いさんに、
IDを指定せずにオートインクリメントで付けいていくのは、仕様に甘えている。
たしかに普通はオートインクリメントを設定しておくものだが、
今回に限りその設定がないものとして考えてみてくれ。
とのお言葉をいただいて参りました。なんじゃそりゃ。
bm000999さんのコメントにある、ISNULL(MAX(ID) + 1, 0)
を利用してみようと思いましたが、そのまま組み込んで、
lang
1INSERT 2 INTO TABLE 3 ( ID 4 , NAME 5 , POINT1 6 , POINT2 7 , POINT3 ) 8SELECT 9 ISNULL(MAX(ID) + 1, 0) 10, {0} /* TextBox */ 11, {1} /* NumericUpDown */ 12, {2} /* NumericUpDown */ 13, {3} /* NumericUpDown */ 14FROM 15 TABLE 16;
としてみたのですが、try-catch
で例外を返されてしまいました。
SQL logic error or missing database near "ISNULL": syntax error
あれ、クエリが間違ってる…?もしかしてINSERT文のときはISNULL
を使えないとか…?
というかそもそもSQLiteにISNULL
って存在するのか…?
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/03/17 20:41