【问题标题】:Running SQL commands and getting message back运行 SQL 命令并返回消息
【发布时间】:2014-04-27 15:36:11
【问题描述】:

我正在开展一个项目,希望能够向 SQL Server 发送命令并运行查询。我已经成功地使用 Joel 的非常好的教程将查询返回到列表框: creating a database query METHOD

我现在正在尝试调整它以执行一些命令,然后运行查询以检查命令是否有效。我的查询失败,因为我认为这些命令不起作用。

目前我正在发送这个:

     MySqlCommand("CREATE TABLE #CSVTest_Data" +
                  "(FirstTimeTaken DATETIME," +
                  "LatestTimeTaken DATETIME," +
                  "Market VARCHAR(50)," +
                  "Outcome VARCHAR(50),"+
                  "Odds DECIMAL(18,2)," +
                  "NumberOfBets INT," +
                  "VolumeMatched DECIMAL(18,2),"+
                  "InPlay TINYINT)");

进入这个:

    private void MySqlCommand(string sql)
    {
        int numberOfRecords;
        //string result;
        using (var connection = GetConnection())
        using (var command = new SqlCommand(sql, connection))
        {
            connection.Open();
            numberOfRecords = command.ExecuteNonQuery();
        }
        MessageBox.Show(numberOfRecords.ToString());
    }

我的理解是 ExecuteNonQuery 返回影响行数的整数。我的消息框显示值为 -1。在 SQL Server 中运行相同的命令会返回“命令已成功完成”。如果有人能告诉我我的 MySqlCommand 方法看起来是否正常,以及我如何返回通过运行该函数输出的 SQL Server 消息,我将不胜感激。

【问题讨论】:

    标签: c# sql .net sql-server


    【解决方案1】:

    为了获取输出到 SQL Server Management Studio 中的 Messages 选项卡的消息,在 SQL Server 上执行 SQL 语句时的“控制台”,需要挂钩到InfoMessage event on the SqlConnection class

    using (var connection = GetConnection())
    using (var command = new SqlCommand(sql, connection))
    {
        connection.InfoMessage += (s, e) =>
        {
            Debug.WriteLine(e.Message);
        };
        connection.Open();
        numberOfRecords = command.ExecuteNonQuery();
    }
    

    显然,您需要以不同于我上面显示的方式处理事件,并且这里的e 参数还有其他属性,请参阅SqlInfoMessageEventArgs 了解详细信息。

    现在话虽如此,请记住,输出到 SQL Server Management Studio 中的消息选项卡的某些消息是由该程序生成的,而不是源自来自服务器本身,因此我无法确定您所询问的特定消息是否会通过该事件出现。

    另外,在这种特殊类型的 SQL 语句中,ExecuteNonQuery 的正确返回值实际上是 -1,as is documented

    对于 UPDATE、INSERT 和 DELETE 语句,返回值是受命令影响的行数。当正在插入或更新的表上存在触发器时,返回值包括受插入或更新操作影响的行数以及受一个或多个触发器影响的行数。 对于所有其他类型的语句,返回值为 -1。如果发生回滚,返回值也是-1。

    (我的重点)

    【讨论】:

      【解决方案2】:

      改变

      var numberOfRecords = command.ExecuteNonQuery();
      

      var numberOfRecords = command.ExecuteScalar();
      

      另外,请查看SqlCommand Methods

      【讨论】:

      • 没错,我正在创建一个临时表。然后我想运行更多代码来填充它,重新组织它,然后将它插入到实时数据库中。使用 ExecuteScalar 命令,我现在发现代码可以执行我想要的命令,但似乎我无法查询临时表。通过删除 # 并创建一个适当的表,我可以查询它。有没有办法查询临时表?
      • 是的,你可以。没有区别,例如Select Count(*) from #CSVTest
      • 我发现 CREATE TABLE CSVTest_data 有效,但从 Visual Studio 运行时 CREATE TABLE #CSVTest_data 无效。两者都可以在 SQL Server 中正常工作。任何想法为什么?
      • 另外,如果我在 SQL Server 中创建临时表然后运行:return Query("Select Count(*) from #CSVTest_Data");,从 VS,它返回 'Invalid object name'# CSVTest_Data'。
      • @SteveW:是的,我建议你在这种情况下使用stored procedure。这将更容易处理,因为您可以在 sql server 中完成所有操作
      【解决方案3】:

      您应该使用 ExecuteScalar

      ExecuteScalar 通常在您的查询返回一个值时使用。

      ExecuteNonQuery 用于 SQL 语句,如 update、insert、create 等。

      所以改成

      numberOfRecords = (int)command.ExecuteNonQuery();
      

      【讨论】:

        【解决方案4】:

        这是来自 MSDN 对 ExecuteNonQuery 的评论:

        对于 UPDATE、INSERT 和 DELETE 语句,返回值为 受命令影响的行数。 ... 对于所有其他类型的 语句,返回值为-1。

        由于您既没有执行 UPDATE 也没有执行 INSERT 也没有执行 DELETE - 即使操作成功,您也会收到 -1。基本上,您可以假设如果没有抛出 SqlException - 您的 CREATE 语句有效。

        【讨论】:

        • +因为-1无一例外都是成功的,你可以简单地自己发消息,发给你的Textbox
        【解决方案5】:
        numberOfRecords=(int) command.ExecuteScalar();
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-04-07
          • 2014-10-15
          • 2011-12-11
          • 1970-01-01
          • 2012-05-18
          • 1970-01-01
          • 2018-07-01
          • 1970-01-01
          相关资源
          最近更新 更多