web-dev-qa-db-ja.com

すべてのSQLテーブルをループする方法は?

不要になったエントリを削除しないソフトウェアがあります。サーバーで無駄になっているデータの量を感じて、大きなクリーンアップ操作の準備をするために、すべてのテーブルをループして、削除対象としてマークされているレコードをプルしようとしています。これは私が取り組んでいるものです:

DECLARE @total INT
DECLARE @count INT
DECLARE @name NVARCHAR(25)
DECLARE @rn INT

SET @total = (SELECT COUNT(Name) FROM sys.tables)
SET @count = 1
SET @rn = (SELECT ROW_NUMBER() OVER(ORDER BY Name) FROM sys.tables)   

WHILE @count <= @total AND @count < 2
    BEGIN
        SET @name = (   SELECT Name, ROW_NUMBER() OVER(ORDER BY Name)
                        FROM sys.tables 
                        WHERE @rn = @count
                     )

        EXEC('SELECT * FROM WS_Live.dbo.' + @name + ' WHERE GCRecord IS NOT NULL')
        SET @count += 1         
    END

これは私のエラーです:

メッセージ116、レベル16、状態1、行19サブクエリがEXISTSで導入されていない場合、選択リストで指定できる式は1つだけです。

私のエラーはおそらく行の2つの列を選択することに関係していることに気づきました

        SET @name = (   SELECT Name, ROW_NUMBER() OVER(ORDER BY Name)
                        FROM sys.tables 
                        WHERE @rn = @count
                     )

しかし、次の行を選択していることを確認する他の方法がわかりません。

追伸AND @count <2はスクリプトのテスト用です。

すべてのテーブルをループするにはどうすればよいですか?

13
NonSecwitter

このシステムストアドプロシージャを使用する

sp_MSforeachtable @command1="select count(*) from ?"

サンプルコード

注:このsp_MSforeachtableは文書化されていないストアドプロシージャです

24
Hiten004

多分これはあなたが探しているものです

DECLARE @NAME VARCHAR(100)
DECLARE @SQL NVARCHAR(300)

DECLARE CUR CURSOR FOR
  SELECT NAME
  FROM   SYS.TABLES
  WHERE  TYPE = 'U'
         AND SCHEMA_ID = 1

OPEN CUR

FETCH NEXT FROM CUR INTO @NAME

WHILE @@FETCH_STATUS = 0
  BEGIN
      SET @SQL = 'SELECT * FROM WS_LIVE.DBO.'+@NAME+' WHERE GCRECORD IS NOT NULL'

      PRINT @SQL
      EXEC Sp_executesql
        @SQL

      FETCH NEXT FROM CUR INTO @NAME
  END

CLOSE CUR

DEALLOCATE CUR 
13

SQLでカーソルを使用することがリスクになる場合があります。以下のSQLクエリは、CURSORを使用せずに、選択したデータベースのすべてのテーブルをトラバースします。

USE TEST
Declare @TableName nvarchar(256) 
SET @TableName = ''

WHILE @TableName IS NOT NULL
BEGIN
    SET @TableName = 
    (
        SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
        FROM    INFORMATION_SCHEMA.TABLES
        WHERE       TABLE_TYPE = 'BASE TABLE'
            AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
    )
print @TableName -- Your logic will come here
END
GO

上記のSQLステートメントは[〜#〜] test [〜#〜]データベース内のすべてのテーブルを出力します。したがって、print tableステートメントの代わりに、各テーブルのループで実行したいもののような独自のSQLロジックを指定でき、@ TableNameには現在のループのテーブル名が含まれます。

0
Rinoy Ashokan