C # SqlCommand - установка результирующего набора в переменную - PullRequest
3 голосов
/ 27 апреля 2011

Я запускаю команду SQL в C #, которая возвращает одно значение (строку). Затем я пытаюсь сохранить его в переменной, но он всегда выдает это исключение:

Первое случайное исключение типа «System.InvalidOperationException» произошло в System.Data.dll Поток '' (0x1bbc) завершился с кодом 0 (0x0). System.InvalidOperationException: недопустимая попытка чтения, когда данные отсутствуют. в System.Data.SqlClient.SqlDataReader.GetValue (Int32 i)

Однако, когда я запускаю ту же команду в SQL Server, она определенно выводит значение.

myCommand = new SqlCommand("SELECT TrialName FROM dbo.CT WHERE NumId='"+TrialId+"'", myConnection);    
SqlDataReader dr = myCommand.ExecuteReader();  
String TName = dr[0].ToString(); 

Даже если я жестко закодирую всю команду sql (вместо использования переменной TrialId), она все равно выдает исключение. Что здесь происходит?

Ответы [ 4 ]

8 голосов
/ 27 апреля 2011

Вы должны вызвать dr.Read () перед чтением из устройства чтения данных:

myCommand = new SqlCommand("SELECT TrialName FROM dbo.CT WHERE NumId='"+TrialId+"'", 

myConnection);                
SqlDataReader dr = myCommand.ExecuteReader();                
if(dr.Read())
{
    String TName = dr[0].ToString(); 
}

SqlDataReader.Read () продвигает устройство чтения к следующей записи и возвращает false, если записей больше нет.

2 голосов
/ 27 апреля 2011

Как указывают другие ответы, вам нужно вызвать метод Read () в SqlDataReader.

Однако, если вы возвращаете только одно значение из оператора select, вам следует рассмотреть возможность использования SqlCommand.ExecuteScalar метод .Для этого не требуется столько кода, сколько для использования SqlDataReader.

Примерно так:

string name = Convert.ToString(myCommand.ExecuteScalar());
1 голос
/ 27 апреля 2011

Вам нужно позвонить dr.Read(), прежде чем вы сможете читать с него. DataReader.Read() переводит DataReader на следующую строку. Вы также должны вызвать его для первой строки, чтобы использовать его в цикле while:

while ( dr.Read() )
{
    ...
}

Надеюсь, это поможет!

0 голосов
/ 27 апреля 2011

Могу ли я предложить использовать параметризованный запрос для защиты от уязвимостей SQL-инъекций?Если вам требуются специальные операторы SQL вместо хранимых процедур, рассмотрите возможность использования чего-то вроде этого:

С помощью команды ExecuteScalar() можно обойтись, если вам требуется только значение первого столбца из первой строки:

string TName;        
using (var conn = new SqlConnection(SomeConnectionString))
using (var cmd = conn.CreateCommand())
{
    conn.Open();
    cmd.CommandText = "SELECT TrialName FROM dbo.CT WHERE NumId=@Trial";
    cmd.Parameters.AddWithValue("@Trial", TrialId);
    TName = cmd.ExecuteScalar().ToString();
}

Если вам требуется более одного значения, продолжайте использовать SqlDataReader:

string TName;        
using (var conn = new SqlConnection(SomeConnectionString))
using (var cmd = conn.CreateCommand())
{
    conn.Open();
    cmd.CommandText = "SELECT TrialName FROM dbo.CT WHERE NumId=@Trial";
    cmd.Parameters.AddWithValue("@Trial", TrialId);
    using (var reader = cmd.ExecuteReader())
    {
        if (reader.Read())
        {
            TName  = reader["TrialName"].ToString();
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...