- - PR -
oracle.data.adapterで自動生成されるSQLについて
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2008-09-30 17:05
VB2005、Oracle共に初心者です。
oracle.data.adapterでSQLを自動生成し、テーブルを更新する 処理を作成しております。(System.Data.OracleClientにより Access MDBを更新するプログラムをOracle用に変更中) 実際に実行したところ、「ORA-00911: 文字が無効です。」の エラーが発生しました。 原因を探りたいのですが、自動生成されたSQL文の内容を確認 するには、どのようにすれば良いのでしょうか? とりあえず、ソースも記載しておきますので、何か気づいた方が いらっしゃれば、アドバイスも含めてお願いします。 【ソースコード(途中省略】 ' UPDATEコマンドの作成 Private Function CreateUpdateCommand(ByVal dt As DataTable, ByVal AddTablename As Boolean) As OracleCommand Dim cmd As New OracleCommand Dim SqlStr As String Dim i As Integer cmd.CommandText = "UPDATE " & dt.TableName & " SET " i = 1 SqlStr = "" For Each col As DataColumn In dt.Columns If AddTablename = True Then SqlStr = SqlStr & dt.TableName & "." & col.ColumnName & " = ?, " Else SqlStr = SqlStr & col.ColumnName & " = ?, " End If Dim param As New OracleParameter param.ParameterName = "@p" & i param.SourceColumn = col.ColumnName If col.DataType Is System.Type.GetType("System.String") Then param.OracleDbType = OracleDbType.Varchar2 Else param.OracleDbType = OracleDbType.Int32 End If param.SourceVersion = DataRowVersion.Current cmd.Parameters.Add(param) Next ' 最後に付加したカンマを破棄 cmd.CommandText = cmd.CommandText & Left(SqlStr, Len(SqlStr) - 2) & " WHERE " SqlStr = "" i = 1 For Each col As DataColumn In dt.Columns If AddTablename = True Then SqlStr = SqlStr & " ( " & dt.TableName & "." & col.ColumnName & " = ? ) AND " Else SqlStr = SqlStr & " ( " & col.ColumnName & " = ? ) AND " End If Dim param As New OracleParameter param.ParameterName = "@p" & i param.SourceColumn = col.ColumnName If col.DataType Is System.Type.GetType("System.String") Then param.OracleDbType = OracleDbType.Varchar2 Else param.OracleDbType = OracleDbType.Int32 End If param.SourceVersion = DataRowVersion.Original cmd.Parameters.Add(param) Next ' 最後に付加した(AND)を破棄 cmd.CommandText = cmd.CommandText & Left(SqlStr, Len(SqlStr) - 5) cmd.Connection = cnt CreateUpdateCommand = cmd End Function ' ------------------------------------------------------------------------ Public Function Exec_update(ByRef SqlStr As String, ByRef NewValues As BTDBRecords2, ByVal tablename As String) As Integer Dim dt As DataTable = GetSqlResult(SqlStr, tablename) Dim oOleAdap As New OracleDataAdapter Dim i As Integer Try ' 抽出対象が存在すれば、カーソルのあるレコードを削除 If dt.Rows.Count() = 0 Then Exec_update = 0 Else For i = 0 To NewValues.Count - 1 If NewValues(i).Index >= dt.Columns.Count Then Exec_update = 0 dt.Reset() Exit Function End If If dt.Columns(NewValues(i).Index).DataType Is System.Type.GetType("System.String") Then ' 文字列型 dt.Rows(0).Item(NewValues(i).Index) = NewValues(i).Value Else ' 数値型として処理 ' 代入値の作成 ' = If NewValues(i).Operation = 0 Then dt.Rows(0).Item(NewValues(i).Index) = NewValues(i).Value ' += ElseIf NewValues(i).Operation = 7 Then dt.Rows(0).Item(NewValues(i).Index) = dt.Rows(0).Item(NewValues(i).Index) + CInt(NewValues(i).Value) ' -= ElseIf NewValues(i).Operation = 9 Then dt.Rows(0).Item(NewValues(i).Index) = dt.Rows(0).Item(NewValues(i).Index) - CInt(NewValues(i).Value) End If End If Next Try oOleAdap.UpdateCommand = CreateUpdateCommand(dt, True) Exec_update = oOleAdap.Update(dt) Catch ee As Exception oOleAdap.UpdateCommand = CreateUpdateCommand(dt, False) Exec_update = oOleAdap.Update(dt) End Try End If Catch e As Exception Exec_update = -1 End Try End Function | ||||||||
|
投稿日時: 2008-09-30 17:32
内容の表記に一部誤りがありました。
>oracle.data.adapterでSQLを自動生成し、テーブルを更新する >処理を作成しております。(System.Data.OracleClientにより ~~~~~~~~~~~~~~~~~~~~~~~~~ ↑ System.Data.Oledb の誤りです。 | ||||||||
|
投稿日時: 2008-09-30 17:34
> ' UPDATEコマンドの作成
思いっきり、作成しているようなのですが? どこが自動生成なのでしょう? | ||||||||
|
投稿日時: 2008-09-30 17:50
のコードを実行する直前で、oOleAdap.UpdateCommand プロパティに入っている CommandオブジェクトのCommandTextやParametersの中身を確認してみるといいんじゃないでしょうか。
System.Data.OracleClient を使用した場合、パラメータの書式は「コロン(:) + 名前(例… :hoge )」ですね。 | ||||||||
|
投稿日時: 2008-09-30 17:55
Jittaさんへ
確かに自動生成では無いですね。 申し訳ありません。 cmd.CommandTextの内容に関しては、特に使用出来ない文字は 設定されておりませんでした。 【cmd.CommandTextの内容】 "UPDATE nyukolog SET nyukolog.FIELD1 = ?, nyukolog.FIELD2 = ?, nyukolog.FIELD3 = ?, nyukolog.FIELD4 = ?, nyukolog.FIELD5 = ?, nyukolog.FIELD6 = ?, nyukolog.FIELD7 = ?, nyukolog.FIELD8 = ? WHERE ( nyukolog.FIELD1 = ? ) AND ( nyukolog.FIELD2 = ? ) AND ( nyukolog.FIELD3 = ? ) AND ( nyukolog.FIELD4 = ? ) AND ( nyukolog.FIELD5 = ? ) AND ( nyukolog.FIELD6 = ? ) AND ( nyukolog.FIELD7 = ? ) AND ( nyukolog.FIELD8 = ? )" 作成したSQL文の?に、値を代入していると思われます。 修正した部分は、System.Data.OledbオブジェクトをODP.NETオブジェクトに 変更のみです。 oOleAdap.UpdateCommand = CreateUpdateCommand(dt, True) Exec_update = oOleAdap.Update(dt) この時に、実行されるSQL文を確認したいと思うのですが、 どの様にすればよろしいのでしょうか? よろしくお願いします。 | ||||||||
|
投稿日時: 2008-09-30 19:44
? はパラメーターを表すプレースホルダです。
私は : をつけたパラメーター名しか使ったことがないのですが、 ODP.NET では ? は使えなかったような? @IT 「ODP.NETでOracle固有の機能を活用する 」 http://www.atmarkit.co.jp/fdb/rensai/odpdotnet01/odpdotnet04.html OTN 「値のバインド」 http://www.oracle.com/technology/global/jp/oramag/oracle/05-sep/o55odpnet.html | ||||||||
|
投稿日時: 2008-09-30 19:49
エラーとは関係ありませんが、このSQLは「自動生成」されてますよね? 主キーを張ったほうがいいですよ。 主キーがないと全ての列の値が一致するかどうかがレコード一致条件になります。 where 句に各列の値が羅列されてますよね。 SQLServer の場合、こういうコマンドでトランザクションがらみの内部エラーが発生することがあります。内部でもみ消されるので厄介な現象です。 Oracle では試したことはありませんが、危険かも。 | ||||||||
|
投稿日時: 2008-09-30 21:32
あ、ODP.NETか。勘違いしてたorz |