2009/09/01(Tue) 11:46:17 編集(投稿者)
■No40679 (もんたな さん) に返信
> Acmd.CommandText = "INSERT INTO t_TRN_HDT_DAT(PROC_BAR, DELI_CD, HDT_IN_DT, IMP_DT) " _
> & "VALUES('" & Bar & "', '" & Code & "', #" & Taking & "#, " _
> & "#" & Now().ToString("yyyy/MM/dd HH:mm:ss") & "#)"
> と書き直したら思ったようにデータがインサートされました。
コントロールパネルの地域設定(地域と言語のオプション)で、日付を「和暦」にされていたり、
日付区切りの "/" や 時刻区切りの ":" を別の文字に変更されていると、この SQL は失敗します。
OS 設定に依存したコードにならないよう、Now.ToString の際には、
Dim s1 As String = Now().ToString("yyyy/MM/dd HH:mm:ss")
ではなく、
'Imports System.Globalization
Dim s2 As String = Now().ToString("MM\/dd\/yyyy HH\:mm\:ss", CultureInfo.InvariantCulture)
Dim s3 As String = Now().ToString("yyyy\/MM\/dd HH\:mm\:ss", CultureInfo.InvariantCulture)
などの構文を使うことをお奨めしておきます。
逆に言うと、開発したアプリにこういった問題が含まれているかどうかを検証するために、
テスト項目に、地域設定を通常以外の設定にした状態でのテストを含めておくことをお奨めします。
(利用者によっては、年を西暦から和暦表示に変更する方もおられますから)
>>こういう場合には、データを文字列として埋め込むのではなく、パラメータ クエリにした方が無難ですよ。
> これってどういうことでしょうか?
パラメータ クエリとは、Access で言うところの PARAMETERS を使った実装です。
ADO.NET においては、OleDbParameter 等を通じて操作します。
たとえば、このような実装になります。
' PARAMETERS 宣言を用いたパラメータ クエリ。
' http://office.microsoft.com/ja-jp/access/HP010322601041.aspx
'sql = "PARAMETERS Bar TEXT(11), Code TEXT(2), Taking DATE;" _
' & "INSERT INTO t_TRN_HDT_DAT (PROC_BAR, DELI_CD, HDT_IN_DT, IMP_DT)" _
' & " VALUES (Bar, Code, Taking, Now())"
' パラメータ部に、疑問符 (?) プレースホルダを使用したパラメータ クエリ。
sql = "INSERT INTO t_TRN_HDT_DAT (PROC_BAR, DELI_CD, HDT_IN_DT, IMP_DT)" _
& " VALUES (?, ?, ?, Now())"
'ここからが本題。
Using insertCommand As OleDbCommand = con.CreateCommand()
'SQL とパラメータ定義です。Add する順番は、SQL 内のパラメータ順と一致させてください。
insertCommand.CommandText = sql
insertCommand.Parameters.Add("Bar", OleDbType.VarWChar, 11)
insertCommand.Parameters.Add("Code", OleDbType.VarWChar, 2)
insertCommand.Parameters.Add("Taking", OleDbType.Date)
insertCommand.Prepare()
'データを渡した後、ExecuteNonQuery を実行します。
insertCommand.Parameters("Bar").Value = "01545264439"
insertCommand.Parameters("Code").Value = "01"
insertCommand.Parameters("Taking").Value = #8/28/2009 2:29:00 PM#
insertCommand.ExecuteNonQuery()
insertCommand.Parameters("Bar").Value = "01234567890"
insertCommand.Parameters("Code").Value = "99"
insertCommand.Parameters("Taking").Value = #12/31/2010 12:34:56 AM#
insertCommand.ExecuteNonQuery()
End Using
上記では 2 件のデータを登録していますが、データが変化しても SQL 文は同じ物が使えます。
この方法は、
・複数件のデータを大量に処理する際、SQL の再解釈が発生しない分、処理効率が向上する。
・数値や日付などを扱う際に、データを文字列化する必要が無いため、書式等を気にしなくて済む。
・「'」や「"」などの特殊文字を含んだデータを取り扱う際にも、エスケープ処理が不要となる。
などの利点があります。