Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

sql server+c++

.pdf
Скачиваний:
18
Добавлен:
07.06.2015
Размер:
2.12 Mб
Скачать

А. Фільтрування на рівні сервера.

За замовчуванням майстер створює для таблиць об’єкта DataSet команди вибірки усіх даних з бази сервера. Для компоненти TableAdapter вибраної таблиці можемо створити додаткові команди вибірки даних на основі параметризованих запитів. Для цього в режимі дизайну форми (рис. 4.52) у розділі Components Tray натисніть правою кнопкою миші на компоненті TableAdapter потрібної таблиці (п. 75) та у контекстному меню виберіть пункт Add Query (п. 76).

75 76

Рис. 4.52. Створення команди запиту до бази даних

77

78

Рис. 4.53. Редагування параметризованого запиту до бази даних

69

Далі у вікні Search Criteria Builder (рис. 4.53) відредагуйте назву нового запиту у більш зрозумілий контекст (п. 77), згідно його функціональності, та у частині Query Text додайте до запиту конструкцію WHERE. Наприклад, для вибору даних у заданому діапазоні значень стовпця ID, необхідно додати таку стрічку

WHERE ID >= @IDMin AND ID <= @IDMax

@IDMin та @IDMax це параметри, значення яких зчитуються з компонентів форми та підставляються в SQL-запит. Створюваний SQL-запит повинен повертати такий же перелік стовпців, що й базовий запит.

Після створення нового запиту майстер додасть у розділ Components Tray компоненту ToolStrip (п. 79) та її графічну панель для введення даних фільтрування на форму програми (п. 80).

80

79

Рис. 4.54. Форма програми з панеллю фільтрування за параметрами

Аналогічно створимо для стовпця Surname панель фільтрування згідно введеного шаблону. Для цього створимо ще одну команду для вибірки даних (рис. 4.45) та додамо до її SQL-запиту таку стрічку:

WHERE Surname LIKE RTRIM(@Surname) + '%'

81

82

Рис. 4.55. Параметризований запит із шаблонним фільтром

70

Останній запит має вибирати дані, які починаються зі значення параметра, оскільки ми до шаблону добавили символ % (заміна довільного значення). Функція RTRIM() обрізає кінцеві пробіли зі значення параметра.

Необхідний програмний код для функції оброблення події натискання кнопки з назвою фільтра додається майстром автоматично.

На рис. 4.56 проілюстрована робота цих двох панелей фільтрування даних.

а)

б)

Рис. 4.56. Ілюстрація роботи програми-клієнта з панелями фільтрування на основі параметризованих запитів

Необхідно зазначити, що такий підхід до фільтрування даних є ефективним та простим у реалізації для таблиці, що не має залежних від себе таблиць. Однак, якщо існують залежні таблиці, тоді, аби уникнути помилки часу виконання внаслідок обмежень зовнішнього ключа, необхідно очистити ці таблиці об’єкта DataSet від даних, та заново заповнити їх, враховуючи параметри фільтру для головної таблиці. Якщо ж існують для залежних таблиць також і від них залежні, тоді необхідно каскадним чином внести корективи і для них.

71

Б. Локальна фільтрація.

Локальне фільтрування даних виконується засобами компоненти BindingSource (рис. 4.57) для окремої таблиці за допомогою параметра Filter. Значення фільтра формують на основі тих же правил, які визначені для логічних операцій конструкції WHERE мови SQL. Хоча звісно логічні вирази моделі ADO.NET мають деякі свої відмінності (детальніше у розділі 5 Додаткових відомостей). Для відміни фільтрації використовується метод RemoveFilter().

обмеження

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Об’єкт

 

 

 

Елемент

 

 

Об’єкт

 

 

 

керування

 

 

 

DataSet

 

 

DataGridView

 

 

BindingSource

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Рис. 4.57. Схема фільтрування на рівні локальної моделі даних

Додамо на форму програми дві кнопки (Button), мітку (Label), текстову стрічку (TextBox) та підпишемо їх, як на рис. 4.58. Тепер, відповідно, запрограмуємо кнопку «Фільтрувати» та «Відмінити фільтр».

