- PR -

ストアドで一時テーブルを認識しない(SQLServe 2005)

1
投稿者投稿内容
nixo
会議室デビュー日: 2005/06/14
投稿数: 5
投稿日時: 2007-09-05 11:51
C#.NET初心者です。
初歩的質問かもしれませんが・・・

プログラムにて一時テーブルを作成し、その後
一時テーブルを参照したストアドをキックしているのですが
「オブジェクト名 '#(一時テーブル)'は無効です。」というエラーが出て
テーブルを認識してくれません。

【試したこと】
1: 
一時テーブル作成後、プログラムにてSELECTをかけると
ちゃんとテーブルが作成されて取得できることを確認。

2: 
SQL Server Manegement Studioの
「システムデータベース」→「tempdb」→「一時テーブル」には

"#(一時テーブル)________________000000*****"(←ユーザーID付加?)

となっていたので、試しに上記のとおりの名前にテーブル名を変更するが、
ストアドでは認識せず同様のエラー

3:
スキーマ名を付加したテーブル名に変更するが、同様のエラー

4:作成前に一時テーブルが存在してれば削除する処理を追加。
しかし同様エラー。


DB権限の問題かと思ったのですが、解決法が分かりません。
設定問題でしょうか?もしくはプログラムの問題があるのでしょうか?
初歩的な質問で申し訳ありませんがご教授願います。
または解説している資料・サイト等があれば教えてください。


環境)
VS2005/SQLServer2005

プログラム)
-----C#:test.cs

string sql; // SQL文
DataSet ds = new DataSet();// データセット
 sql = "";
sql += " SELECT";
 sql += " AAAA AS A,";
 ・・・
 sql += " AAAA AS A,";
 sql += " INTO #(一時テーブル) FROM (";"
 -------略
 // アクセスコマンド生成
 SqlAccessCommand ac = new SqlAccessCommand(sql);
 // 実行
 ExecuteSql(ci, ac);

-----T-SQL:

 ALTER PROCEDURE DECILE
  (@** -------略
 )
 AS
 
 //カーソル宣言
 declare cur cursor for
   select * from #(一時テーブル)  ←ここでエラー
まるく
大ベテラン
会議室デビュー日: 2004/01/09
投稿数: 181
投稿日時: 2007-09-05 12:00
http://www.google.co.jp/search?hl=ja&q=SQLServer+%E4%B8%80%E6%99%82%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB&btnG=Google+%E6%A4%9C%E7%B4%A2&lr=lang_ja

一時テーブルは、同一接続セッション内のみ有効です。
一時テーブルに対する理解が不十分であると推測します。

http://technet.microsoft.com/ja-jp/library/ms177399.aspx
nixo
会議室デビュー日: 2005/06/14
投稿数: 5
投稿日時: 2007-09-05 12:39
返信ありがとうございます。

プログラムの方で、
一時テーブル作成前にトランザクションを開始し、
ストアド終了後にコミットする処理にしていますが。。。

ストアドに切り替わった時点で
セッションが切れているということでしょうか?
まるく
大ベテラン
会議室デビュー日: 2004/01/09
投稿数: 181
投稿日時: 2007-09-05 14:00
引用:

プログラムの方で、
一時テーブル作成前にトランザクションを開始し、
ストアド終了後にコミットする処理にしていますが。。。



失礼しました。
当方でも最小コードで試してみましたが、問題なく動作します。
まずは、(余計な共通部品やヘルパークラス等使わずに)最小コードを組んで試してみられてはどうでしょう。

以下当方が試したコード(ストアド作成部分は初回に流して以降コメント化)
VB2005です。

コード:
        Using con As New SqlClient.SqlConnection(ConnectionString)
            Using cmd As New SqlClient.SqlCommand
                Try
                    '■Open connection
                    con.Open()

                    '■Create table
                    cmd.Connection = con
                    cmd.CommandText = "CREATE TABLE #TempTable (vid int)"
                    cmd.CommandType = CommandType.Text
                    cmd.ExecuteNonQuery()

                    '■Insert data
                    cmd.CommandText = "INSERT INTO #TempTable (vid) values (777)"
                    cmd.CommandType = CommandType.Text
                    cmd.ExecuteNonQuery()

                    '■Create procedure
                    'Dim sb As New StringBuilder
                    'sb.Append("ALTER PROCEDURE TEMP_PROC" + System.Environment.NewLine)
                    'sb.Append("AS" + System.Environment.NewLine)
                    'sb.Append("    DECLARE cur cursor for select vid from #TempTable" + System.Environment.NewLine)
                    'sb.Append("    DECLARE @result int                              " + System.Environment.NewLine)
                    'sb.Append("    OPEN cur                                         " + System.Environment.NewLine)
                    'sb.Append("    FETCH NEXT FROM cur INTO @result                 " + System.Environment.NewLine)
                    'sb.Append("    CLOSE cur                                        " + System.Environment.NewLine)
                    'sb.Append("    DEALLOCATE cur                                   " + System.Environment.NewLine)
                    'sb.Append("    SELECT @result                                   " + System.Environment.NewLine)
                    'sb.Append("GO" + System.Environment.NewLine)
                    'cmd.CommandText = sb.ToString
                    'cmd.CommandType = CommandType.Text
                    'cmd.ExecuteNonQuery()

                    '■Execute procedure
                    cmd.CommandText = "TEMP_PROC"
                    cmd.CommandType = CommandType.StoredProcedure
                    Dim obj As Object = cmd.ExecuteScalar()
                    MessageBox.Show("result=" + obj.ToString)

                    '■Close connection
                    con.Close()

                Catch ex As Exception
                    MsgBox(ex.ToString)

                End Try
            End Using
        End Using

nixo
会議室デビュー日: 2005/06/14
投稿数: 5
投稿日時: 2007-09-05 15:42
>まるくさん

おっしゃる通り、共通部品を使用せず
自身でコネクションを取得することころから同様の処理を行ったところ
(VBが分からなかったのでC#で試しました。すみません。。。)
正常に一時テーブルを認識することを確認しました。

問題はどこの処理でセッションが切れてしまったか?ですね。

さらに、
ローカル#(一時テーブル)ではなくグローバル##(一時テーブル)に置き換えると
前提処理でもストアドで認識することが分かりました。

ということはやはりユーザーの問題でしょうか?

共通部品を含め、もう少し調査してみます。

Kitu@Core
会議室デビュー日: 2007/10/10
投稿数: 1
投稿日時: 2007-10-10 16:54
同じ事象に遭遇しましたが、何故かSqlCommandインスタンスのParametersのクリアを行うようにしたところ回避できました。

1 Sqlサーバー接続
2 ストアド実行
3 一時テーブル作成
4 一時テーブルを参照するストアド実行
→ 「オブジェクト名 '#(一時テーブル)'は無効です。」

以下に変更

1 Sqlサーバー接続
2 ストアド実行
3 一時テーブル作成
4 Parameters.Clear()
5 一時テーブルを参照するストアド実行

ご参考になれば幸いです。

1

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