【问题标题】:c# - Running multiple SQL scriptsc# - 运行多个 SQL 脚本
【发布时间】:2017-10-26 06:21:27
【问题描述】:

我知道我的问题似乎有点宽泛,但我会尽量做到具体和简短。所以我目前正在用 c# 编写一个关于数据归档的程序。基本上,我会有一个按钮,当我单击它时,它应该会在我的 SQL Server 数据库中生成新表。

我的问题是执行查询的方法。我已经有一个 sql 脚本文件列表(用 SSMS 编写),我想在 c# 中执行它们(按顺序)。 我应该将脚本硬编码到我的 c# 程序中以创建表吗?它看起来像这样:

  private void btnCreateTables_Click(object sender, EventArgs e){
    string query = "IF OBJECT_ID('dbo.AuditCardTypeBenefit_TEST','U') IS NULL ";
    query += "BEGIN ";
    query += "CREATE TABLE[dbo].[AuditCardTypeBenefit_TEST]( "; 
    query += "[AuditID] [decimal](18, 0) IDENTITY(1,1) NOT NULL, ";
    query += "[AuditType] [char](5) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, ";
    query += "[CardTypeBenefitID] [decimal](18, 0) NOT NULL, ";

    query += "[EventCode] [varchar](8) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, ";
    query += "[CardTypeGroupID] [varchar](5) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, ";
    query += "[AgeFrom] [int] NULL, ";
    query += "[AgeTo] [int] NULL, ";

    query += "[Gender] [char](1) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, ";
    query += "[CreateBy] [nvarchar](128) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, ";
    query += "[CreateDate] [datetime] NOT NULL, ";
    query += "[Status] [char](2) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, ";
    query += "[CancelReason] [varchar](250) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, ";
    query += "[LastChangeBy] [nvarchar](128) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, ";
    query += "[LastChangeDate] [datetime] NOT NULL, ";
    query += "[RecordVersion] [timestamp] NOT NULL ";
    query += ") ON [PRIMARY] ";
    query += "END "; }

或者我应该通过在 c# 中读取文件(调用它们)来执行脚本文件吗?我想知道是否可以按特定顺序阅读它们。另外,脚本文件中的一些SQL语句在c#中读取是不兼容的,例如GO语句。

我正在考虑像我刚刚在上面发布的代码一样对其进行硬编码,因为它可以按照我想要的顺序执行表格生成。问题是想象如果我想创建 50 个表,那么代码行会很长。

因为我的想法是点击按钮,然后它将在 sql server 中创建所有表。

最好的建议是什么?

编辑: 我尝试执行 sql 脚本文件,看看它是否可行。就是这样:

private void btnCreateTables_Click(object sender, EventArgs e)
        {
 string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;

            try
            {
                using (SqlConnection con = new SqlConnection(constr))
                {
                    FileInfo file = new FileInfo("C:\\Users\\88106221\\Documents\\PromotionEvent_Test.sql");
                    string script = file.OpenText().ReadToEnd();
                    Server server = new Server(new ServerConnection(con));
                    server.ConnectionContext.ExecuteNonQuery(script);
   }

            }
            catch(Exception ex)
            {

                MessageBox.Show(ex.Message);
                textBox1.AppendText(string.Format("{0}", Environment.NewLine));
                textBox1.AppendText(string.Format("{0} MainPage_Load() exception - {1}{2}", _strThisAppName, ex.Message, Environment.NewLine));
                Debug.WriteLine(string.Format("{0} MainPage_Load() exception - {1}", _strThisAppName, ex.Message));

            }

现在它说找不到我的 PromotionEvent_Test.sql 目录。我检查了目录,它是正确的。是什么原因?

【问题讨论】:

  • 建议:使用文字字符串 (@"(IF OBJECT_ID('dbo.AuditCardTypeBenefit_TEST','U') IS NULL) ...") 来包装长 SQL 查询,或者将查询放入存储过程/脚本文件并调用。
  • 但是我有不同的 sql 脚本,每个脚本代表一个不同的表,具有不同的数据类型、约束、触发器、索引等。您的建议不是将所有内容连接到一个查询中吗?
  • 如果您已经将 SQL 脚本作为文件保存,您可能只想将它们全部放在一个目录中,并将它们命名为 1.sql、2.sql、...n.sql。然后你可以按照你想要的顺序阅读它们。
  • @Zohar,这就是我现在的想法。但是 c# 可以像 SQL server 读取脚本文件一样读取脚本文件吗?

标签: c# .net sql-server ssms


【解决方案1】:

要运行脚本文件,请使用此 C# 方法。

public void CreateDataBase(string FileNameWithPath)
{
    List<string> cmds = new List<string>();
    if (File.Exists(_pFileNameWithPath))
    {
        TextReader tr = new StreamReader(FileNameWithPath);
        string line = "";
        string cmd = "";
        while ((line = tr.ReadLine()) != null)
        {
            if (line.Trim().ToUpper() == "GO")
            {
                cmds.Add(cmd);
                cmd = "";
            }
            else
            {
                cmd += line + "\r\n";
            }
        }
        if (cmd.Length > 0)
        {
            cmds.Add(cmd);
            cmd = "";
        }
        tr.Close();
    }
    if (cmds.Count > 0)
    {
        try
        {
            using (SqlCommand command = new SqlCommand())
            {
                command.Connection = new SqlConnection("ConnectionString To Master");
                command.CommandType = CommandType.Text;
                if (command.Connection.State == System.Data.ConnectionState.Closed)
                {
                    command.Connection.Open();
                }
                for (int i = 0; i < cmds.Count; i++)
                {
                    command.CommandText = cmds[i];
                    command.ExecuteNonQuery();
                }
            }
        }
        catch (Exception exp)
        {
            MessageBox(exp.Message);
        }
    }
}

并使用它

CreateDataBase ("C:\1.SQL");
CreateDataBase ("C:\2.SQL");
CreateDataBase ("C:\3.SQL");
CreateDataBase ("C:\4.SQL");
CreateDataBase ("C:\5.SQL");
CreateDataBase ("C:\6.SQL");
CreateDataBase ("C:\7.SQL");
CreateDataBase ("C:\8.SQL");
CreateDataBase ("C:\9.SQL");

【讨论】:

  • 我试试看
  • 我正在考虑将它们放入我的“btnCreateTables”中,以便在我单击它时生成表格。它会以同样的方式工作吗?
  • @LordCookie 我不鼓励直接在 button_click 处理程序中执行此操作。它将阻止您的 UI 线程,使应用程序无响应。
  • 但至少我想让我的程序以这种方式运行。
猜你喜欢
  • 2016-04-27
  • 2013-11-20
  • 2022-12-11
  • 1970-01-01
  • 2021-08-16
  • 2017-12-12
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多