代码之家  ›  专栏  ›  技术社区  ›  Steve Wranovsky

从.NET应用程序执行SQL Server脚本的最佳实践?

  •  4
  • Steve Wranovsky  · 技术社区  · 16 年前

    从.NET应用程序中执行SQL Server脚本的建议方法是什么?为什么?

    我正在创建一个可以从安装程序运行的应用程序,以便在安装应用程序的早期版本时处理数据库的升级。数据库有一个版本表,我可以通过编程访问该表,并确定要运行哪个升级脚本来升级数据库。我把它嵌入到一个应用程序中是有意义的,我们的安装程序可以调用它来进行升级。

    我正在寻找如何最好地执行适当的升级脚本。在网上搜索我看到过用“go”语句拆分脚本的建议,并使用 SqlCommand.ExecuteNonQuery() . 我还看到了使用建议 SQL Server Management Objects (SMO) .

    我在寻找有关从.NET应用程序中执行这些脚本的各种方法的优缺点的建议。

    3 回复  |  直到 16 年前
        1
  •  1
  •   CodingBarfield    16 年前

    最好的方法是满足所有功能和非功能约束的任何方法。

    你需要什么样的速度,目前的情况有什么问题吗 您的备份/故障策略是什么

    我可能会使用sqlcommand.executeNonQuery(),因为它是.NET运行时的一部分,不需要用户不需要额外安装应用程序。

    根据您的问题,我假设有一个现有的应用程序,其中包含大量的嵌入式查询字符串。我将尝试将放入某种类型的存储库中,该存储库会自动将它们放在服务器(作为存储过程)和代码中。

    不要害怕使用查询的简单文本文件或其他配置文件。

        2
  •  2
  •   Taylor Gerring    16 年前

    虽然它可能不能特别满足您在.NET应用程序中运行的需要, sqlcmd 非常适合(和设计)这个过程。通过实现能力分析和运行SQL脚本,您将复制工具功能。sqlcmd在 standalone installer 可以与应用程序捆绑在一起。

    如果选择使用链接的sqlcommand.executeNonQuery()解决方案,那么对于大型脚本来说,将脚本读取到较小的缓冲区中搜索“go”语句(而不是一次读取所有语句)将更节省内存。

        3
  •  1
  •   jasonmw    16 年前

    我使用system.diagnostics.process并调用osql.exe得到了一致的结果。它是为一个SQL文件而设计的……

    我创建了一个临时文件,我在其中编写了我的嵌入式SQL文件,让OSQL执行它,然后清理它。

        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();