web-dev-qa-db-ja.com

sql useステートメントと変数

現在のデータベースをSQLステートメントで切り替えようとしています。私は次のことを試しましたが、すべての試みは失敗しました:

  1. @DatabaseNameを使用
  2. EXEC sp_sqlexec @Sql-@Sql = 'USE [' + @DatabaseName + ']'

もう少し詳細を追加します。

編集:2つの別々のデータベースでいくつかのことを実行したいのですが、両方のデータベースが変数で設定されています。このようなもの:

USE Database1
SELECT * FROM Table1

USE Database2
SELECT * FROM Table2
25
Drejc

私も同じ問題を抱えていますが、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が異常終了することはありません。

10
Alpha

前者の問題は、あなたがやっていることは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
9
Joel Goodwin

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)
4
tmi

これを試して:

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)
2
KM.

私は誰かがこれに対する解決策を必要とする場合、これは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の値を変更するだけで、同じテーブルを別のカタログからリストできます。

2
Hans Langer

SQLCMDがオプションの場合、T-SQLでできること以上のスクリプト変数をサポートします。例: http://msdn.Microsoft.com/en-us/library/ms188714.aspx

1
onupdatecascade

あなたはこれを行うことができます:

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)
0
Garry_G