tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルADO.NETでのデータ更新について
記事No1122
投稿日: 2004/10/27(Wed) 12:39
投稿者みけ
いつも参考にさせていただいております。

Oracleの更新先のテーブル名は、TEST で
SYAIN_ID(主キー)・SYAIN_NAME の2フィールドをもっています。
SYAIN_ID = 'AAA'であるレコードのSYAIN_NAME を
更新しようとすると、DataAdapterのUpdateで
「UpdateCommand の動的 SQL 生成は、キーである列情報を返さない
SelectCommand に対してサポートされていません。」という
エラーが発生します。

OleDbCommandのExecuteNonQueryで値を更新すると、
うまくいくのですが・・・。

どなたかエラーの対処方法を教えていただけないでしょうか?
よろしくお願いします。

------ 実行環境
Windows2000 Professional
Oracle 9i
VisualBasic .NET 2003
.NET Framework 1.1

------ 再現コード
Imports System.Data.OleDb

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles Button1.Click

        Dim strConn As String
        Dim objConn As OleDbConnection
        Dim objAdp As OleDbDataAdapter
        Dim objTbl As New DataTable
        Dim strSql As String
        Dim objRow As DataRow

        '接続文字列の設定
        strConn = "Provider=OraOLEDB.Oracle"
        strConn &= ";User ID=test"
        strConn &= ";password=test"
        strConn &= ";Data Source=test"
        strConn &= ";Persist Security Info=False"

        '接続開始
        objConn = New OleDbConnection(strConn)
        objConn.Open()

        strSql = "SELECT * FROM TEST"
        objAdp = New OleDbDataAdapter(strSql, objConn)
        objAdp.Fill(objTbl)

        '主キーの設定
        With objTbl
            .PrimaryKey = New DataColumn() {.Columns("SYAIN_ID")}
        End With

        '更新処理
        objRow = objTbl.Rows.Find("AAA")
        If Not objRow Is Nothing Then
            objRow.BeginEdit()
            objRow("SYAIN_NAME") = "山田"
            objRow.EndEdit()
        End If

        'Sqlコマンドの自動作成
        Dim objCmdBuilder As New OleDbCommandBuilder(objAdp)

'        Dim cmdSql As OleDbCommand = objCmdBuilder.GetUpdateCommand

        objAdp.Update(objTbl)    '←ここでエラー

    End Sub

[ツリー表示へ]
タイトルRe: ADO.NETでのデータ更新について
記事No1125
投稿日: 2004/10/28(Thu) 08:59
投稿者るしぇ
主キーの情報をデータベースから取得してみて下さい。
[VB.NET]
        objAdp.MissingSchemaAction = MissingSchemaAction.AddWithKey
        objAdp.Fill(objTbl)
        If objTbl.PrimaryKey.Length = 0 Then
            MessageBox.Show("主キーの情報を取得できませんでした。", "データベース検索",
MessageBoxButtons.OK, MessageBoxIcon.Error)
        End If

[ツリー表示へ]
タイトルRe^2: ADO.NETでのデータ更新について
記事No1127
投稿日: 2004/10/28(Thu) 09:18
投稿者みけ
るしぇさん、レスありがとうございました。

説明不足だったのですが、
objTbl.PrimaryKeyが存在することはデバッグで確認しています。
それから、もちろんobjRow.ItemArrayもレコードの値が
セットされていることは確認しています。
コメントアウトしているobjCmdBuilder.GetUpdateCommandで
コマンドを取得しようとしたのですが、
同じエラーが出るのです。

ODP.NET の開発者ガイドでは
MissingSchemaAction を MissingSchemaAction.AddWithKey に
設定して Fill メソッドがコールされている場合でも,スキーマまたは
キー情報は提供されません。
とあるので、もしかしたら OLEDB Data Provider でも
同じことがいえるのでしょうか?
そういった情報を探していたのですが、見つけることができませんでした・・・

