数据读取器跳过第一个结果

发布于 2024-08-18 14:18:34 字数 3779 浏览 5 评论 0原文

我有一个相当复杂的 SQL 查询,它根据客户 ID 从数据库中提取不同类型的产品。它提取三种不同类型的产品,通过其唯一标识符编号范围进行标识(即,ID 1000-1999 是一种产品类型,2000-2999 是另一种产品类型,3000-3999 是另一种产品类型)。

SELECT b.fldMachineName, m2.fldRotaryPressName, mids.fldMachine_ID
FROM dbo.tblCustomerGeneralInfo c
LEFT JOIN dbo.tblMachine_IDs mids ON c.fldCustomer_ID = mids.fldCustomer_ID
LEFT JOIN dbo.tblBobstFlatDieSpecs b ON mids.fldMachine_ID = b.fldMachine_ID
LEFT JOIN dbo.tblDieInfo m1 ON mids.fldMachine_ID = m1.fldMachine_ID
LEFT JOIN dbo.tblRotaryDieSpecs sm ON m1.fldMachine_ID = sm.fldMachine_ID
LEFT JOIN dbo.tblRotaryPresses m2 ON sm.fldRotaryPress_ID = m2.fldRotaryPress_ID
WHERE c.fldCustomer_ID = '20'
ORDER BY fldRotaryPressName

c.fldCustomer_ID 是我需要的唯一用户输入,当我在 SQL Server Management Studio Express 中对数据库运行此查询时,它运行良好。但是,当我将其包装在我用 C# for SharePoint 编写的 Web 部件中的 using 语句中时,它不会返回应有的第一行,而是返回空值。例如,如果在 SSMS 中我得到三个结果(例如“1001”、“2008”和 3045),那么我的数据读取器将仅返回两个结果,第一个结果为空值(即“null”、“2008”) 、”和“3045”)。以下是我的 C# 代码:

            con.Open();
            using (SqlCommand cmd = new SqlCommand("SELECT b.fldMachineName, m2.fldRotaryPressName, mids.fldMachine_ID " +
                                                   "FROM dbo.tblCustomerGeneralInfo c " +
                                                   "LEFT JOIN dbo.tblMachine_IDs mids ON c.fldCustomer_ID = mids.fldCustomer_ID " +
                                                   "LEFT JOIN dbo.tblBobstFlatDieSpecs b ON mids.fldMachine_ID = b.fldMachine_ID " +
                                                   "LEFT JOIN dbo.tblDieInfo m1 ON mids.fldMachine_ID = m1.fldMachine_ID " +
                                                   "LEFT JOIN dbo.tblRotaryDieSpecs sm ON m1.fldMachine_ID = sm.fldMachine_ID " +
                                                   "LEFT JOIN dbo.tblRotaryPresses m2 ON sm.fldRotaryPress_ID = m2.fldRotaryPress_ID " +
                                                   "WHERE c.fldCustomer_ID = @CustomerID " +
                                                   "ORDER BY fldRotaryPressName", con))
            {
                cmd.Parameters.Add("@CustomerID", SqlDbType.VarChar, 4).Value = customers.SelectedValue.ToString();

我们的 SQL 分析器显示传递的相同查询,无论它是通过 SSMS 还是从 Web 部件完成,除了所使用的文字与参数之外。另外,如果我将参数更改为文字,则会得到相同的结果。 C# 与 SSMS 处理 SQL 查询的方式是否存在差异,或者我是否以某种方式错误地实现了它?

为了完整起见,以下是将数据从阅读器拉入下拉列表的代码:

                    dr.read();
                    while (dr.Read())
                    {
                        try
                        {
                            string itemValue = Convert.ToString(dr["fldMachine_ID"]);
                            string flatName = Convert.ToString(dr["fldMachineName"]);
                            if (!string.IsNullOrEmpty(flatName))
                            {
                                items.Add(flatName, itemValue);
                            }
                            string rotaryName = Convert.ToString(dr["fldRotaryPressName"]);
                            if (!string.IsNullOrEmpty(rotaryName))
                            {
                                items.Add(rotaryName, itemValue);
                            }
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.ToString());
                        }
                    }

                        // Bind list to ddl.
                        machines.DataSource = items;
                        machines.DataValueField = "Value";
                        machines.DataTextField = "Key";
                        machines.DataBind();

                        machines.Enabled = true;
                    }

