2009-07-28 7 views
2

SQLスクリプトを手動で解析して各ステートメントを個別に実行する必要がありますか、それとも良い方法がありますか? プログラムで解決策を探している私は、すでにこれを行うことができるツールがあることを知っています。 ソリューションがsqliteだけでなく、すべてのデータベースシステムで動作するのは良いことです。C#:SQLスクリプトをデータベースにプログラムにインポートするには?

+0

レコードをデータベースにインポートしようとしていますか? – jn29098

+0

あなたのスクリプトがどこから来たのか尋ねることはできますか?この情報は答えによく影響するかもしれません... Rob –

答えて

2

私はこれがSqlLiteに適用されるかどうかはわかりませんが、私はのSQLServerと、次のようなコードを使用しました:

protected virtual void ExecuteScript(SqlConnection connection, string script) 
{ 
    string[] commandTextArray = script.Split(new string[] { "GO" }, StringSplitOptions.RemoveEmptyEntries); // See EDIT below! 
    connection.Open(); 
    foreach (string commandText in commandTextArray) 
    { 
     if (commandText.Trim() == string.Empty) continue; 
     SqlCommand command = new SqlCommand(commandText, connection); 
     command.ExecuteNonQuery(); 
    } 
    connection.Close(); 
} 

(警告:私は私の元のコードを少し変更する必要がありましたので、これはですテストされていないコード)

ADO.NET経由でスクリプトを実行しているときに "GO"という単語が問題であることがわかりました。そのため、コード全体で "GO"を区切り文字としてSplit()一連のコマンドを使って、一度に1つずつ実行します。

EDIT:別の単語の一部は間違いなく正当な関心事であるとして、スクリプトで表示されることがあり、「GO」その下のマークさんのコメント@

。私は上記のコードを書いたときに覚えている、私は "GO"がバッチセパレータとしてのみ現れたことを確認するスクリプトを検索した。別の方法としては、「GO」の後に常に「 - SPLIT HERE!」などのコメントが続くようにすべてのスクリプトを編集するという方法もあります。区切り文字を「GO-SPLIT HERE!」に変更します。ただし、スクリプトを編集する必要があります。さらに別のオプションは、Regex.Split()です。これは、GOの前に空白がないかどうかを確認することができます。私のスクリプトでは、私のバッチセパレータは常に自分の行に行きます。

string[] commandTextArray = System.Text.RegularExpressions.Regex.Split(script, "\r\n[\t ]*GO"); 

一番下の行は、バッチ区切りのためのいくつかの書式設定の一貫性を正確にスクリプトを分割するために必要とされることである:同じルールはスクリプトに適用された場合は、次のようなものは動作するはず。

+0

引用符、コメント、大文字と小文字の区別、または - あなたの例 - 別の単語の一部としてGOに注意してください。 –

+0

ありがとう、@マーク、良いコメント。私は自分の答えを更新しました。 – devuxer

+0

SqlCommandコマンド=新しいSqlCommand(スクリプト、接続); は にする必要があります。SqlCommandコマンド=新しいSqlCommand(commandText、connection); – WowtaH

2

DbCommand.ExecuteNonQueryメソッドを使用すると、データベースに対して任意のSQLを実行できます。 SqlCommandオブジェクトと

サンプル:

var command = new SqlCommand("CREATE TABLE foo ...", connection); 
command.ExecuteNonQuery(); 

それは「GO」を含んでいる場合には、複数のバッチでコマンドを分割しますので、あなたは、コマンドを分割する必要があるかもしれない別の回答で示唆したように。

+0

空白行やコメントを含む多くの異なるSQL文を含む大きな文字列を実行することができますか? – codymanix

+0

はい、コマンドをSQLに変更せずに送信します。 –

1

私はSqlLiteに精通していませんが、ほとんどのRDBMS 'ではセミコロンで終了すると複数の文を送信できます。 MSSQLのように、改行文字をステートメントターミネータとして受け付けるものもあります。セミコロン+改行は、最も幸せになり、よくフォーマットされたコードにつながります。

バッチ区切り文字を使用している場合 - MSSQLでは通常は「GO」です - クライアントが解析するようにもう少し作業が必要です。 MSSQLを処理するためにcoupleofsolutionsがありましたが、どのように移植性があるかはわかりません。私はHaack'sが最高の出発点だと思う。

+0

SQLiteはセミコロンを受け入れます。 – MyItchyChin

0

次のコードでは、Config.Database.CreateCommandTextは、データベース内のテーブルとインデックスを作成するセミコロン区切りステートメントのコレクションです。次の例は、System.Data.SQLiteを使用せずにDBを作成します。

private SQLiteCommand command; 
private SQLiteConnection connection; 

connection = new SQLiteConnection(Config.Database.ConnectionString.ToString()); 
connection.Open(); 

command = connection.CreateCommand(); 

SQLiteConnection.CreateFile(Config.Database.Path); 

command.CommandText = Config.Database.CreateCommandText; 

command.ExecuteNonQuery(); 
0

私はダムの答えに同意しています: - :\ \プログラムファイル(x86の)SQLスクリプトでの取り扱い「GO」セパレータは、SQL Serverのフォルダ「Cで見つけることができるのDDLが必要になります簡単な方法http://weblogs.asp.net/jgalloway/archive/2006/11/07/Handling-_2200_GO_2200_-Separators-in-SQL-Scripts-2D00-the-easy-way.aspx Microsoft SQL Server \ 100 \ SDK \ Assemblies \ "

Microsoft.SqlServer.ConnectionInfo.dll 
Microsoft.SqlServer.Management.Sdk.Sfc.dll 
Microsoft.SqlServer.Smo.dll 

互換性のあるフレームワークなので、この行を設定ファイルに追加してください。

<startup useLegacyV2RuntimeActivationPolicy="true"> 
    <supportedRuntime version="v4.0" /> 
</startup> 

この投稿に記載されている回答は、より洗練されている必要があります。たとえば例外をハンドリングし、ロールバックできるようにする... SQLトランザクションの詳細についてはhttp://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqltransaction.aspxをチェックしてください。

関連する問題