1

特定の条件下で実行する必要がある SQL テーブルに動的 SQL を格納しています。現在、カーソルを使用してそれを処理していますが、カーソルは最も効率的な方法ではないため、可能な限り避けるように常に言われていました。それで、私の質問は、それらなしで動的SQLを実行するにはどうすればよいですか(方法がある場合)?システム全体は、この動的な SQL の混乱を中心に構築されているため、変更する必要はありません。

このために、テーブルにId AS IDENTITYSQL AS VARCHARフィールドがあり、SQL フィールドには実行される SQL が含まれていると仮定します (当然のことです)。

編集: 基本的に、テーブルをループして、SQL 列で SQL を実行したいと考えています。

したがって、テーブルの行は基本的に次のようになります。

ID   SQL
--   ----------------------
1    SELECT * FROM RECORD
2    SELECT * FROM PERSON
3    SELECT * FROM LOCATION

私が書くのは、テーブルを走査して実行するためのカーソルであるため、コードを書いていません。次のようなもの以外に、テーブルをループしてその文字列を SQL クエリとして実行する他の方法を知りません。

DECLARE @sql VARCHAR(MAX)

DECLARE _cursor CURSOR
FOR
    SELECT  [SQL]
    FROM    #tmp2

OPEN _cursor

FETCH NEXT FROM _cursor INTO @sql

WHILE @@FETCH_STATUS = 0 
    BEGIN
        PRINT ( @sql )
    END
CLOSE _cursor   
DEALLOCATE _cursor
4

2 に答える 2

3

カーソルを使用せずに連結のトリックをいくつでも使用して、1 つの大きなバッチを作成できます。私は個人的にこのFOR XMLトリックをよく使用します。

概要は次のとおりです。

http://www.simple-talk.com/sql/t-sql-programming/concatenating-row-values-in-transact-sql/

ただし、カーソル (通常はコードの匂いがしますが) は、これの非パフォーマンスにひどく寄与することはありません。また、単一のバッチよりもはるかに簡単にエラーなどを処理する機会があります。

さらに、バッチの最初のステートメントでなければならないステートメントの一部に DDL がある場合は、それらを別々のバッチで送信する必要があります。EXEC または sp_executesql は、SSMS に GO バッチ区切り記号があるように、バッチ分割を実装していません。

于 2012-08-06T19:03:14.100 に答える
2

このスキーマ全体の根本的な欠陥を無視しています....

declare @sql nvarchar(max) 
   select @sql = '' 
   select @sql = @sql + SQL + ';' from #tmp2  

   exec sp_executesql @sql

少なくとも、カーソルを削除しました :)

編集:私のために働いているコード...

create table #tmp2 (sql nvarchar(100))
insert #tmp2 values ('select * from sysobjects')
insert #tmp2 values  ('Select * from sysColumns')    
declare @sql nvarchar(max) 
   select @sql = '' 
   select @sql = @sql + SQL + ';' from #tmp2       
   exec sp_executesql @sql        
drop table #tmp2
于 2012-08-06T18:54:58.107 に答える