- PR -

OracleのDate型フィールドにDbNull.ValueをInsertすると失敗する。

投稿者投稿内容
未記入
大ベテラン
会議室デビュー日: 2006/05/19
投稿数: 125
投稿日時: 2007-05-11 17:39
VS2005
Oracle10g

OracleデータベースにDATETESTテーブルを作成し、Date型のTESTDATEフィールドを作成します。

Formにボタンを1つ配置しClickイベントで以下のコードを実行します。
DATETESTテーブルのTESTDATEフィールドに2件のデータをInsertするプログラムです。


1件目のデータでTESTDATEフィールドに Now
2件目のデータでTESTDATEフィールドに DbNull.Value
上記のデータをDATETESTテーブルにInsertした場合、登録は成功します。

1件目のデータでTESTDATEフィールドに DbNull.Value
2件目のデータでTESTDATEフィールドに Now
上記のデータをDATETESTテーブルにInsertした場合、登録は失敗し例外がスローされます。
例外内容
OracleException
ORA-01861: リテラルが書式文字列と一致しません


これはOracleの仕様なのでしょうか?
それとも私が考え違いをしているのでしょうか?



Public Class Form1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim table As New DataTable
table.Columns.Add(New DataColumn("TESTDATE", GetType(Date)))
Dim row As DataRow

'--成功するコード--
row = table.NewRow
row("TESTDATE") = Now
table.Rows.Add(row)

row = table.NewRow
row("TESTDATE") = DBNull.Value
table.Rows.Add(row)
'-------------------

'--OracleExceptionが発生するコード--
'row = table.NewRow
'row("TESTDATE") = DBNull.Value
'table.Rows.Add(row)

'row = table.NewRow
'row("TESTDATE") = Now
'table.Rows.Add(row)
'-------------------

Call DataBaseEntry(table)
End Sub

Private Sub DataBaseEntry(ByVal tbl As DataTable)
Dim cnn As New OracleClient.OracleConnection
cnn.ConnectionString = "接続文字列"

Dim cmdInsert As New OracleClient.OracleCommand
cmdInsert.Connection = cnn
cmdInsert.CommandText = "INSERT INTO DATETEST (TESTDATE) VALUES (:TESTDATE)"

Dim prm As New OracleClient.OracleParameter
prm = cmdInsert.CreateParameter
prm.ParameterName = "TESTDATE"
prm.SourceColumn = "TESTDATE"
cmdInsert.Parameters.Add(prm)

Dim adp As New OracleClient.OracleDataAdapter
adp.InsertCommand = cmdInsert
adp.Update(tbl)
End Sub

End Class


[ メッセージ編集済み 編集者: 未記入 編集日時 2007-05-11 17:40 ]
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-05-11 18:14
Oracle って、NULL って書くんじゃない?
の前に、実行している SQL 文を確認しなきゃ
_________________
未記入
大ベテラン
会議室デビュー日: 2006/05/19
投稿数: 125
投稿日時: 2007-05-11 20:36
Jittaさん
返答ありがとうございます。

ただ返答の意味がわかりません。
row = table.NewRow
row("TESTDATE") = DBNull.Value
table.Rows.Add(row)
・・・中略
adp.Update(tbl)
が成功していることを考えるとDBNull.Value という書き方、Insert文に問題があるとは思えないのですが。

宜しくお願いいたします。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-05-11 22:12
だったら、Orale 上で実行されている UPDATE 文と INSERT 文で差異がないか、調べてみませんか?

とはいえ、実行中の SQL 文を出す方法は私はわからないので、とりあえずは DataAdapter.Update で投げる SQL 文をみてみましょうよ。

それって、自分で作った?それとも、自動生成した?
自動生成しているなら、絶対に確認するべき。
_________________
未記入
大ベテラン
会議室デビュー日: 2006/05/19
投稿数: 125
投稿日時: 2007-05-11 22:23
何度も申し訳ありません。
UPDATE 文と INSERT 文で「差異」とは何の差異でしょうか?
具体的に何をどう確認すればよいのかわかりません。
DataAdapter.Update で投げるSQL分は自分で作成しました。
宜しくお願いいたします。

引用:

Jittaさんの書き込み (2007-05-11 22:12) より:
だったら、Orale 上で実行されている UPDATE 文と INSERT 文で差異がないか、調べてみませんか?

Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-05-11 22:43
引用:

未記入さんの書き込み (2007-05-11 22:23) より:
何度も申し訳ありません。
UPDATE 文と INSERT 文で「差異」とは何の差異でしょうか?
具体的に何をどう確認すればよいのかわかりません。
DataAdapter.Update で投げるSQL分は自分で作成しました。
宜しくお願いいたします。



じゃぁ、その2つで、DateTime 型のフィールドに値を格納している箇所で、値の扱い方に違いがあるんじゃないですか?

って、ちげ〜。ごめん、携帯で見てたので、コードまで読んでいませんでした。

ところで、タイトルは「DbNull.Value を INSERT すると」となっていますが、成功するときもあるんですよね?だったら、この書き方はおかしいですよね?
もしくは、

1件目のデータでTESTDATEフィールドに Now
2件目のデータでTESTDATEフィールドに DbNull.Value

で、本当に2件のデータが登録されてるのか、疑問に思います。1件しか登録されていないなら、「DbNull.Value を Insert すると失敗する」といえますが、2件とも登録されているなら、ちょっと違いますよね。
で、2件登録できているなら、3件や4件でどうなるか、1件だけにしたらどうなるか、確認していただきたいと思います。

あと、ツールで、実行中の SQL 文をとれないか、あるいはログに残せないか。
たぶん、DataBase Expert の会議室か、OTN の会議室で聞けばすぐ答えが返ってくると思います。
_________________
未記入
大ベテラン
会議室デビュー日: 2006/05/19
投稿数: 125
投稿日時: 2007-05-12 00:04
引用:

で、本当に2件のデータが登録されてるのか、疑問に思います。1件しか登録されていないなら、「DbNull.Value を Insert すると失敗する」といえますが、2件とも登録されているなら、ちょっと違いますよね。
で、2件登録できているなら、3件や4件でどうなるか、1件だけにしたらどうなるか、確認していただきたいと思います。



確認しました。
例えば10件のデータを登録するとして
10件のデータすべてがDbNull.Valueであれば登録は成功します。
もちろん10件のデータすべてがNowであれば登録は成功します。
しかし一度DbNull.Valueのデータを登録した後にNowのデータを登録するとOracleExceptionが発生します。
つまり1件ではエラーは発生しません。
何件登録しようがDbNull.Valueを登録した次にNowのデータが来た時点でエラーが発生します。

新規ソリューションで作成した最小のミニマムコードで発生しているためコード上の他の要因が絡んでいるとは思えず、Oracleだけの問題なのか、またはOracleのVersionの違いにより発生するのか、SQLServerなどでも発生するのか、が気になります。
SQLServerでも発生するのであればADO.NETの問題だと判断できそうですが、実行環境がありません。

引用:

あと、ツールで、実行中の SQL 文をとれないか、あるいはログに残せないか。
たぶん、DataBase Expert の会議室か、OTN の会議室で聞けばすぐ答えが返ってくると思います。


投稿してみます。
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2007-05-12 00:35
逆に Oracle の環境がないので試せませんが、SQL Server 2005 Express で試しました。普通に成功しました。
_________________
囚人のジレンマな日々

スキルアップ/キャリアアップ(JOB@IT)