我完全被难住了,我真的很感谢我能得到的任何帮助。

I have a fairly complex SQL query that pulls different types of products from a database based on a customer ID. It pulls three different types of products, identified by their unique identifier number ranges (i.e., IDs 1000-1999 are one type of product, 2000-2999 are another, and 3000-3999 are yet another).

SELECT b.fldMachineName, m2.fldRotaryPressName, mids.fldMachine_ID
FROM dbo.tblCustomerGeneralInfo c
LEFT JOIN dbo.tblMachine_IDs mids ON c.fldCustomer_ID = mids.fldCustomer_ID
LEFT JOIN dbo.tblBobstFlatDieSpecs b ON mids.fldMachine_ID = b.fldMachine_ID
LEFT JOIN dbo.tblDieInfo m1 ON mids.fldMachine_ID = m1.fldMachine_ID
LEFT JOIN dbo.tblRotaryDieSpecs sm ON m1.fldMachine_ID = sm.fldMachine_ID
LEFT JOIN dbo.tblRotaryPresses m2 ON sm.fldRotaryPress_ID = m2.fldRotaryPress_ID
WHERE c.fldCustomer_ID = '20'
ORDER BY fldRotaryPressName

c.fldCustomer_ID is the only piece of user input that I need, and when I run this query against the database in SQL Server Management Studio Express, it runs fine. However, when I wrap this in a using statement in the web part I am writing in C# for SharePoint, it does not return the first row that it should, instead returning a null value. For instance, if in SSMS I get three results (say, '1001,' '2008,' and 3045') then my datareader will return only two results, with a null value for the first (i.e., 'null,' '2008,' and '3045'). Here is my code in C#:

            con.Open();
            using (SqlCommand cmd = new SqlCommand("SELECT b.fldMachineName, m2.fldRotaryPressName, mids.fldMachine_ID " +
                                                   "FROM dbo.tblCustomerGeneralInfo c " +
                                                   "LEFT JOIN dbo.tblMachine_IDs mids ON c.fldCustomer_ID = mids.fldCustomer_ID " +
                                                   "LEFT JOIN dbo.tblBobstFlatDieSpecs b ON mids.fldMachine_ID = b.fldMachine_ID " +
                                                   "LEFT JOIN dbo.tblDieInfo m1 ON mids.fldMachine_ID = m1.fldMachine_ID " +
                                                   "LEFT JOIN dbo.tblRotaryDieSpecs sm ON m1.fldMachine_ID = sm.fldMachine_ID " +
                                                   "LEFT JOIN dbo.tblRotaryPresses m2 ON sm.fldRotaryPress_ID = m2.fldRotaryPress_ID " +
                                                   "WHERE c.fldCustomer_ID = @CustomerID " +
                                                   "ORDER BY fldRotaryPressName", con))
            {
                cmd.Parameters.Add("@CustomerID", SqlDbType.VarChar, 4).Value = customers.SelectedValue.ToString();

Our SQL profiler shows the same query being passed regardless of if it's done through SSMS or from the web part, except for the literal being used versus the parameter. Also, if I change the parameter to a literal, I have the same result. Is there a discrepancy in the way that C# handles SQL queries as opposed to SSMS, or have I somehow implemented it incorrectly?

Here is the code for pulling the data from the reader into the dropdownlist, for the sake of completeness:

                    dr.read();
                    while (dr.Read())
                    {
                        try
                        {
                            string itemValue = Convert.ToString(dr["fldMachine_ID"]);
                            string flatName = Convert.ToString(dr["fldMachineName"]);
                            if (!string.IsNullOrEmpty(flatName))
                            {
                                items.Add(flatName, itemValue);
                            }
                            string rotaryName = Convert.ToString(dr["fldRotaryPressName"]);
                            if (!string.IsNullOrEmpty(rotaryName))
                            {
                                items.Add(rotaryName, itemValue);
                            }
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.ToString());
                        }
                    }

                        // Bind list to ddl.
                        machines.DataSource = items;
                        machines.DataValueField = "Value";
                        machines.DataTextField = "Key";
                        machines.DataBind();

                        machines.Enabled = true;
                    }

I am completely stumped, and I really appreciate any help I can get.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

装纯掩盖桑 2024-08-25 14:18:34

更新

原来问题是循环之前的额外 dr.Read() 调用。见评论。

更新

查看代码,似乎数据绑定位于错误的位置 - 也许是这样的?另外,我将其更改为显示空项目...也许这会暴露逻辑问题。

while (dr.Read())
{
    try
    {
      string itemValue = dr["fldMachine_ID"].ToString();
      string flatName =  dr["fldMachineName"].ToString();
      if (string.IsNullOrEmpty(flatName)) flatName = "!NULL!";
      if (string.IsNullOrEmpty(itemValue)) itemValue = "!NULL!";
      items.Add(flatName, itemValue);

      string rotaryName = dr["fldRotaryPressName"].ToString();
      if (string.IsNullOrEmpty(rotaryName)) rotaryName= "!NULL!";
      items.Add(rotaryName, itemValue);
    }
    catch (Exception ex)
    {
      MessageBox.Show(ex.ToString());
    }

}
// Bind list to ddl.
machines.DataSource = items;
machines.DataValueField = "Value";
machines.DataTextField = "Key";
machines.DataBind();

machines.Enabled = true;

old

会不会是像 customers.SelectedValue.ToString().Trim() 这样愚蠢的东西?

您可以运行探查器并准确查看服务器正在执行的 SQL...然后在 SSMS 中运行它以查看是否仍然得到不同的结果。

update

Turned out the problem was a extra dr.Read() call before the loop. See comments.

update

Looking at the code, it seems the databind is in the wrong place -- maybe something like this? Also, I changed it to show the null items... maybe this will expose a logic problem.

while (dr.Read())
{
    try
    {
      string itemValue = dr["fldMachine_ID"].ToString();
      string flatName =  dr["fldMachineName"].ToString();
      if (string.IsNullOrEmpty(flatName)) flatName = "!NULL!";
      if (string.IsNullOrEmpty(itemValue)) itemValue = "!NULL!";
      items.Add(flatName, itemValue);

      string rotaryName = dr["fldRotaryPressName"].ToString();
      if (string.IsNullOrEmpty(rotaryName)) rotaryName= "!NULL!";
      items.Add(rotaryName, itemValue);
    }
    catch (Exception ex)
    {
      MessageBox.Show(ex.ToString());
    }

}
// Bind list to ddl.
machines.DataSource = items;
machines.DataValueField = "Value";
machines.DataTextField = "Key";
machines.DataBind();

machines.Enabled = true;

old

Could it be something silly like customers.SelectedValue.ToString().Trim()?

You can run the profiler and see EXACTLY the SQL that the server is executing... then run that in SSMS to see if you still get different results.

月竹挽风 2024-08-25 14:18:34

您的代码示例显示您在开始时对 DataReader 调用 Read 两次,这将导致读取器跳过第一行。您应该只需要 while 循环中的 read 调用。

  dr.read();  // unnecessary read call
  while (dr.Read())
  { }

your code sample shows you calling Read on the DataReader twice at the start, that would cause the reader to skip the first row. You should only need the read call in the while loop.

  dr.read();  // unnecessary read call
  while (dr.Read())
  { }
凉风有信 2024-08-25 14:18:34

您正在读取循环内进行数据绑定。实际上,您应该在填充后绑定到可枚举。

另外,请查看 command.AddWithValue() 方法。

You are doing the databind inside the read loop. Really you should bind to an enumerable after it has been populated.

Also, look at the command.AddWithValue() method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文