private: System::Void button1_Click

(System::Object^ sender, System::EventArgs^ e) { StudentsBindingSource->Filter="Surname LIKE '"+textBox1->Text+"%'"; }

private: System::Void button2_Click

(System::Object^ sender, System::EventArgs^ e) { StudentsBindingSource->RemoveFilter(); }

Рис. 4.58. Ілюстрація фільтрування даних на рівні об’єкта DataSet

72

4.3.10. Робота з BLOB-даними.

Великий двійковий об’єкт (BLOB – Binary Large Object) можна записувати в базу даних у вигляді двійкових чи символьних даних, у залежності від типу поля джерела даних. BLOB – це загальний термін для типів даних text, ntext, varchar(max), nvarchar(max), image, varbinary(max) із максимальним об’ємом даних до 2 Гбайт. Для збереження великих об’ємів тексту, як звичайного, так і форматованого (RTF), рекомендується використовувати тип nvarchar(max), для збереження об’єктів, наприклад фотографій, використовувати тип да-

них varbinary(max).

Для ілюстрації можливостей роботи з BLOB-полями створимо простеньку базу даних з однієї таблиці (рис. 4.59). Стовпець Photo зарезервуємо для зберігання в базі даних фотографій, а стовпець Text – для текстових блоків, у тому числі й у RTF-форматі.

Рис. 4.59. Структура таблиці з BLOB-полями

Створимо нову Windows Forms програму та налаштуємо за допомогою майстра строго типізований об’єкт DataSet. У вікні Data Sources (рис.4.60) стовпець Photo зв’яжемо з компонентою PictureBox, що призначена для відображення графічних зображень (п. 83).

83

Рис. 4.60. Встановлення стовпця у режим відображення графічних зображень

73

Компонента PictureBox може відображати такі формати зображень: растрові (файли BMP, GIF, JPEG, TIFF та PNG), векторні (файли WMF або EMF), піктограми (файл ICO).

Тепер налаштуємо стовпець Text на відображення тексту. За замовчуванням з ним зв’язана компонента TextBox. Після перетягування її на форму програми вона буде відображати звичайний текст стовпця. Для відображення блоку тексту необхідно встановити для її параметра Multiline значення True. Для відображення форматованого тексту необхідно стовпець зв’язати з компонентою RichTextBox (п. 87). Для цього необхідно додати її до переліку зв’язаних компонент (п. 84), шляхом вибору відповідної галки у вікні Options (п. 85).

а) в)

87

84

б)

85

86

Рис. 4.61. Додавання до переліку нових режимів перегляду даних

74

Після проведення відповідних налаштувань стовпців можемо приступати до форматування форми вікна програми (рис. 4.62).

Перетягнемо з вікна Data Sources на форму програми таблицю People (п. 88), стовпець з фотографіями Photo (п. 89) та стовпець для форматованого блоку тексту Text (п. 90). Для завантаження у базу даних фотографій з файлів перетягнемо на форму програми також діалогову компоненту OpenFileDialog (п. 91).

88

89

90

Рис. 4.62. Форматування форми програми

Компонента DataGridView має можливість відображати також і графічні об’єкти. Однак доцільніше рисунки відображати в окремих вікнах. Тому вилучимо (п. 92) стовпці Photo (п. 91) та Text (п. 93) з переліку відображуваних стовпців компоненти DataGridView.

91

93

92

Рис. 4.63. Налаштування кількості стовпців для відображення

75

Відформатуємо дизайн форми програми. Для того, щоб рисунки зменшувалися до розміру компоненти PictureBox, встановимо для її параметра SizeMode значення Zoom. Для завантаження та вилучення фотографій додамо на форму програми дві кнопки (Button) та запрограмуємо їхні функції оброблення події натиснення кнопки таким чином:

// завантаження фотографії у базу даних private: System::Void button1_Click

(System::Object^ sender, System::EventArgs^ e)

{

if(openFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK)

PhotoPictureBox->Image = System::Drawing::Image::FromFile(openFileDialog1->FileName);

}

