ADO.NET. Управление базами данных. Связь по схеме OLE DB провайдера. Коррекция стилей DataGridView, страница 7

·  Запустите приложение в режиме отладки (F5). В этом режиме мы видим окно Output режима отладки.

·  Взгляните в окно Output и убедитесь, что построитель сгенерировал достаточно сложную команду.

Особенно высоко оценят услуги класса те, кто не имеет навыка в составлении синтаксически правильных (well formed) команд SQL (SQL-операторов, или предложений).

UPDATE Studs SET Name = ? , Phone = ? , Addr = ?

WHERE ((StudID = ?)     

AND ((? = 1 AND Name IS NULL) OR (Name = ?))

AND ((? = 1 AND Phone IS NULL) OR (Phone = ?))

AND ((? = 1 AND Addr IS NULL) OR (Addr = ?)))

Команда UPDATE — это SQL-оператор, включающий 3 части: UPDATE, SET и WHERE. Она отдельно применяется к каждой строке таблицы базы данных. Как видите, большую ее часть занимает довольно длинное логическое выражение части WHERE. В первом приближении смысл команды таков: установить в строке таблицы базы данных изменения, в соответствии с позиционными параметрами, которые в технологии OLE DB принято обозначать знаками вопроса. Значения параметров (подставляемых вместо знаков вопроса) берутся из строк таблицы, расположенной в DataSet (вспомните, что это копия реальной таблицы БД).

Меня, как и вас, не устраивает первое приближение. Хочется понять смысл всех деталей приведенного оператора. Больше всего (и довольно долго) меня смущали единицы и манипуляции с ними. Поэтому сразу раскрою секрет.

·  Выражение  ? = 1 надо читать так: если текущее поле можно обнулять (вы бы догадались до этого?).

·  Выражение  ? = 1 AND Name IS NULL надо читать так: если поле Name можно обнулять и оно на задано.

·  Выражение  ? = 1 AND Name IS NULL OR (Name = ?) надо читать так: если поле Name можно обнулять и оно на задано, или оно равно старому значению поля Name.

Каждый вопрос — это следующий по счету параметр. Смысл каждого вопроса определяется списком параметров команды. Этот список для каждой команды разный.

Сначала выясним, сколько параметров требует команда UPDATE. Каждая строка таблицы имеет 4 колонки, следующих в строго заданном порядке: StudID, Name, Phone, и Addr. Вспомним, что первая колонка является счетчиком, то есть автоматически инкрементируемым полем, новое значение которого не следует задавать извне, так как оно генерируется СУБД. Кажется, что для внесения изменений в каждую строку таблицы, достаточно подать 3 параметра — новые значения колонок: Name, Phone, и Addr.

Подсчитав количество вопросов, видим, что на самом деле оператор UPDATE требует задать 10 параметров. Объяснение кроется в том, что для внесения изменений требуется знать не только новые значения полей каждой строки таблицы, но и старые (обычно их обозначают префиксом Original). Чтобы быть последовательным, приведем последовательность и смысл всех 10 параметров команды UPDATE:

 1.Name, 2.Phone, 3.Addr, 4.Original_StudID, 5.IsNull_Name, 6.Original_Name, 7.IsNull_Phone, 8.Original_Phone, 9.IsNull_Addr, 10.Original_Addr.

Повторю, что разные команды требуют разное количество параметров. Чтобы увидеть другие команды, генерируемые построителем, вставьте вывод других команд.

Console.WriteLine (builder.GetInsertCommand().CommandText);

Console.WriteLine (builder.GetDeleteCommand().CommandText);

В окне Output вы увидите два новых произведения класса OleDbCommandBuilder: команды INSERT и DELETE. В команде INSERT всего 3 вопроса (то есть, параметра).

INSERT INTO Studs (Name, Phone, Addr) VALUES (? , ? , ?)

Она имеет наиболее простой вид, так как в ней не анализируются старые значения (их просто нет). INSERT требует задать лишь 3 параметра для генерации 3-х новых полей (Name, Phone, Addr) вставляемой строки таблицы. Поле автоматически генерируемого идентификатора StudID (identity column) задавать не нужно.

Команда DELETE требует уже 7 параметров.

DELETE FROM  Studs

WHERE ((StudID = ?)

AND ((? = 1 AND Name IS NULL) OR (Name = ?))

AND ((? = 1 AND Phone IS NULL) OR (Phone = ?))

AND ((? = 1 AND Addr IS NULL) OR (Addr = ?)))

·  Первым должен идти параметр Original_StudID — старое (существующее в базе) значение первичного ключа строки, которую следует удалить.