現在のデータベースをSQLステートメントで切り替えようとしています。私は次のことを試しましたが、すべての試みは失敗しました:
もう少し詳細を追加します。
編集:2つの別々のデータベースでいくつかのことを実行したいのですが、両方のデータベースが変数で設定されています。このようなもの:
USE Database1
SELECT * FROM Table1
USE Database2
SELECT * FROM Table2
私も同じ問題を抱えていますが、GOいですが便利なGOTOのセットでそれを克服しました。
すべてを実行する前に「スクリプトランナー」と呼ぶ理由は、実際のスクリプトを使用したい開発者から複雑さといアプローチを隠したいからです。同時に、2つの(3つ以上に拡張可能な)データベースでまったく同じ方法でスクリプトが実行されることを確認できます。
GOTO ScriptRunner
ScriptExecutes:
--------------------ACTUAL SCRIPT--------------------
-------- Will be executed in DB1 and in DB2 ---------
--TODO: Your script right here
------------------ACTUAL SCRIPT ENDS-----------------
GOTO ScriptReturns
ScriptRunner:
USE DB1
GOTO ScriptExecutes
ScriptReturns:
IF (db_name() = 'DB1')
BEGIN
USE DB2
GOTO ScriptExecutes
END
このアプローチを使用すると、変数を保持することができ、DECLAREステートメントを2回実行した場合でもSQL Serverが異常終了することはありません。
前者の問題は、あなたがやっていることはUSE 'myDB'
のではなく USE myDB
。文字列を渡している;しかし、USEは明示的な参照を探しています。
後者の例は私にとってはうまくいきます。
declare @sql varchar(20)
select @sql = 'USE myDb'
EXEC sp_sqlexec @Sql
-- also works
select @sql = 'USE [myDb]'
EXEC sp_sqlexec @Sql
KMの貴重なソリューションに感謝したかっただけです。 SQLServerでのデータベース圧縮要求の行数を減らすために、自分で実装しました。誰かを助けることができる場合、これは私のSQLリクエストです:
-- Declare the variable to be used
DECLARE @Query varchar (1000)
DECLARE @MyDBN varchar(11);
-- Initializing the @MyDBN variable (possible values : db1, db2, db3, ...)
SET @MyDBN = 'db1';
-- Creating the request to execute
SET @Query='use '+ @MyDBN +'; ALTER DATABASE '+ @MyDBN +' SET RECOVERY SIMPLE WITH NO_WAIT; DBCC SHRINKDATABASE ('+ @MyDBN +', 1, TRUNCATEONLY); ALTER DATABASE '+ @MyDBN +' SET RECOVERY FULL WITH NO_WAIT'
--
EXEC (@Query)
これを試して:
DECLARE @Query varchar(1000)
DECLARE @DatabaseName varchar(500)
SET @DatabaseName='xyz'
SET @Query='SELECT * FROM Server.'+@DatabaseName+'.Owner.Table1'
EXEC (@Query)
SET @DatabaseName='abc'
SET @Query='SELECT * FROM Server.'+@DatabaseName+'.Owner.Table2'
EXEC (@Query)
私は誰かがこれに対する解決策を必要とする場合、これは1つです:
動的なUSEステートメントを使用する場合、すべてのクエリは動的である必要があります。なぜなら、すべてのクエリは同じコンテキスト内にある必要があるからです。
SYNONYMで試すことができます。基本的には特定のテーブルのエイリアスです。このSYNONYMはsys.synonymsテーブルに挿入されるため、どのコンテキストからでもアクセスできます。
次の静的ステートメントを見てください。
CREATE SYNONYM MASTER_SCHEMACOLUMNS FOR Master.INFORMATION_SCHEMA.COLUMNS
SELECT * FROM MASTER_SCHEMACOLUMNS
動的になりました:
DECLARE @SQL VARCHAR(200)
DECLARE @CATALOG VARCHAR(200) = 'Master'
IF EXISTS(SELECT * FROM sys.synonyms s WHERE s.name = 'CURRENT_SCHEMACOLUMNS')
BEGIN
DROP SYNONYM CURRENT_SCHEMACOLUMNS
END
SELECT @SQL = 'CREATE SYNONYM CURRENT_SCHEMACOLUMNS FOR '+ @CATALOG +'.INFORMATION_SCHEMA.COLUMNS';
EXEC sp_sqlexec @SQL
--Your not dynamic Code
SELECT * FROM CURRENT_SCHEMACOLUMNS
@CATALOGの値を変更するだけで、同じテーブルを別のカタログからリストできます。
SQLCMDがオプションの場合、T-SQLでできること以上のスクリプト変数をサポートします。例: http://msdn.Microsoft.com/en-us/library/ms188714.aspx
あなたはこれを行うことができます:
Declare @dbName nvarchar(max);
SET @dbName = 'TESTDB';
Declare @SQL nvarchar(max);
select @SQL = 'USE ' + @dbName +'; {can put command(s) here}';
EXEC (@SQL);
{but not here!}
これは、次のような再帰的な選択ができることを意味します。
Declare @dbName nvarchar(max);
SET @dbName = 'TESTDB';
Declare @SQL nvarchar(max);
SELECT @SQL = 'USE ' + @dbName + '; ' +(Select ... {query here}
For XML Path(''),Type)
.value('text()[1]','nvarchar(max)');
Exec (@SQL)