0

大規模なデータベース作成クエリがあり、その最初は次のとおりです。

USE Master
GO

IF EXISTS(SELECT * FROM sys.sysdatabases where name = 'MyDatabase')
    DROP DATABASE MyDatabase
GO
CREATE DATABASE MyDatabase
GO
USE MyDatabase
GO

最初に次のように変数を宣言したいと思います。

DECLARE @MainDB VARCHAR(30) = NULL
USE Master
GO

IF EXISTS(SELECT * FROM sys.sysdatabases where name = @MainDB)
    DROP DATABASE @MainDB
GO
CREATE DATABASE @MainDB
GO
USE @MainDB
GO

sqlcmdツールを使用して割り当てられた新しいデータベース名を使用して、コマンドラインからこのクエリを実行します。ただし、SQLは、変数@MainDBが宣言されていないことを通知しています。これは私にできることですか?そうでない場合は、この問題を回避することをどのように推奨しますか?

4

5 に答える 5

0

コマンドライン変数をt-sql変数と等しくする方法を見つけました

USE master
GO
DECLARE @Mydb VARCHAR(30) = "$(mydb)"

IF EXISTS(SELECT * FROM sys.sysdatabases where name = @Mydb)
    print @Mydb
    Execute('create database ' + @Mydb)

私が実行するバッチファイルは次のようになります。

sqlcmd -S %1 -i CreateDatabases.sql -v mydb="%2"

これで、sqlcmdから実行して、%1にサーバーを入力し、%2に目的のDB名を入力できます。

返信してくれたみんなに感謝します。彼らは皆、私が正しい解決策を見つけるのを助けてくれました。

于 2012-10-10T18:34:49.943 に答える
0

この質問は一種の再ハッシュです。

T-SQLでデータベース名に変数を使用するにはどうすればよいですか?

簡単な答えは、可変データベース名を持つことはできないということです。T-SQLをstring/VARCHAR(MAX)に入れ、検索と置換を行ってから実行する必要があります。

于 2012-10-09T19:47:40.710 に答える
0

申し訳ありませんが、SQL変数には「バッチ」スコープしかなく、これらの「GO」コマンドはバッチの境界を示すため、このようにすることはできません。したがって、GOに合格するたびに、すべての変数が消去されます(宣言されていません)。

これを回避する方法はいくつかあります。

  1. GOを取り除く:これは、スクリプトの代わりにストアドプロシージャ(GOを含めることはできません)が必要な場合に行うことですが、非常に複雑な一連の洗練されたトリックであり、それをやってのけるために。それを使用するには、かなりT-SQLに精通している必要があります。

  2. 代わりに、#tempテーブルを使用して値を保持してください。これが機能するのは、#tempテーブルに代わりにsession-scopeまたは単にbatch-scopeがあるためです。

  3. SQLCMDからNTDOS環境変数を使用および操作することもできると思いますが、その方法についてはよくわかりません。

これらのいずれかを追求したい場合は、どれを教えてください。例を使用して、より詳細に説明できます。


おっと、これの「可変データベース名」の部分を見逃しました。これも可能ですが、動的SQLをミックスに追加する必要があります。

于 2012-10-09T19:53:55.147 に答える
0

複数の問題があります... GO 現在のバッチを終了します。したがって、変数は表示されなくなります。宣言を移動する必要があります。DROP DATABASE @MainDBまた、動的クエリを使用することはできません。例えば、

GO 
DECLARE @MainDB VARCHAR(30) = 'MyDB';
IF EXISTS(SELECT * FROM sys.sysdatabases where name = @MainDB)
BEGIN
  EXECUTE ('DROP DATABASE '+@MainDB);
END;
于 2012-10-09T19:54:31.383 に答える
0

コマンドラインからこれを実行する必要があると言うので、すでに構築した構造に依存するコードがたくさんある場合は、次のようにすることができます。

  1. スクリプトの一時的なコピーを作成します
  2. @MainDBを検索して、一時スクリプトのパラメーターとして渡したDB名に置き換えます
  3. sqlcmdツールを使用して一時スクリプトを実行します

明らかに、このオプションが必要な場合は、スクリプトからDECLARE @MainDB varchar(30)=NULLを削除してください。

このアプローチを選択した場合、さまざまな異なるテクノロジ(PowerShell、Python、バッチファイル、VBScriptなど)を使用して3つのステップを実装できます。

VBScriptファイルアプローチ:

set obj = CreateObject("Scriptlet.TypeLib")  
tempsqlfile = obj.GUID & ".sql" 'get a new name for your sql file

set fso = CreateObject("Scripting.FileSystemObject")
set objFile = objFSO.OpenTextFile(tempsqlfile, ForReading) 'open the template file
strSQLText = objFile.ReadAll
objFile.Close

strNewSQLText = Replace(strSQLText, "@MainDB", Wscript.Arguments(1)) 'replace the db name
Set objFile = objFSO.OpenTextFile(tempsqlfile, ForWriting)
objFile.WriteLine strNewText 'write the new file
objFile.Close

Set Shell = WScript.CreateObject("WScript.Shell")
commandLine = "osql -E -i " & Wscript.Arguments(0) & -o " & tempsqlfile & ".rpt"
Set oExec = Shell.Exec(commandLine)

変数名についてお詫びします-私はさまざまな場所から断片を切り取って貼り付けましたが、要点を理解する必要があります。

(また、これらすべてのオプションからVBScriptを選択したことをお詫びします。また、欠落しているパラメーターのチェックでエラーが発生しないことに注意してください)

上記のように、そのスクリプトを「runmystuff.vbs」として保存すると、次のことができます。

runmystuff.vbs sqlfile.sql MagicNewDB

これにより、スクリプト内のすべての場所で@MainDBがMagicNewDBに置き換えられ、osqlを使用して実行されます。

于 2012-10-09T22:00:00.003 に答える