質問

私の動的SQL文を私に保存されている。いのに対して繰り返し処理を実行する結果をカーソルを移動させます。んも考えられない早いスピートと右の構文です。ここで僕がやってます。

SELECT @SQLStatement = 'SELECT userId FROM users'

DECLARE @UserId

DECLARE users_cursor CURSOR FOR
EXECUTE @SQLStatment --Fails here. Doesn't like this

OPEN users_cursor
FETCH NEXT FROM users_cursor
INTO @UserId

WHILE @@FETCH_STATUS = 0
BEGIN

EXEC asp_DoSomethingStoredProc @UserId

END
CLOSE users_cursor
DEALLOCATE users_cursor

何をなす。

役に立ちましたか?

解決

SQLは本当にダイナミックにする必要があるので、もし

カーソルだけが実行されている文の宣言カーソルの一部を作る、select文を受け入れます。サーバーがグローバルカーソルを使用する必要があります作業するには、以下のため。

Declare @UserID varchar(100)
declare @sqlstatement nvarchar(4000)
--move declare cursor into sql to be executed
set @sqlstatement = 'Declare  users_cursor CURSOR FOR SELECT userId FROM users'

exec sp_executesql @sqlstatement


OPEN users_cursor
FETCH NEXT FROM users_cursor
INTO @UserId

WHILE @@FETCH_STATUS = 0
BEGIN
Print @UserID
EXEC asp_DoSomethingStoredProc @UserId

FETCH NEXT FROM users_cursor --have to fetch again within loop
INTO @UserId

END
CLOSE users_cursor
DEALLOCATE users_cursor
あなたはグローバルカーソルを使用しないように必要がある場合は、

、あなたはまた、一時テーブルにあなたの動的SQLの結果を挿入し、カーソルを移入し、そのテーブルを使用することができます。

Declare @UserID varchar(100)
create table #users (UserID varchar(100))

declare @sqlstatement nvarchar(4000)
set @sqlstatement = 'Insert into #users (userID) SELECT userId FROM users'
exec(@sqlstatement)

declare users_cursor cursor for Select UserId from #Users
OPEN users_cursor
FETCH NEXT FROM users_cursor
INTO @UserId

WHILE @@FETCH_STATUS = 0
BEGIN

EXEC asp_DoSomethingStoredProc @UserId

FETCH NEXT FROM users_cursor
INTO @UserId

END
CLOSE users_cursor
DEALLOCATE users_cursor

drop table #users

他のヒント

あなたは@STATEMENTに「+」を使用することはできませんので、

このコードでは、カーソルと動的な列のための非常に良い例です。

ALTER PROCEDURE dbo.spTEST
AS
    SET NOCOUNT ON
    DECLARE @query NVARCHAR(4000) = N'' --DATA FILTER
    DECLARE @inputList NVARCHAR(4000) = ''
    DECLARE @field sysname = '' --COLUMN NAME
    DECLARE @my_cur CURSOR
    EXECUTE SP_EXECUTESQL
        N'SET @my_cur = CURSOR FAST_FORWARD FOR
            SELECT
                CASE @field
                    WHEN ''fn'' then fn
                    WHEN ''n_family_name'' then n_family_name
                END
            FROM
                dbo.vCard
            WHERE
                CASE @field
                    WHEN ''fn'' then fn
                    WHEN ''n_family_name'' then n_family_name
                END
                LIKE ''%''+@query+''%'';
            OPEN @my_cur;',
        N'@field sysname, @query NVARCHAR(4000), @my_cur CURSOR OUTPUT',
        @field = @field,
        @query = @query,
        @my_cur = @my_cur OUTPUT
    FETCH NEXT FROM @my_cur INTO @inputList
    WHILE @@FETCH_STATUS = 0
    BEGIN
        PRINT @inputList
        FETCH NEXT FROM @my_cur INTO @inputList
    END
    RETURN

非リレーショナルデータベース(IDMS誰ですか?)ODBC接続を介しての操作カーソルと動的SQLが唯一のルート思わ当時の一つとしての資格ます。

select * from a where a=1 and b in (1,2)

は、1秒未満で実行されます句でなしのキーセットを使用するように書き換えながら応答するために45分かかります

select * from a where (a=1 and b=1)
union all
select * from a where (a=1 and b=2)

B列のための文でindidivudal文を作成し、動的SQLはWHERE句で使用するよりもはるかに高速であるとして、それらを実行するために、カーソルを使用して、1145行が含まれている場合。愚かなちょっと?

そして、はい、カーソルのは、使用すべきであるリレーショナルデータベースには時間がありません。私はちょうど私がカーソルループが数倍速くなり、インスタンス間で来ていると信じていないことができます。

まず最初にすべての可能性であれば、カーソルを使用しないでください。ここでは、せずにあなたが行うことができないと思われるときにそれを根絶するためのいくつかのリソースがあります:

あなたのカーソルを失う15個の方法...パート1、はじめに存在しなければなりません

カーソルをせずに行ごとの処理

これは、しかし、あなたはすべての後に1で立ち往生することができる、と述べた - 私はそれらのいずれかが適用されていることを確認するためにあなたの質問から十分に知りません。そのような場合、あなたは別の問題を持っている - あなたのカーソルのSELECT文は、の実際ののSELECT文ではなく、EXECUTE文でなければなりません。あなたは立ち往生してます。

しかし、一時テーブルの使用について(私が書いていた間、入って来た)cmsjrからの回答を参照してください。私は

.... のグローバルのカーソル "プレーン" のものよりもさらにを避けるだろう

後の切り替えてからOracle、SQLサーバー(事業主)、更にカーソルを支援SQLサーバーは遅れています。カーソルは必ずしも悪にも必要なものの方が早く、時にはリーダーと調整の複雑なクエリの再配置または追加を最適化します。の"カーソルの悪意見書"はすでに顕著にSQLサーバーです。

ねこの答えは、スイッチをOracleまたはMSの手掛かり

私はあなたと共有したいもう一つの例があります
:D http://www.sommarskog.se/dynamic_sql.html#cursor0する

は、SQL Serverの別のオプションは、その後、ストアドプロシージャでテーブル変数に動的なクエリのすべてを行う照会し、それを処理するためにカーソルを使用することです。恐ろしいカーソルの議論については:)、私は適切に設定している場合、いくつかの状況では、カーソルが実際に速くすることができることを示した研究を見てきました。 (私のため;)必要なクエリが複雑すぎる、またはちょうどない人間とき、私は彼らに自分自身を使用しています。)可能

このコードでは、あなたのために役立つことがあります。

SQL Serverでカーソル使用の

DECLARE sampleCursor CURSOR FOR 
      SELECT K.Id FROM TableA K WHERE ....;
OPEN sampleCursor
FETCH NEXT FROM sampleCursor INTO @Id
WHILE @@FETCH_STATUS <> -1
BEGIN

UPDATE TableB
   SET 
      ...
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top