我有一个相当复杂的SQL查询,它根据客户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中对数据库运行此查询时,它运行正常。但是,当我在Web部件中的using语句中将其包装在C#for SharePoint中时,它不会返回它应该的第一行,而是返回一个空值。例如,如果在SSMS中我得到三个结果(例如,'1001,''2008,'和3045'),那么我的datareader将只返回两个结果,第一个为空值(即'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部件完成,除了使用的文字与参数之外。此外,如果我将参数更改为文字,我有相同的结果。与SSMS相比,C#处理SQL查询的方式是否存在差异,或者我是否以某种方式错误地实现了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;
}
我完全被难过了,我真的很感激我能得到的任何帮助。
答案 0 :(得分:2)
<强>更新强>
原来问题是循环前额外的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;
<强>旧强>
这可能是愚蠢的customers.SelectedValue.ToString().Trim()
吗?
您可以运行探查器并完全查看服务器正在执行的SQL ...然后在SSMS中运行它以查看您是否仍然得到不同的结果。
答案 1 :(得分:2)
您的代码示例显示您在开始时两次调用DataReader上的Read,这将导致读者跳过第一行。你应该只需要while循环中的read调用。
dr.read(); // unnecessary read call
while (dr.Read())
{ }
答案 2 :(得分:0)
您正在读取循环中执行数据绑定。真的,你应该在填充后绑定到一个枚举。
另外,请查看command.AddWithValue()
方法。