実行時にDB名+テーブル名のコンボが存在しない場合、指定されたDBのリスト内のテーブルを削除しますCleanUpTableListという名前のテーブルすべてのDBは同じサーバー上にあります。私はSQL Server 2014を使用しています。カーソルループを使用してデータベースを変更しようとしましたが、データベースは変更されません
DB名のリストを循環する外部カーソルループと、指定されたデータベース内のテーブル名のリストをプルインする内部カーソルループを作成することで、これを実行しようとしています。 CleanUpTableListに見つからず、それらのテーブルを削除します。しかし、外部ループがデータベースを変更できないようです。スクリプトは開始データベースの関連するテーブルにX回だけアクセスしますが、Xは多くのデータベース名のエントリが外部カーソルにあります。私はDatabase1をして開始し、私は私の外側のカーソルに3つのデータベース名のエントリを持って、代わりに取得するのであれば、例えば、:
DROP TABLE Database1..TableB
DROP TABLE Database1..TableC
DROP TABLE Database2..TableE
DROP TABLE Database2..TableF
DROP TABLE Database3..TableH
DROP TABLE Database3..TableI
私が取得:
DROP TABLE Database1..TableB
DROP TABLE Database1..TableC
DROP TABLE Database1..TableB
DROP TABLE Database1..TableC
DROP TABLE Database1..TableB
DROP TABLE Database1..TableC
...されていません本当に私が欲しいものなので、外側のループで何かが間違っていると仮定しています。私は通常のDB変更コマンドがあることを知っています
USE Database1;
GO
しかし、私はEXEC()でそれを行う方法を理解することができませんでした。それは、GOが「USE Database1;」と同じ行にあることができないため、EXEC()を使用するときに新しい行を作る方法がわからないために、GOの近くで構文エラーが発生していると私は思い出しました。私は
SET @ChangeDB = 'USE ' + @DatabaseName + ';'
EXEC(@ChangeDB + CHAR(13) + 'GO')
と
SET @ChangeDB ='USE ' + @DatabaseName + ';' +CHAR(13) + 'GO'
EXEC(@ChangeDB)
を使用してみましたが、これらはまた、構文エラーが返されました。
DB /表作成スクリプト:
CREATE DATABASE Database1;
CREATE DATABASE Database2;
CREATE DATABASE Database3;
CREATE DATABASE Database4;
CREATE TABLE Database1.dbo.TableA (Column1 INT, Column2 INT);
CREATE TABLE Database1.dbo.TableB (Column1 INT, Column2 INT);
CREATE TABLE Database1.dbo.TableC (Column1 INT, Column2 INT);
CREATE TABLE Database2.dbo.TableD (Column1 INT, Column2 INT);
CREATE TABLE Database2.dbo.TableE (Column1 INT, Column2 INT);
CREATE TABLE Database2.dbo.TableF (Column1 INT, Column2 INT);
CREATE TABLE Database3.dbo.TableG (Column1 INT, Column2 INT);
CREATE TABLE Database3.dbo.TableH (Column1 INT, Column2 INT);
CREATE TABLE Database3.dbo.TableI (Column1 INT, Column2 INT);
CREATE TABLE Database4.dbo.CleanUpTableList (DBName VARCHAR(20), TableName VARCHAR(20));
INSERT INTO Database4..CleanUpTableList VALUES ('Database1','TableA')
INSERT INTO Database4..CleanUpTableList VALUES ('Database2','TableD')
INSERT INTO Database4..CleanUpTableList VALUES ('Database3', 'TableG')
クリーンアップスクリプト:
DECLARE @fetch_database_cursor INT
DECLARE @DatabaseName VARCHAR(50)
DECLARE DatabaseList CURSOR FOR
select name from sys.databases
where
name IN ('Database1','Database2', 'Database3'
)
OPEN DatabaseList
FETCH NEXT FROM DatabaseList INTO @DatabaseName
/* Keep track of the outer loop FETCH_STATUS in a local variable */
SET @fetch_database_cursor = @@FETCH_STATUS
/* Use outer loop FETCH_STATUS local variable as condition for outer WHILE loop */
WHILE @fetch_database_cursor = 0
BEGIN
DECLARE @ChangeDB VARCHAR(2500)
DECLARE @TableName VARCHAR(50)
DECLARE @ExecuteSQL VARCHAR(2500)
DECLARE @fetch_table_cursor INT
/* Change DB here */
SET @ChangeDB = 'USE ' + @DatabaseName
EXEC(@ChangeDB)
/* Declare inner cursor */
DECLARE TableList CURSOR FOR
select table_name
from information_schema.tables
WHERE TABLE_TYPE = 'BASE TABLE'
AND table_name NOT IN (
SELECT TableName
FROM Database4..CleanUpTableList
WHERE DBName = @DatabaseName
)
ORDER BY table_name
OPEN TableList
FETCH NEXT FROM TableList INTO @TableName
/* Store inner cursor fetch_status in local variable */
SET @fetch_table_cursor = @@FETCH_STATUS
/* Use inner cursor fetch_status local variable as condition for inner WHILE loop */
WHILE @fetch_table_cursor = 0
BEGIN
SET @ExecuteSQL = 'DROP TABLE ' [email protected]
EXEC(@ExecuteSQL)
SELECT @Tablename, 'Has Been Successfully Dropped'
FETCH NEXT FROM TableList INTO @TableName
SET @[email protected]@FETCH_STATUS
END
/* Close and deallocate inner cursor */
CLOSE TableList
DEALLOCATE TableList
FETCH NEXT FROM DatabaseList INTO @DatabaseName
SET @fetch_database_cursor = @@FETCH_STATUS
END
/* Close and deallocate outer cursor */
CLOSE DatabaseList
DEALLOCATE DatabaseList
任意の提案が高く評価されている。ここ
は、関連するコードです。コードから
これは、サーバー上の少数のデータベースでのみ実行しようとしています。サーバー上の他のデータベースにはCleanUpTableListのエントリがないため、このスクリプトを実行すると意図しないテーブルの削除が発生するため、明示的に指定されたデータベースのみが関係することは非常に重要です。 ステートメントのdb_id()セクションを使用してこれらのデータベースを明示的に識別できると思いますか?同様に 'EXECUTE master.sys.sp_MSforeachdb 'USE [?]; db_id()IN(1,2,3)が返された場合、ドロップテーブルdbo.sometable '' –
あなたの特定のシナリオの更新を参照 – TheGameiswar