- mso
- ぬし
- 会議室デビュー日: 2003/12/04
- 投稿数: 496
- お住まい・勤務地: 宮城
|
投稿日時: 2005-01-04 12:07
msoです。
環境:
WindowsXP SP1
SqlServer2000
T-SQLでわからないことがあるので、教えてください。
動的にCURSORを生成して、処理を行うとしていたのですが
期待通りに動作をしてくれません。
#エラーが出ます
そこで下記のようなサンプルを作成し、テストをしたのですが
やはりエラーがでたままとなり動作をしてくれません。
そこでご存知の方がいたら何が良くないのか、
ひょっとしたら出来ないことをやろうとしているのか教えていただきたいと
思います
下記のソースの途中で生成したSQLをPRINTしている箇所があり、
そのSQLからSELECT文を実行すると正しく動作することは確認が
取れています。
実行したいT-SQL
| コード: |
|
CREATE PROCEDURE SP_SAMPLE2
@W_TABLENAME VARCHAR(256) --テーブル名称
,@W_ROWNAME1 VARCHAR(256) --列名称
,@W_ROWNAME2 VARCHAR(256) --列名称
AS
--変数宣言
DECLARE @SQL_STRING VARCHAR(2048)
DECLARE @STR_ID VARCHAR(128)
DECLARE @STR_NAME VARCHAR(128)
BEGIN
SET @SQL_STRING = 'DECLARE CUR_LOOP CURSOR LOCAL FOR'
+ ' SELECT ' + @W_ROWNAME1 + ' ,' + @W_ROWNAME2
+ ' FROM ' + @W_TABLENAME
PRINT @SQL_STRING
EXECUTE sp_executesql @SQL_STRING
OPEN CUR_LOOP
FETCH NEXT FROM CUR_LOOP
INTO @STR_ID,@STR_NAME
WHILE (@@FETCH_STATUS = 0)
BEGIN
PRINT '---------'
PRINT @STR_ID
PRINT @STR_NAME
FETCH NEXT FROM CUR_LOOP
INTO @STR_ID,@STR_NAME
END
--カーソルを閉じる
CLOSE CUR_LOOP
DEALLOCATE CUR_LOOP
END
GO
|
クエリアナライザから実行するときの方法
| コード: |
|
EXECUTE SP_SAMPLE2 'M_SYAIN','SYAIN_ID','SYAIN_NAME'
|
エラーメッセージ
| コード: |
|
サーバー : メッセージ 214、レベル 16、状態 2、プロシージャ sp_executesql、行 17
パラメータを @statement データ型をからプロシージャが必要とする ntext/nchar/nvarchar データ型に変換できません。
|
|
- mso
- ぬし
- 会議室デビュー日: 2003/12/04
- 投稿数: 496
- お住まい・勤務地: 宮城
|
投稿日時: 2005-01-04 13:06
msoです。
| 引用: |
|
エラーメッセージ
| コード: |
|
サーバー : メッセージ 214、レベル 16、状態 2、プロシージャ sp_executesql、行 17
パラメータを @statement データ型をからプロシージャが必要とする ntext/nchar/nvarchar データ型に変換できません。
|
|
宣言しているところをvarchar→NVARCHARにしたら上記のエラーが消えました。
ただ、
| コード: |
|
サーバー : メッセージ 16916、レベル 16、状態 1、プロシージャ SP_SAMPLE2、行 20
名前 'CUR_LOOP' を持つカーソルが存在しません。
|
というエラーが発生するようになっています。
ケアレスミスのにおいが漂うメッセージなので、
見直しをしたい再度実行していきます。
|
- mso
- ぬし
- 会議室デビュー日: 2003/12/04
- 投稿数: 496
- お住まい・勤務地: 宮城
|
投稿日時: 2005-01-04 13:06
#2重投稿してしまったので、削除
[ メッセージ編集済み 編集者: mso 編集日時 2005-01-04 13:07 ]
|
- mso
- ぬし
- 会議室デビュー日: 2003/12/04
- 投稿数: 496
- お住まい・勤務地: 宮城
|
投稿日時: 2005-01-04 13:11
msoです。
自己解決しました。
| コード: |
|
CREATE PROCEDURE SP_SAMPLE2
@W_TABLENAME NVARCHAR(256) --テーブル名称
,@W_ROWNAME1 NVARCHAR(256) --列名称
,@W_ROWNAME2 NVARCHAR(256) --列名称
AS
--変数宣言
-- DECLARE @SQL_STRING VARCHAR(2048)
DECLARE @SQL_STRING NVARCHAR(2048)
DECLARE @STR_ID NVARCHAR(128)
DECLARE @STR_NAME NVARCHAR(128)
BEGIN
SET @SQL_STRING = 'DECLARE CUR_LOOP CURSOR FOR'
+ ' SELECT ' + @W_ROWNAME1 + ' ,' + @W_ROWNAME2
+ ' FROM ' + @W_TABLENAME
PRINT @SQL_STRING
EXECUTE sp_executesql @SQL_STRING
OPEN CUR_LOOP
FETCH NEXT FROM CUR_LOOP
INTO @STR_ID,@STR_NAME
WHILE (@@FETCH_STATUS = 0)
BEGIN
PRINT '---------'
PRINT @STR_ID
PRINT @STR_NAME
FETCH NEXT FROM CUR_LOOP
INTO @STR_ID,@STR_NAME
END
--カーソルを閉じる
CLOSE CUR_LOOP
DEALLOCATE CUR_LOOP
END
GO
|
具体的に修正したところは
1:varchar→nvarchar
2:'DECLARE CUR_LOOP CURSOR LOCAL FOR'
↓
'DECLARE CUR_LOOP CURSOR FOR'
とlocalを削除したところです。
2のlocalを削除したらうまくいった理由が良くわからないのですが、
動的カーソルはすべてグローバルになるのでしょうか?
それともローカルとかグローバルという概念がないものなのでしょうか?
|
- 未記入
- ぬし
- 会議室デビュー日: 2004/09/17
- 投稿数: 667
|
投稿日時: 2005-01-04 16:23
| 引用: |
|
動的カーソルはすべてグローバルになるのでしょうか?
それともローカルとかグローバルという概念がないものなのでしょうか?
|
まず「動的カーソル」という言葉の意味が曖昧ですね。通常、「動的カーソル」といった場合、カーソルを開いたあとでもテーブルの変更が反映されるものを指します。また、データベース用語では、クエリ文字列などを「動的」に組み立てることを「動的ステートメント」と言うことがあります。
で、本題。カーソル自体は静的でも動的でも構いません。今回の場合は、カーソルを開くためのクエリ文字列を動的に組み立てて EXECUTE sp_executesql @SQL_STRING で実行していますね。sp_executesql で実行されるステートメントは、呼び出し元とは別スコープになるので、sp_executesql の内外でローカル変数にお互いにアクセスすることはできないわけです。sp_executesql の内外で同じ変数にアクセスしたい場合は @@ を付けてグローバル変数にしたり、(今回のように) LOCAL をはずしてグローバルカーソルにする必要があります。
|