简体   繁体   中英

Best practices for executing SQL Server Scripts from a .NET Application?

What is the recommended method for executing a SQL Server script from within a .NET application and why?

I'm in process of creating an application we can run from our installer to handle upgrading our database when a prior version of our application is installed. The database has a version table that I can programatically access and determine which upgrade scripts to run to get the database upgraded. It makes sense for me to embed this in an application that our installer can just call to do the upgrade.

I am looking for how best to execute the appropriate upgrade scripts. Searching the web I've seen recommendations for splitting a script by "GO" statements, and using SqlCommand.ExecuteNonQuery() . I've also seen recommendations for using SQL Server Management Objects (SMO) .

I'm looking for advice on the pros/cons of the various ways to execute these scripts from within a .NET application.

Although it may not specifically meet your needs to be run from within a .NET application, sqlcmd is well-suited (and designed) for this process. By implementing the ability parse & run a SQL Script, you are duplicating the tool functionality. sqlcmd is available in a standalone installer that could be bundled with your application.

If you choose to use the linked SqlCommand.ExecuteNonQuery() solution, it will be more memory efficient for large scripts to read the script into a smaller buffer searching for the "GO" statement, "instead of all-at-once".

I have had consistent results using a System.Diagnostics.Process and calling into OSQL.exe. its made for a sql file....

I created a temporary file where i wrote my embedded sql file, had OSQL execute it, then cleaned it up.

    process.StartInfo = new System.Diagnostics.ProcessStartInfo();
    process.StartInfo.FileName = OSQLpath;
    process.StartInfo.UseShellExecute = false;
    ...
    if (!System.IO.Directory.Exists(workingDirectory))
                        System.IO.Directory.CreateDirectory(workingDirectory);
    ...
    StringBuilder sbArgs = new StringBuilder();

    sbArgs.Append("-S ").Append(_serverName);
    sbArgs.Append(" -d ").Append(_databaseName);
    sbArgs.Append(" -E");
    sbArgs.Append(" -i ").Append("\"").Append(inputSQLFilePath).Append("\""); // input file
    sbArgs.Append(" -o ").Append("\"").Append(System.IO.Path.Combine(workingDirectory, String.Format("osqloutput_{1}_{0}.txt", fileUnique, fileName))).Append("\""); // output file

    process.StartInfo.RedirectStandardOutput = true;
    process.StartInfo.RedirectStandardError = true;

    process.StartInfo.Arguments = sbArgs.ToString();
    process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
    process.StartInfo.CreateNoWindow = true;

...

    System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor;
    process.Start();
    process.WaitForExit();

The best method would be any method that meets all functional and nonfunctional restraints.

What kind of speed do you need, is there any problem with the current situation What is your backup/failure strategy

I would probably use the SqlCommand.ExecuteNonQuery() because its a part of the .net runtime that needs no extra installation of applications the user might not need.

From your question I presume there is an existing application with lots of embedded query string. I would try to get the into a repository of some kind that automatically places them on the server (as a stored procedure) and inside your code.

Don't be afraid of simple text files or other config files with query's.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM