tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトル一時テーブルへの INSERT
記事No7852
投稿日: 2008/07/24(Thu) 14:32
投稿者ルイージNO1
お世話になります。
私の知恵では、どうしようもないのでみなさんの知恵をお貸しください。

環境:Windows XP & Visual Stdio2005 & Oracle10g

現在、VS上で下記のような SQL を実施し、一時テーブルを作成しています。

strSql = String.Empty
strSql = "CREATE GLOBAL TEMPORARY TABLE WORK_BRIDE44 (MEMBER_NO VARCHAR2(9), YOYAKUHIN_KBN NUMBER, SEQNO NUMBER)"

_oraCmd = New OracleCommand(strSql, _oraConn)
_oraReader = _oraCmd.ExecuteReader()

上記は正常に行われ、一時テーブルは作成出来るのですが、上記テーブルに対して VS 上で INSERT を行うと、処理は正常に走っているのですが実際にデータが追加されません。

strSql = String.Empty
strSql = "INSERT INTO TABLE1(MEMBER_NO,YOYAKUHIN_KBN,SEQNO) VALUES('" & KainNo & "', " & YoyakuKbn & ", " & SEQNO & ")"

_oraCmd = New OracleCommand(strSql, _oraConn)
_oraReader = _oraCmd.ExecuteReader()

オブジェクトブラウザにて、上記の INSERT を行うとちゃんと一時テーブルにレコードが作成できることは確認済みです。

どこが悪いのかわからず、ずっと手詰まりの状態です。

申し訳ありませんが、知恵をお貸しください。お願いいたします。

[ツリー表示へ]
タイトルRe: 一時テーブルへの INSERT
記事No7853
投稿日: 2008/07/24(Thu) 15:11
投稿者kuroko
> strSql = "CREATE GLOBAL TEMPORARY TABLE WORK_BRIDE44 (MEMBER_NO VARCHAR2(9), YOYAKUHIN_KBN NUMBER, SEQNO NUMBER)"
> 上記テーブルに対して VS 上で INSERT を行うと、処理は正常に走っているのですが実際にデータが追加されません。

追加されているかどうかはどのように確認されたのでしょうか?
on commit句を省略した場合、on commit delete rows となります。
この場合、データはトランザクション内でのみ有効であり、
トランザクションが終了すると自動的に truncate されます。
つまり、トランザクション内でなければテーブルは常に空の状態です。
この点については大丈夫ですか?

[ツリー表示へ]
タイトルRe^2: 一時テーブルへの INSERT
記事No7856
投稿日: 2008/07/24(Thu) 15:32
投稿者ルイージNO1
早速のお返事ありがとうございます。

> 追加されているかどうかはどのように確認されたのでしょうか?
> on commit句を省略した場合、on commit delete rows となります。
> この場合、データはトランザクション内でのみ有効であり、
> トランザクションが終了すると自動的に truncate されます。
> つまり、トランザクション内でなければテーブルは常に空の状態です。
> この点については大丈夫ですか?

こちらの説明が足りなかったようです。申し訳ありません。

はじめは、下記のようにコードを記述しておりました。

strSql = String.Empty
strSql = "CREATE GLOBAL TEMPORARY TABLE WORK_BRIDE44 (MEMBER_NO VARCHAR2(9), YOYAKUHIN_KBN NUMBER, SEQNO NUMBER) "

oraTrans = _oraConn.BeginTransaction()

Try
    _oraCmd = New OracleCommand(strSql, _oraConn)
    _oraCmd.ExecuteNonQuery()

    _oraTrans.Commit()

Catch ex As OracleException
    If IsNothing(_oraTrans) = False Then
        _oraTrans.Rollback()
    End If
    MsgBox(ex.Message, MsgBoxStyle.OkOnly + MsgBoxStyle.Critical + MsgBoxStyle.SystemModal, "予期せぬエラー")
    Cursor = System.Windows.Forms.Cursors.Default
    Exit Sub
End Try

で、一時テーブルを作成し INSERT に関しても、

strSql = String.Empty
strSql = "INSERT INTO WORK_BRIDE44(MEMBER_NO,YOYAKUHIN_KBN,SEQNO) VALUES('" & KainNo & "', " & YoyakuKbn & ", " & SEQNO & ")"

oraTrans = _oraConn.BeginTransaction()

