Oracleバックエンドを備えたWebサーバーに保存するためのパラメーターが.Netクライアントプログラムで設定され、Webサービスを介してデータセットとしてアップロードされるクライアントプログラムを構築しています。
Web サービス コードでは、データがデータセットから読み取られ、Web サーバー (Oracle バックエンド) 上の UPDATE ステートメントに追加されます。
サーバーはファイアウォールの背後にある顧客の LAN で実行され、関連するパラメーターの動的な性質のために、sproc は使用されていません。SQL 文字列はロジックに組み込まれています。
文字列の例を次に示します。
UPDATE WorkOrders
SET TravelTimeHours = :TravelTimeHours,
TravelTimeMinutes = :TravelTimeMinutes,
WorkTimeHours = :WorkTimeHours,
WorkTimeMinutes = :WorkTimeMinutes,
CompletedPersonID = :CompletedPersonID,
CompletedPersonName = :CompletedPersonName,
CompleteDate = :CompleteDate
WHERE WorkOrderNumber = :WorkOrderNumber
VS 2010 でコードをデバッグし、サーバー コードにステップインすると、次のエラーが表示されます。
ORA-01036: illegal variable name/number
宛先の oracle マシンで SQL コマンドを実行すると、上記のステートメントのバインド変数を入力するように求められ、正しい日付形式を使用している限り、UPDATE ステートメントは正しく機能しました。
質問:
1)月の形式が間違っていると、オラクルがORA-01036エラーをスローした可能性はありますか?
2) Oracle マシンで実行されている ASP.net Web サイトから日付形式を変換する必要がないのはなぜですか? Oracle には、バインド変数の入力画面を除外するデフォルトの変換ルーチンがありますか?
3) 日付形式が問題でなかった場合、ORA-1036 は正確には何を意味し、どの変数が不正な名前/番号を持っているかをどのように発見しますか?
これは、データセットのタイプ (WOName) を受け取り、適切な SQL 文字列を返す関数のスニペットです。多くのケースが存在しますが、読みやすくするために削除されています。
Private Function GetMainSQLString(ByVal WOName As String) As String
Dim Result As String = ""
Select Case WOName
Case "Monthly Site Inspection"
Dim sb As New StringBuilder
sb.Append("UPDATE WorkOrders SET ")
sb.Append("CompletedPersonID = :CompletedPersonID, CompletedPersonName = :CompletedPersonName, CompleteDate = :CompleteDate, ")
sb.Append("SupervisorID = :SupervisorID, SupervisorName = :SupervisorName ")
sb.Append("WHERE WorkOrderNumber = :WorkOrderNumber")
Result = sb.ToString
End Select
Return Result
End Function
これは、クライアント プログラムから受信した 15 種類のデータセット (WOName) のどれに応じて、Oracle コマンド オブジェクト byRef を取得し、それに必要なパラメーターを追加する関数のスニペットです。多くのケースが存在しますが、読みやすくするために削除されています。
更新された Cmd オブジェクトはメイン プログラム ロジックに返され、そこで ExecuteNonQuery() が呼び出されます。
以下の params のテスト値は次のとおりです。
dr.Item("CompletedPersonID") 21
dr.Item("CompletedPersonName") Pers Name
dr.Item("CompleteDate") #8/16/2010#
dr.Item("SupervisorID") 24
dr.Item("SupervisorName") Sup Name
dr.Item("WorkOrderNumber") 100816101830
Private Function addMainCmdParams(ByVal WOName As String, ByRef cmd As OracleCommand, ByVal dr As DataRow) As OracleCommand
Select Case WOName
Case "Monthly Site Inspection"
cmd.Parameters.Add(":CompletedPersonID", Oracle.DataAccess.Client.OracleDbType.Int32).Value = dr.Item("CompletedPersonID")
cmd.Parameters.Add(":CompletedPersonName", Oracle.DataAccess.Client.OracleDbType.Varchar2).Value = dr.Item("CompletedPersonName")
cmd.Parameters.Add(":CompleteDate", Oracle.DataAccess.Client.OracleDbType.Date).Value = dr.Item("CompleteDate")
cmd.Parameters.Add(":SupervisorID", Oracle.DataAccess.Client.OracleDbType.Int32).Value = dr.Item("SupervisorID")
cmd.Parameters.Add(":SupervisorName", Oracle.DataAccess.Client.OracleDbType.Varchar2).Value = dr.Item("SupervisorName")
cmd.Parameters.Add(":WorkOrderNumber", Oracle.DataAccess.Client.OracleDbType.Varchar2).Value = dr.Item("WorkOrderNumber")
End Select
Return cmd
End Function
今日これを実行している間、この正確なコードは成功しました。しかし、別の同様のケースはありませんでした。私はまだ、Oracle によって実行される暗黙の型キャスト (存在する場合) を信頼していません。特に、Oracle が dbNull.value で渡されるこれらのパラメーターをどのように処理するかについては疑いがあります。それが問題なら、私はそれを回避する必要があります。このシステムに渡された値を常に取得するとは限らないオプションのパラメーターと列が多すぎて、null で中断できません。