- PR -

OleDbCommandBuilderが生成するSQL

1
投稿者投稿内容
さとし
会議室デビュー日: 2007/01/24
投稿数: 8
投稿日時: 2007-06-14 16:40
すみません。どなたか、お知恵拝借できないでしょうか?
asp.net2.0 + accessにてwebアプリ作成中です。
OleDbCommandBuilderが生成するSQLがおかしくて困っております。
列に[c_id][日付][1_no][1_memo]をもつaccessのテーブルがあり、
[c_id]を主キーにしております。ボタンクリックにより、
[c_id]にはセッションid(guid)を入れ、その他の列にはフォームの内容を入れます。
その後フォームが修正され、再度ボタンが押された時は、先のセッションidがあるかどうか調べ、あれば、そのレコードを修正する様にしたいのです。
しかし、その再度ボタンが押された時にDataAdapter.Updateにてエラーが出ます。
=================================
クエリ式 '((c_id = ?) AND ((? = 1 AND 日付 IS NULL) OR (日付 = ?)) AND ((? = 1 AND 1_no IS NULL) OR (1_no = ?)))' の 構文エラー
=================================
上記の通りOleDbCommandBuilderで生成したクエリがおかしいのですが、
SQLがなんでこんな風になるのでしょうか?
テーブルは先に示した極、単純なものです。
以下は一部分かりやすく修正したソースです。

Protected Sub Btn_Keitai_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Btn_Keitai.Click
'アダプタとコマンドの用意
Dim m_Adapter As New OleDbDataAdapter()
Dim m_Command = New OleDbCommand()
Dim m_Connection = New OleDbConnection()
Dim SM_SQLCONNECTION_STRING_TEMPCS As String = "接続文字列"
m_Connection.ConnectionString = SM_SQLCONNECTION_STRING_TEMPCS
m_Command.Connection = m_Connection
m_Command.CommandText = "select * from tempcs"
m_Adapter.SelectCommand = m_Command

'データセットへの読み込み
Dim TempCsDataSet As DataSet = New DataSet()
Dim dt As DataTable = TempCsDataSet.Tables("tempcs")
Dim ModifyRow As DataRow
m_Adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey
m_Adapter.Fill(TempCsDataSet, "tempcs")

'主キーがSession("TempGuid")のレコードが存在しなければ、レコード追加
'既に存在していれば、そのレコードを修正
If dt.Rows.Find(Session("TempGuid")) Is Nothing Then
ModifyRow = dt.NewRow()
ModifyRow("c_id") = Session("TempGuid")
ModifyRow("日付") = Now()
ModifyRow("1_no") = "01"
ModifyRow("1_memo") = "01のメモ"
dt.Rows.Add(ModifyRow)
Else
ModifyRow = dt.Rows.Find(Session("TempGuid"))
ModifyRow("c_id") = Session("TempGuid")
ModifyRow("日付") = Now()
ModifyRow("1_no") = "02"
ModifyRow("1_memo") = "02のメモ"
End If

'コマンド生成とアップデート
Dim TempCsBuilder As OleDbCommandBuilder = New OleDbCommandBuilder(m_Adapter)
m_Adapter.Update(TempCsDataSet, "tempcs")

End Sub
NAL-6295
ぬし
会議室デビュー日: 2003/01/26
投稿数: 966
お住まい・勤務地: 東京
投稿日時: 2007-06-14 17:28
NAL-6295です。

多分、
QuotePrefixとQuoteSuffixにそれぞれ、"["と"]"を定義してあげれば、
構文エラーは回避されます。

ちなみに、オプティミスティック同時実行制御が有効な場合CommandBuilderで生成するクエリは基本的にすべての項目が変更されていない場合のみ更新するというような形に生成されます。


さとし
会議室デビュー日: 2007/01/24
投稿数: 8
投稿日時: 2007-06-14 18:25
NAL-6295様。ご指摘の通りで解決いたしました。
素人なもので、他のみなさんからすれば、「こんなことで。。。」
とお思いでしょうが、3日も悩んで、憂鬱な日々を送っていました。
そもそもエラーメッセージにupdate句がないのがおかしいのだと思いこんでました。

NAL-6295「様様」です。本当にありがとうございました。

一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2007-06-14 18:30
識別子の先頭に数字を使っているからとかそういう話なのかなぁ。
さとし
会議室デビュー日: 2007/01/24
投稿数: 8
投稿日時: 2007-06-14 20:13
一郎様。
レスありがとうございます。
DBの列名ですよね?
DB、ソースともに以下の様に変更してみましたら、
1_no →no
1_memo →memo
今度は、1回目のupdateの段階で、
INSERT INTO ステートメントの構文エラーです。
というエラーになってしまいました。
益々なぞですが、NAL-6295さんご指摘の
TempCsBuilder.QuotePrefix = "["
TempCsBuilder.QuoteSuffix = "]"
を入れるとエラーはなくなります。







NAL-6295
ぬし
会議室デビュー日: 2003/01/26
投稿数: 966
お住まい・勤務地: 東京
投稿日時: 2007-06-15 02:40
NAL-6295です。

引用:

益々なぞですが、NAL-6295さんご指摘の
TempCsBuilder.QuotePrefix = "["
TempCsBuilder.QuoteSuffix = "]"
を入れるとエラーはなくなります



名前に空白や予約済みトークンなどの文字を含む(たとえば先頭が数字等)場合
PrefixとSuffixである[]で囲ってあげることで、
「ここからここまでが列名ですよ〜。」
と規定してあげることでエラーが出なくなります。

ちなみにSQLServerは[]、Oracleは""となります。


[ メッセージ編集済み 編集者: NAL-6295 編集日時 2007-06-15 02:41 ]
1

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