Лого на 91. НЕГ „Проф. Константин Гълъбов“

Модул 4 · Урок 18

Програмиране на информационна система

Практикум: дата без час, INSERT с автоматичен ключ, търсене по няколко полета и прихващане на аварийните спирания с изключения.

Какво правим тук

Този урок е практикум — четири учебни часа, в които довършваш функционалността от предишните два. Всяка задача носи по един нов проблем, който неминуемо изниква при работа с истинска база.

Ключово

Тук се учиш на неща, които не се виждат в готовия код: датата идва с час, дългите заявки се строят трудно и грешат, а програмата спира аварийно точно когато потребителят направи нещо неочаквано.

Задача 1 — датата носи и час

Добави във формата останалите атрибути на таблицата Student. При датата обаче има уловка: C# няма променлива, която да съхранява само дата. Дори атрибутът в SQL Server да е от тип date, при преминаване в C# стойността му се пази в променлива от тип DateTime — и към нея автоматично се добавя време 00:00:00, което после се показва в текстовата кутия.

DateTime DaT = (DateTime)reader[5];
studBornDateBox.Text = DaT.ToShortDateString();

Бележка

ToShortDateString() се съобразява с регионалните настройки на машината — на един компютър ще изведе 5.12.2002, на друг 12/5/2002. Когато форматът трябва да е един и същ навсякъде, задай го изрично: DaT.ToString("dd.MM.yyyy").

Задача 2 — добавяне на нов ученик

Формата може да служи и за въвеждане на нови редове. Добавяш бутон „Нов“, а методът зад него е почти същият като при „Запази“ — само построяването на UPDATE се заменя с построяване на INSERT INTO:

string queryString = "INSERT INTO Student (name,surname," + "family,egn," +
    "birth_date,birth_place,district,e_mail) VALUES ('"
    + studNameBox.Text + "','" + studSurnameBox.Text + "','"
    + studFamilyBox.Text + "','" + studEGNBox.Text + "','"
    + studBornDateBox.Text + "','" + studBornPlaceBox.Text + "','"
    + studDistrictBox.Text + "','" + studMailBox.Text + "');";
// MessageBox.Show(queryString);
  • Дългите заявки се строят трудно и в тях лесно се допускат грешки — сървърът отказва да изпълни синтактично неправилен оператор. Затова по време на разработката покажи построената заявка с MessageBox.Show(queryString), а като се увериш, че е наред, върни реда в коментар.
  • Заявката ще мине без idStudent само ако той е ключ с автоматично задавани стойности. Ако не е, трябва да включиш и него в списъка от атрибути, а стойността да вземеш от кутията — лош вариант, защото тогава потребителят трябва да решава какъв идентификатор е свободен.

Задача 3 — търсене по няколко полета

Разшири търсенето: не само по идентификатор, а и по другите атрибути. Идеята е да проверяваш кои текстови кутии са непразни и за всяка непразна да добавяш елемент в клаузата WHERE:

if (studNameBox.Text != "")
    queryString += " name = '" + studNameBox.Text + "'";

Внимание

Внимавай, ако непразните кутии станат две. Долепени една след друга, условията дават WHERE name = 'Огнян' family = 'Трайчев' — синтактична грешка. Между условията трябва да влезе AND, а най-чисто е да ги събереш в списък и да ги съединиш накрая.

Задачи 4 и 5 — когато програмата спре аварийно

При работа с формата възникват най-различни непредвидени ситуации. Опитай нарочно:

  • да търсиш, без да си задал стойност за аргумент;
  • да търсиш с идентификатор, който не съществува в таблицата;
  • да записваш, преди изобщо да си прочел данни.

Наблюдавай реакцията на програмата. В случаите, когато спира аварийно, си припомни механизма за изключения и го използвай, за да прихванеш спирането и да изведеш подходящо съобщение вместо него.

try
{   reader.Read();
    studNameBox.Text = reader[1].ToString();
}
catch (InvalidOperationException)
{   MessageBox.Show("Няма ученик с този идентификатор.");
}

Задача 5

Регистрирай ситуациите, в които си предизвикал аварийно спиране, и начина, по който си се справил. Обсъдете ги със съучениците си — един вече може да е решил проблема, който на теб ти предстои.

Задача 6 — и другите таблици

По модела на формата за Student направи вторични форми за разглеждане, редактиране и допълване и на другите таблици. Започни със School_data — тя има само един ред, така че функционалността се изработва лесно (добавянето на нов ред там е безсмислено).

Какво трябва да запомниш

  • Датата от базата идва като DateTime с час 00:00:00 — форматирай я, преди да я покажеш.
  • INSERT може да пропусне първичния ключ само ако той се задава автоматично от сървъра.
  • Показвай построената заявка, докато я разработваш — така грешката се вижда веднага.
  • Условията в WHERE се съединяват с AND, не се долепват едно до друго.
  • Всяко действие на потребителя, което може да няма резултат, се обгражда с try … catch.