Форум программистов, компьютерный форум, киберфорум
Наши страницы
C#: Базы данных, ADO.NET
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.89/19: Рейтинг темы: голосов - 19, средняя оценка - 4.89
paltan
0 / 0 / 0
Регистрация: 24.11.2011
Сообщений: 5
1

Как работает SQLDataReader?

28.11.2011, 12:22. Просмотров 3920. Ответов 6
Метки нет (Все метки)

Всем привет.
Вопрос конечно банальный, но мне не удалось найти на него исчерпывающий ответ.
Кто знает каким образом проходит SQLDataReader по полученному результату запроса из БД?
Проблема в том, что в очередной раз сталкиваюсь с проблемой поиска ошибки при попытке считывания данных.
Вот код:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
DataTable people = new DataTable ();
 
        try
        {
            string query = string.Format(@"SELECT dbo.Book.ID, 
                                                dbo.PeopleGroup.PersonType_Name, 
                                                dbo.Book.Surname, 
                                                dbo.Book.FirstName, 
                                                dbo.Book.SecondName, 
                                                dbo.Book.Phone_work, 
                                                dbo.Book.Phone_mob, 
                                                dbo.Book.Phone_home, 
                                                dbo.Book.Email, 
                                                dbo.Book.Birthday, 
                                                dbo.Book.Address, 
                                                dbo.Book.User_ID, 
                                                dbo.Book.PersonType_ID 
                                                FROM dbo.Book 
                                                INNER JOIN dbo.PeopleGroup ON dbo.Book.PersonType_ID = dbo.PeopleGroup.PersonType_ID
                                                ORDER BY dbo.Book.Surname");
            SqlCommand com = new SqlCommand(query, SQLCon);
            SQLCon.Open();
 
            SqlDataReader reader = com.ExecuteReader();
            if (reader.HasRows)
            {
                while (reader.Read())
                {                    people.Rows.Add(reader.GetInt32(0),
                                            reader["PersonType_Name"].ToString(),
                                            reader["Surname"].ToString(),
                                            reader["FirstName"].ToString(),
                                            reader["SecondName"].ToString(),
                                            reader["Phone_work"].ToString(),
                                            reader["Phone_mob"].ToString(),
                                            reader["Phone_home"].ToString(),
                                            reader["Email"].ToString(),
                                            reader["Birthday"].ToString(),
                                            reader["Address"].ToString(),
                                            reader.GetInt32(11),
                                            reader.GetByte(12));
                }
            }
        }
        catch (Exception ex)
        {
 
        }
        finally
        {
            if (SQLCon.State == ConnectionState.Open)
                SQLCon.Close();
        }
На картинке видно, что ридер успел прочитать некоторую информацию. Но на чем он споткнулся, я не могу понять - порядок считывания данных мне не понятен.
1. Имеет ли значение, в каком порядке я считываю данные из полученных данных?
0
Миниатюры
Как работает SQLDataReader?  
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.11.2011, 12:22
Ответы с готовыми решениями:

Как передать данные из SqlDataReader в BindingSource?
При загрузке формы, с помощью SqlDataReader-а заполняется ComboBox. private void Form1_Load(object...

Закрытие SqlDataReader
Критично ли обрамлять работу с SqlDataReader в try/catch с тем чтобы закрывать SqlDataReader в...

SqlDataReader и бинарные данные
Уважаемое Эксперты помогите пожалуйста ! Я записываю двоичное данное на базе SQL 2000 обратно...

SqlDataReader и запрос Compute
Собственно как при помощи SqlDataReader извлечь данные полученные посредством выполнения запроса...

SqlDataReader не видит SqlCommand
Приветствую. Столкнулся с не понятной проблемой, код (похожий) без проблем работает в 2х...

6
Enifan
0 / 0 / 0
Регистрация: 14.10.2018
Сообщений: 16
20.01.2019, 16:59 2
Допустим есть таблица
ID Имя Номер
1 Петр 555
2 Иван 444
3 Юлия 333

далее пишется стандартный код большинства запросов

C#
1
2
3
string query = string.Format(@"SELECT ...... FROM ...... WHERE ......."); /* стандартный запрос */
SqlCommand com = new SqlCommand(query, SQLCon);
SqlDataReader reader = com.ExecuteReader();
предположим по нашему запросу были найдены данные - смотри таблицу ниже (эта самая таблица теперь хранится в объекте reader)

ID Имя Номер
2 Иван 444
3 Юлия 333

далее пробегаемся по этой самой таблице (с помощью цикла while), которая хранится в объекте reader

C#
1
2
3
4
5
while (reader.Read())
{
// Здесь и происходит получение данных из таблицы, которая хранится в !!! reader !!!
// Чтение данных происходит ПОСТРОЧНО
}
В данном случаи было найдено 2 строки, значит цикл будет крутиться всего 2 раза

1-ый проход цикла
сейчас мы находимся в 1-ой строке, выделенной жирным цветом
ID Имя Номер
2 Иван 444
3 Юлия 333

C#
1
2
3
4
5
// данный код вставляем в цикл while
// цифры выделенные красным - номер столбца
int id = reader.GetInt32(0); // id = 2
string name = reader.GetString(1); // name = Иван
int number = reader.GetInt32(2); // number = 444
2-ой проход цикла
сейчас мы находимся в 2-ой строке, выделенной жирным цветом
ID Имя Номер
2 Иван 444
3 Юлия 333

C#
1
2
3
4
5
// данный код вставляем в цикл while
// цифры выделенные красным - номер столбца
int id = reader.GetInt32(0); // id = 3
string name = reader.GetString(1); // name = Юлия
int number = reader.GetInt32(2); // number = 333
Как итог:
1) данный класс плачевным для многих (как по мне он коряво сделан), так что ваш вопрос точно не банальный
2) данные считываются построчно, и пока очередь в цикле не дойдет до нужной строки - к этой строке доступ никак не получить
3) надо учитывать что за данные считываются
4) надо учитывать может ли быть значение NULL ибо получение данных немного усложняется
5) да и вообще в этом классе допустить ошибку как нечего делать
0
OttoFix
20 / 16 / 5
Регистрация: 11.12.2018
Сообщений: 80
21.01.2019, 07:24 3
Цитата Сообщение от paltan Посмотреть сообщение
На картинке видно, что ридер успел прочитать некоторую информацию.
На картинке так же видно, что номера телефонов имеют тип System.DBNull, а у нас в коде
C#
1
reader["Phone_work"].ToString()
получается мы пытаемся конвертировать NULL в String. Может я конечно же ошибаюсь, но ошибка думаю именно в этом.
0
Usaga
Эксперт .NET
5539 / 3742 / 662
Регистрация: 21.01.2016
Сообщений: 14,919
Завершенные тесты: 2
21.01.2019, 08:08 4
OttoFix, System.DBNull ни разу не null. Сотворять над этим типом ToString() можно.
0
nedel
636 / 617 / 366
Регистрация: 09.04.2014
Сообщений: 1,471
Завершенные тесты: 1
21.01.2019, 12:55 5
если у вас не инициализированна структура people, то проще использовать SqlDataAdapter
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
DataTable people = new DataTable ();
 
        try
        {
            string query = string.Format(@"SELECT dbo.Book.ID, 
                                                dbo.PeopleGroup.PersonType_Name, 
                                                dbo.Book.Surname, 
                                                dbo.Book.FirstName, 
                                                dbo.Book.SecondName, 
                                                dbo.Book.Phone_work, 
                                                dbo.Book.Phone_mob, 
                                                dbo.Book.Phone_home, 
                                                dbo.Book.Email, 
                                                dbo.Book.Birthday, 
                                                dbo.Book.Address, 
                                                dbo.Book.User_ID, 
                                                dbo.Book.PersonType_ID 
                                                FROM dbo.Book 
                                                INNER JOIN dbo.PeopleGroup ON dbo.Book.PersonType_ID = dbo.PeopleGroup.PersonType_ID
                                                ORDER BY dbo.Book.Surname");
            SqlCommand com = new SqlCommand(query, SQLCon);
            using(SqlDataAdapter adapter=new SqlDataAdapter (com))
                  adapter.Fill(people);
 
        }
        catch (Exception ex)
        {
 
        }
        finally
        {
            if (SQLCon.State == ConnectionState.Open)
                SQLCon.Close();
        }
0
Enifan
0 / 0 / 0
Регистрация: 14.10.2018
Сообщений: 16
22.01.2019, 18:12 6
мне бы глянуть как устроена таблица, но если вы думает что проблема в том что
Цитата Сообщение от OttoFix Посмотреть сообщение
получается мы пытаемся конвертировать NULL в String.
то возникает проблема о которой я упоминал выше
Цитата Сообщение от Enifan Посмотреть сообщение
4) надо учитывать может ли быть значение NULL ибо получение данных немного усложняется
в общем, если в данной ячейке откуда вам нужно вытащить данные может иметь значение NULL то попробуйте этот код (для примера SQL (предлагаемая Visual Studio) с типами int, string, byte)

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Ячейки не могут иметь значение NULL
while(reader.Read())
{
    int number = reader.GetInt32(0);
    string name = reader.GetString(1);
    bool correct = (bool)reader.GetBoolean(2);
}
 
// Ячейки могут содержать значение NULL, синтаксис довольно-таки корявый
while(reader.Read())
{
    int? number = reader.IsDBNull(0) ? null : (int?)reader.GetInt32(0);
    string? name = reader.IsDBNull(1) ? null : reader.GetString(1);
    bool? correct = reader.IsDBNull(2) ? null : (bool?)reader.GetBoolean(2);
}
Следует отметить что в каждой БД могут быть свои нюансы при использования SqlDataReader.
PS. Я с этим ридером сколько времени работаю, до сих пор натыкаюсь на какие-нибудь ошибки
0
OttoFix
20 / 16 / 5
Регистрация: 11.12.2018
Сообщений: 80
23.01.2019, 06:16 7
Цитата Сообщение от Usaga Посмотреть сообщение
System.DBNull ни разу не null. Сотворять над этим типом ToString() можно.
Спасибо, что поправили! Это я уже заработался, естественно DBNull.ToString() вернет String.Empty.

Да тут долго можно гадать, даже вопрос до конца не понятен, я его прочел следующим образом "При обработке результата SQL запроса, происходит ошибка в момент считывания данных с помощью SQLReader".
ТС даже текст ошибки не приложил, тут скорее всего где-то не совпадение типов данных, но гадать надоело.
0
23.01.2019, 06:16
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.01.2019, 06:16

SqlDataReader обращение без индексов
Обычно делаю вот так: using (SqlDataReader dr = myCommand.ExecuteReader()) { ...

Извлечь данные из SqlDatareader в строку
Нужно извлчь данные из дата ридера строкой представляющей собой одну запись таблицы в БД. Строка...

SqlDataReader. Тупит SELECT DISTINCT
Есть SELECT запрос... Выполняю команду dataReader=command.ExecuteReader(); Потом читаю ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru