【问题标题】:How to determine if ExecuteReader returned a result set or not如何确定 ExecuteReader 是否返回结果集
【发布时间】:2020-11-17 22:50:59
【问题描述】:

我正在研究从已执行的存储过程中检索架构的概念。目标是遍历多个存储过程以生成数据字典。

我有一个正在检索数据的 CLR 程序集。出于性能原因,存储过程具有自动生成的参数以不产生任何行,因此期望得到一个空结果集,我可以从中检索架构。我遇到的问题是存储过程可能被传递到没有结果集的函数中。我需要一种方法来处理和识别这些存储过程。

函数如下:

    public static void Return_ColumnData(SqlString query)
    {
        DataTable schema = null;
        SqlConnection connection = new SqlConnection("context connection=true");
        string sQuery = query.ToString();

        using (SqlCommand command = new SqlCommand(sQuery, connection))
        {
            try
            {
                connection.Open();
                SqlDataReader reader = command.ExecuteReader();
                schema = reader.GetSchemaTable();
                reader.Close();

                string insertQuery = "INSERT INTO #tmpColData (ColumnName, Length, Precision, Scale, DataType) SELECT @ColumnName, @Length, @Precision, @Scale, @DataType";

                foreach (DataRow myField in schema.Rows)
                {
                    using (SqlCommand insertCommand = new SqlCommand(insertQuery, connection))
                    {
                        insertCommand.Parameters.Add("@ColumnName", SqlDbType.NVarChar, 100).Value = myField[0].ToString();
                        insertCommand.Parameters.Add("@Length", SqlDbType.Int).Value = Convert.ToInt32(myField[2]);
                        insertCommand.Parameters.Add("@Precision", SqlDbType.Int).Value = Convert.ToInt32(myField[3]);
                        insertCommand.Parameters.Add("@Scale", SqlDbType.Int).Value = Convert.ToInt32(myField[4]);
                        insertCommand.Parameters.Add("@DataType", SqlDbType.NVarChar, 100).Value = myField[24].ToString();

                        insertCommand.ExecuteNonQuery();
                    }
                }

                connection.Close();
            }
            catch (SqlException exception)
            {
                SqlContext.Pipe.Send(exception.Errors[0].Message);
            }
        }

    }

如果我不处理它,它会从调用程序集(Return_ColumnData)的存储过程中抛出这个错误:

Msg 50000, Level 16, State 1, Procedure dbo.Procedure2DataDict, Line 236 [Batch Start Line 0]
6522  A .NET Framework error occurred during execution of user-defined routine or aggregate "Return_ColumnData":
System.NullReferenceException: Object reference not set to an instance of an object.
System.NullReferenceException:
   at Procedure2DataDict.Return_ColumnData(SqlString query)

我尝试添加一个 reader.HasRows 以确定是否有结果集,但如果没有结果集并且有 0 行不适合我,它将返回 false。

                if (reader.HasRows)
                {
                    schema = reader.GetSchemaTable();
                } else
                {
                    SqlContext.Pipe.Send("Failed to get schema. No rows output.");
                    reader.Close();
                    connection.Close();
                    return;
                }

我必须假设不存在使用 ExecuteReader() 处理结果集的东西。我知道 ExecuteReader() 和 ExecuteNonQuery() 之间存在差异,但由于该函数将针对多个过程的迭代运行,所以我事先不知道 proc 是否会返回结果集。

感谢任何帮助。

【问题讨论】:

    标签: c# sql-server clr


    【解决方案1】:

    您应该使用 FieldCount。

    来自Remarks: 执行本质上不返回行的查询(例如 DELETE 查询),将 FieldCount 设置为 0。

    【讨论】:

      【解决方案2】:

      所以我相信答案正以我收到的错误的形式盯着我。

      错误消息是 NullReferenceException,因此我决定不检查 HasRows 以确保 GetSchemaData() 的结果!= null。

                      if (reader.GetSchemaTable() != null)
                      {
                          schema = reader.GetSchemaTable();
                      } else
                      {
                          SqlContext.Pipe.Send("Failed to get schema. No rows output.");
                          reader.Close();
                          connection.Close();
                          return;
                      }
      

      我已经对我的案例进行了测试,它按预期工作。

      我知道可能有多种方法可以处理这个问题,人们仍然可以贡献他们的方法。

      谢谢!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-07-20
        • 2011-06-23
        • 2011-07-12
        • 1970-01-01
        • 1970-01-01
        • 2013-06-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多