2010-01-19 3 views
2

У меня довольно сложный SQL-запрос, который вытаскивает различные типы продуктов из базы данных на основе идентификатора клиента. Он вытягивает три разных типа продуктов, идентифицируемых по их уникальным диапазонам номеров идентификаторов (т. Е. Идентификаторы 1000-1999 - это один тип продукта, 2000-2999 - другой, а 3000-3999 - еще один).Datareader пропускает первый результат

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, он прекрасно работает. Однако, когда я переношу это в оператор using в веб-части, которую я пишу в C# для 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 Profiler показывает тот же запрос передается независимо от того, если это делается через SSMS или из веб-части, кроме буквального используется по отношению к параметру. Кроме того, если я изменю параметр на литерал, я получаю тот же результат. Есть ли несоответствие в том, что C# обрабатывает SQL-запросы, а не SSMS, или я каким-то образом реализовал его неправильно?

Вот код для вытягивать данные из считывателя в DropDownList, для полноты картины:

    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

Вы проверили, как выглядит ваш запрос в SQL Profiler? – Oded

+0

Запустить запрос, используя литерал '11' один раз, без параметров команды, что это возвращает? –

+0

Вы тестируете с идентификатором CustomerID 11 в своем коде? – 37Stars

ответ

2

обновление

Оказалось, проблема была дополнительная dr.Read() вызов перед циклом. См. Комментарии.

обновление

Глядя на код, кажется, DataBind находится в неправильном месте - может быть что-то вроде этого? Кроме того, я изменил его, чтобы показать нулевые элементы ... возможно, это вызовет логическую проблему.

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, чтобы увидеть, все ли у вас разные результаты.

+0

Я не вижу ничего подобного, хотя, полагаю, это не значит, что его там нет. В процессе отладки я подключился к процессу SharePoint и прошел проверку при проверке моих значений и, похоже, просто передал параметр ID. –

+0

Кроме того, я должен упомянуть, что я также попытался скопировать SQL, что веб-часть была отправлена ​​из профилировщика и вклеена в SSMS. У меня был тот же результат. –

+0

Просто так я понимаю, когда вы берете код, который вы видите в Профилире, и запускаете его в Enterprise Manager, вы получаете ожидаемые результаты? – Hogan

0

Вы выполняете привязку данных внутри цикла чтения. Действительно, вы должны привязываться к перечислимому после его заполнения.

Также обратите внимание на метод command.AddWithValue().

+0

Ошибка AddWithValue(). Он хочет, чтобы числа представлялись в виде строк, AWV должен был преобразовать в число. (Конечно, CustomerID должен быть представлен как int в БД, но это еще одна история ...) – Hogan

+0

Моя ошибка там. Хоган указал на это в первый раз, и я это исправил. Я просто скопировал этот кусок в неправильное место, когда обновляю свой код. Я посмотрел на AddWithValue, но да, я не вижу, чтобы он работал, поскольку все, что я имею в виду, это строки. –

2

Ваш пример кода показывает, что вы дважды читаете в DataReader в начале, что заставит читателя пропустить первую строку. В цикле while вам потребуется только чтение.

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

Примечание: код выглядел по-другому, прежде чем он нашел проблему и поместил read() в пример кода. – Hogan

Смежные вопросы