0

SQL スクリプトを実行して、データベース スキーマを変更します。次のようになります。

using (var command = connection.CreateCommand())
{
    command.CommandText = script;
    command.ExecuteNonQuery();
}

さらに、コマンドはトランザクション内で実行されます。

スクリプトは次のようになります。

Alter Table [TableName]
ADD [NewColumn] bigint NULL

Update [TableName]
SET [NewColumn] = (SELECT somevalue FROM anothertable)

NewColumn存在しないため、エラーが発生します。実行前に解析して検証するようです。

Management Studio で全体を実行するとGO、ステートメントの間に入れることができ、機能します。スクリプトに入れるGOと、ADO.NET が文句を言います (「GO」付近の構文が正しくありません)。

スクリプトを別々のスクリプトに分割し、別々のコマンドで実行することもできますが、これは扱いにくいでしょう。GOスクリプトを自分で解析して、すべてに分割できました。もっと良い解決策があるべきだと思いますが、何かがわかりませんでした。このようなスクリプトはどのように実行する必要がありますか?


John Saunders の回答によると、誰かが興味を持っている場合の私の実装:

List<string> lines = new List<string>();
while (!textStreamReader.EndOfStream)
{
    string line = textStreamReader.ReadLine();
    if (line.Trim().ToLower() == "go" || textStreamReader.EndOfStream)
    {
        ExecuteCommand(
            string.Join(Environment.NewLine, lines.ToArray()));

        lines.Clear();
    }
    else
    {
        lines.Add(line);
    }
}
4

2 に答える 2

2

それを行うために多数のORMライブラリの1つを使用していませんか? 良い :-)

構造的な変更を行うスクリプトを実行する際に完全に安全を確保するには、SqlClient ではなく SMO を使用し、接続文字列を介して MARS がオンになっていないことを確認します (いずれにせよ、SMO は通常、文句を言います)。ServerConnectionクラスと ExecuteNonQueryを探します - もちろん別の DLL :-)

相違点は、SMO dll がスクリプトをそのまま SQL に渡すことです。これは、SSMS または isql コマンド ラインを介してスクリプトを実行するのとまったく同じです。GO のスライスは、別のグリッチに遭遇するたびに、はるかに大きなスキャンに成長します (GO が複数行のコメントの途中にある、複数の USE ステートメントがある、スクリプトがまさにその DB をドロップしているなど)。 SqlCLient が接続されました - おっと :-)。継承したコードベースでそのようなものを1つ殺しました(より複雑なスクリプトがMARSと競合し、MARSは運用コードには適していますが、管理者には適していません).

于 2010-08-14T22:18:33.770 に答える
1

各バッチを個別に実行する必要があります。特に、複数のバッチ(「GO」キーワード)を含む可能性のあるスクリプトを実行するには、「GO」キーワードでスクリプトを分割する必要があります。

未検証:

string script = File.ReadAllText("script.sql");
string[] batches = script.Split(new [] {"GO"+Environment.NewLine}, StringSplitOptions.None);
foreach (string batch in batches)
{
    // run ExecuteNonQuery on the batch
}
于 2010-06-23T14:59:31.577 に答える