[ツリー表示へ]
タイトルRe^3: ADO.NETでのデータ更新について
記事No1128
投稿日: 2004/10/28(Thu) 09:27
投稿者るしぇ
> ODP.NET の開発者ガイドでは
> MissingSchemaAction を MissingSchemaAction.AddWithKey に
> 設定して Fill メソッドがコールされている場合でも,スキーマまたは
> キー情報は提供されません。
> とあるので、もしかしたら OLEDB Data Provider でも
> 同じことがいえるのでしょうか?
> そういった情報を探していたのですが、見つけることができませんでした・・・

じゃあ OracleClient でテストしてみれば?


↓ 追加書き込み
>objTbl.PrimaryKeyが存在することはデバッグで確認しています。
というかよくよく考えると矛盾してるね。
> MissingSchemaAction を MissingSchemaAction.AddWithKey に
> 設定して Fill メソッドがコールされている場合でも,スキーマまたは
> キー情報は提供されません。
> とあるので、もしかしたら OLEDB Data Provider でも
> 同じことがいえるのでしょうか?
ローカルのデータテーブルに主キーを設定するのでなく、
    MissingSchemaAction.AddWithKey
を設定して Fill の時に主キーの情報が取れているかどうかを
調べるコードが前回書込みしたコードなんですが?
> 同じことがいえるのでしょうか?
じゃなくて取れてなければ Length が 0 と表示されますので
断言できるはずなんですが…なんでまだ疑問形?

[ツリー表示へ]
タイトルRe^4: ADO.NETでのデータ更新について
記事No1129
投稿日: 2004/10/28(Thu) 12:44
投稿者みけ
>     MissingSchemaAction.AddWithKey
> を設定して Fill の時に主キーの情報が取れているかどうかを
> 調べるコードが前回書込みしたコードなんですが?
> > 同じことがいえるのでしょうか?

とんちんかんなことをお返事していましたね。ごめんなさい!

MissingSchemaAction.AddWithKeyを設定すると
objTbl.PrimaryKey.Length は、 1 でした。

OLEDB プロバイダで接続するとは言っても
結局はOracleデータベースに依存しているので
このやり方での更新は不可能だということですね。
(でもやっぱり納得いかないような・・・)

[ツリー表示へ]
タイトルRe^5: ADO.NETでのデータ更新について
記事No1130
投稿日: 2004/10/28(Thu) 12:58
投稿者るしぇ
> MissingSchemaAction.AddWithKeyを設定すると
> objTbl.PrimaryKey.Length は、 1 でした。
という事はスキーマ情報は取れているという事ですね。
しかし
>「UpdateCommand の動的 SQL 生成は、キーである列情報を返さない
>SelectCommand に対してサポートされていません。」という
>エラーが発生します。
…という事は OleDbDataAdapter では Oracle に対する
UpdateCommand の動的 SQL 生成をするのに情報がうまく
取れない部分があるのかもしれませんね。[VB.NET]側のインター
フェースは同じ…というか継承クラスとして纏められていますが…
実際問題、色々と不都合は出てくるのでしょう。…で、OracleClient で
テストは成功しましたか?

こちらでは SqlClient と OracleClient で UpdateCommand の
動的 SQL 生成は成功しています。

[ツリー表示へ]
タイトルRe^6: ADO.NETでのデータ更新について
記事No1131
投稿日: 2004/10/28(Thu) 18:07
投稿者みけ
> こちらでは SqlClient と OracleClient で UpdateCommand の
> 動的 SQL 生成は成功しています。

そうなんですか!

実は、自分のPCをサーバーに見立てて開発しており
ほかにオラクルClientの環境をもつ開発機がありません。
.NET + OracleClient環境を作ってテストしようと思うのですが、
少し先になると思います。
とりあえずは、ExecuteNonQueryで更新することにします。

るしぇさん、迅速なレスと検証をありがとうございました!!

[ツリー表示へ]