// вилучення фотографії private: System::Void button2_Click

(System::Object^ sender, System::EventArgs^ e)

{

PhotoPictureBox->Image = nullptr;

}

Тепер повернемося до компоненти RichTextBox, яка зв’язана зі стовпцем Text. За замовчуванням ця компонента працює з базою даних згідно свого параметра Text, тобто без підтримки форматування. Для підтримки форматування тексту, тобто режиму RTF (rich text format), необхідно переналаштувати компоненту на роботу з базою даних через її параметр Rtf. Для цього у класі форми (файл form1.h) потрібно знайти стрічку зі встановленням параметрів компоненти RichTextBox, де здійснюється її прив’язування до бази даних, та замінити перший параметр функції прив’язування з "Text" на "Rtf".

// TextRichTextBox this->TextRichTextBox->DataBindings->Add((gcnew System::Windows::

Forms::Binding(L"Rtf", this->PeopleBindingSource, L"Text", true)));

Остаточний вигляд програми зображений на рис. 4.64. Для форматування тексту можна до форми програми також додати панель з кнопками, як у редакторі Microsoft Word, та запрограмувати кожну з них на окрему функцію форматування тексту.

76

Рис. 4.64. Програма-клієнт з BLOB-полями

4.3.11. Особливості обновлення даних в об’єкті DataSet.

Строго типізований об’єкт DataSet представляє собою від’єднану від сервера модель даних. Він завантажує дані зі сервера шляхом виклику функції Fill() адаптера даних кожної таблиці, дає можливість відредагувати ці дані (змінити, вставити, видалити) та потім за допомогою функції Update() цих же адаптерів даних передати зміни у базу даних на сервері. У випадку однієї, реляційно незв’язаної таблиці, проблем з отриманням та зворотною передачею даних немає жодних. Однак, коли структура бази даних передбачає реляційні залежності між таблицями, тобто накладаються обмеження зовнішнього ключа, тоді й виникають проблеми з обновленням даних, послідовність обновлення яких є порушеною.

Помилки щодо порушення цілісності даних можуть генеруватися як на рівні об’єкта DataSet, так і при передачі змін у базу даних на сервері. Розглянемо основні етапи обновлення даних для таблиць з реляційною залежністю за схемою «головний-підлеглий».

А. Заповнення даними таблиць об’єкта DataSet.

Якщо зв’язки між таблицями в об’єкті DataSet встановлені з параметром ForeignKeyConstraint, тоді при створенні форми програмиклієнта необхідно заповнити таблиці даними з бази даних серверу у правильному порядку. У першу чергу потрібно заповнити головні таблиці, а потім вже підлеглі до них, тобто такі, що мають встановлений зовнішній ключ з посиланням на потенційний ключ головної таблиці.

77

Проілюструємо це на прикладі структури бази даних КСА.

-1-

Groups

-2-

School

Students

Hostel

 

-3-

Joint Debts

Порядок заповнення даними об’єкта DataSet:

1)таблиці Groups, Schools, Hostels, Debts;

2)таблиця Students;

3)таблиця Joint.

Функція оброблення події завантаження форми програми має мати такий вигляд:

private: System::Void Form1_Load

(System::Object^ sender, System::EventArgs^ e)

{

this->GroupsTableAdapter->Fill(this->KSADataSet->Groups); this->SchoolsTableAdapter->Fill(this->KSADataSet->Schools); this->HostelsTableAdapter->Fill(this->KSADataSet->Hostels); this->DeptsTableAdapter->Fill(this->KSADataSet->Depts); this->StudentsTableAdapter->Fill(this->KSADataSet->Students); this->JointTableAdapter->Fill(this->KSADataSet->Joint);

}

Б. Очищення від даних таблиць об’єкта DataSet.

Очищення від даних здійснюється у зворотному порядку, тобто в першу чергу необхідно очистити таблиці, що мають залежність від інших таблиць, а потім вже головні таблиці.

-3-

Groups

-2-

School

Students

Hostel

 

-1-

Joint Debts

78

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]