Try
    _oraCmd = New OracleCommand(strSql, _oraConn)
    _oraCmd.ExecuteNonQuery()

    _oraTrans.Commit()

Catch ex As OracleException
    If IsNothing(_oraTrans) = False Then
        _oraTrans.Rollback()
    End If
    MsgBox(ex.Message, MsgBoxStyle.OkOnly + MsgBoxStyle.Critical + MsgBoxStyle.SystemModal, "予期せぬエラー")
    Cursor = System.Windows.Forms.Cursors.Default
    Exit Sub
End Try

という風にしておりましたが、この INSERT 時の

oraCmd = New OracleCommand(strSql, _oraConn)
    _oraCmd.ExecuteNonQuery()

    _oraTrans.Commit()

ここで、Comitまでの処理は問題なく通っていたのですが、実際にこの一時テーブルを使用した SQL を流し、 DataRow = DataTable.Rows.Item(0) と記述すると

「位置 0 に行がありません。」

というようにエラーが返ってきます。おそらく kuroko 様がおっしゃられるように Commit した時点でデータが空になっているからだと調べて思ったので、最初の記述へ変更した経緯です。逆に言えば、

oraCmd = New OracleCommand(strSql, _oraConn)
    _oraCmd.ExecuteNonQuery()

    _oraTrans.Commit()

この部分をどう記述すればいいかご教授願いますでしょうか?

質問の意図が変わってしまったのと、長文になり大変申し訳ありませんがよろしくお願いいたします。

[ツリー表示へ]
タイトルRe^3: 一時テーブルへの INSERT
記事No7858
投稿日: 2008/07/24(Thu) 16:31
投稿者kuroko
先ほども回答しましたとおり on commit句省略(on commit delete rows)時に
データが存在できる期間はトランザクション内のみです。
一時表に追加したデータをどのように利用したいのかはわかりませんが
トランザクション終了(コミット or ロールバック)前であれば削除も取得
も可能です。
ちなみに、on commit delete rows のほかに on commit preserve rows
というものがあります。
こちらはセッション内でのみ有効となります。

[ツリー表示へ]
タイトルRe^4: 一時テーブルへの INSERT
記事No7859
投稿日: 2008/07/24(Thu) 20:36
投稿者ルイージNO1
遅くなり申し訳ありません。

> 先ほども回答しましたとおり on commit句省略(on commit delete rows)時に
> データが存在できる期間はトランザクション内のみです。
> 一時表に追加したデータをどのように利用したいのかはわかりませんが
> トランザクション終了(コミット or ロールバック)前であれば削除も取得
> も可能です。
> ちなみに、on commit delete rows のほかに on commit preserve rows
> というものがあります。
> こちらはセッション内でのみ有効となります。

いろいろ考えたのですが、自分の思う期待結果を得られなかったので一時テーブルではなく、DBの中にテーブルを作成し、対応いたしました。

非常に勉強になりました。本当にありがとうございました。

[ツリー表示へ]
タイトルRe: 一時テーブルへの INSERT
記事No7854
投稿日: 2008/07/24(Thu) 15:18
投稿者やじゅ
> お世話になります。
> 私の知恵では、どうしようもないのでみなさんの知恵をお貸しください。

ExecuteReader

ExecuteNonQuery

[ツリー表示へ]
タイトルRe^2: 一時テーブルへの INSERT
記事No7855
投稿日: 2008/07/24(Thu) 15:26
投稿者やじゅ
> ExecuteReader
> ↓
> ExecuteNonQuery

これは、どちらでも処理はされますが、ExecuteNonQueryの方が好ましい。

テーブル名の違いは?
WORK_BRIDE44 <>  TABLE1

[ツリー表示へ]
タイトルRe^3: 一時テーブルへの INSERT
記事No7857
投稿日: 2008/07/24(Thu) 15:35
投稿者ルイージNO1

返信ありがとうございます。

> これは、どちらでも処理はされますが、ExecuteNonQueryの方が好ましい。

そうなんですね。。ExecuteNonQuery と ExecuteReader の判別がうまく理解できていないので。。

> テーブル名の違いは?
> WORK_BRIDE44 <>  TABLE1

ここは、私がこの記事を投稿する時に任意に変えてしまったものですので、実際はテーブル名は正しい表記になっております。

[ツリー表示へ]