- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
S. D. F. - W Cat
Шрифт:
Интервал:
Закладка:
090 S := 'SELECT ';
100 for i := 0 to Items.Count - 1 do // список полей вставляем в запрос
110 if Checked[i] then
120 S := S + LowerCase(Items[i]) + ', ';
130 end; // with CheckListBox1
140 delete(S, length(S)-1, 2);
150 Memo1.Clear;
160 Memo1.Lines.Add(S);
170 S := 'FROM '+ LowerCase( ListBox1.Items[ ListBox1.ItemIndex] );
180 Memo1.Lines.Add(S);
190 RunSQL( MakeSQL);
200 end;
- Тут все должно быть ясно: кнопка вырабатывает команду SELECT для полей отмеченных галочкой и распечатывает результат.
* Ну, как теперь-то все готово.
- Вот же шило в одном месте. Ладно, следующий пункт:
Тестирование
- Как ты помнишь, тренироваться мы будем по книге Мартина Грубера «Понимание SQL»[1], при потребности будем поглядывать в «Firebird. Руководство разработчика баз данных» Хелен Борри[2].
* Ну и в интернете найдется масса материала.
- Для нашей игры понадобится база с определенными таблицами, полюбуйся на них приложении к [1].
* Не сказать, что 3 таблицы это очень много, но…
- Я так понимаю, что тебе лень, а лень двигатель прогресса.
- В данном случае, я тебе помогу…
- На закладке SQL ставим еще одну кнопку «Run SQL by List».
- Будут выполнятся запросы записанные в текстовом файле.
- Каждый запрос должен заканчиваться «;», допускается перенос запроса на несколько строк, не допускается несколько запросов в одной строке.
- Не отображается результат запросов SELECT
- При ошибочном запросе, выполнение списка прекращается.
010 procedure TFMain.Button6Click(Sender: TObject);
020 var
030 i : integer;
040 L : TStringList;
050 S : string;
060 begin // Run SQL by List
070 with OpenDialog1 do
080 begin // подготавливаем диалог
090 Filter := 'File with SQL|*.txt';
100 DefaultExt := 'txt';
110 if Execute then
120 with DataModule2 do
130 begin
140 L := TStringList.Create;
150 L.LoadFromFile(FileName); // открываем файл
160 His.Lines.Add('Run SQL by List '+FileName);// запись в историю
170 S := '';
180 for i := 0 to L.Count - 1 do
190 begin
200 S := S + ' ' + L[i]; // складываем строки
210 if pos(';', S) > 0 then // пока в строке не появится ';'
220 begin
230 S := trim(S); // ??
240 His.Lines.Add(S); // записываем запрос в историю
250 if RunSQL(S) then break; // если запрос не выполнился выходим.
260 S := '';
270 end; // if
280 end; // for
290 L.Free;
300 end; // if Execute
310 end; // OpenDialog1
320 end;
* В общем все понятно…
* Что за безобразие, хочу чтобы SELECT тоже выполнялись списком.
- Надо подумать. Минуточку. «Раз, два... Меркурий во втором доме... луна ушла... шесть – несчастье... вечер – семь...»
- Готово – сделать можно, даже несколько вариантов, т.е. я имею в виду из уже готовых элементов кода с минимальными добавлениями, а значит, я ничего подсказывать не буду, уж изволь сделать сам.
* Да?!
- Да.
- Возвращаюсь к нашей теме.
- Сейчас я тебе дам пару файлов. Желательно, чтобы ты поступил так:
- 1. Создай новую базу.
- 2. Сделай из нижеследующего файл и выполни его.
«начало кода»
CREATE TABLE Salespeople
( snum integer,
sname char (10),
city char (10),
comm decimal );
CREATE TABLE Customers
( cnum integer,
cname char (10),
city char (10),
rating integer,
snum integer );
CREATE TABLE Orders
( onum integer,
amt decimal,
odate date,
cnum integer,
snum integer );
«конец кода»
- 3. Тут есть нюанс, который я еще не понял, но после создания таблицы, она не активна!?! Потом попробуешь, и возможно найдешь красивое решение. А пока закрой программу, затем запусти ее вновь и открой свою базу. Этого достаточно.
- 4. Сделай следующий файл и выполни:
«начало кода»
INSERT INTO Salespeople (snum,sname,city ,comm)
VALUES (1001,'Peel','London',.12);
INSERT INTO Salespeople (snum,sname,city ,comm)
VALUES (1002,'Serres','San Jose',.13);
INSERT INTO Salespeople (snum,sname,city ,comm)
VALUES (1004,'Motika','London',.11);
INSERT INTO Salespeople (snum,sname,city ,comm)
VALUES (1007,'Rifkin','Barcelona',.15);
INSERT INTO Salespeople (snum,sname,city ,comm)
VALUES (1003,'Axelrod','New York',.10);
INSERT INTO Customers (cnum,cname,city,rating,snum)
VALUES (2001,'Hoffman','London',100,1001);
INSERT INTO Customers (cnum,cname,city,rating,snum)
VALUES (2002,'Giovanni','Rome',200,1003);
INSERT INTO Customers (cnum,cname,city,rating,snum)
VALUES (2003,'Liu','San Jose',200,1002);
INSERT INTO Customers (cnum,cname,city,rating,snum)
VALUES (2004,'Grass','Berlin',300,1002);
INSERT INTO Customers (cnum,cname,city,rating,snum)
VALUES (2006,'Clemens','London',100,1001);
INSERT INTO Customers (cnum,cname,city,rating,snum)
VALUES (2008,'Cisneros','San Jose',300,1007);
INSERT INTO Customers (cnum,cname,city,rating,snum)
VALUES (2007,'Pereira','Rome',100,1004);
INSERT INTO Orders (onum,amt,odate,cnum,snum)
VALUES (3001,18.69,'10/03/1990',2008,1007);
INSERT INTO Orders (onum,amt,odate,cnum,snum)
VALUES (3003,767.19,'10/03/1990',2001,1001);
INSERT INTO Orders (onum,amt,odate,cnum,snum)
VALUES (3002,1900.10,'10/03/1990',2007,1004);
INSERT INTO Orders (onum,amt,odate,cnum,snum)
VALUES (3005,5160.45,'10/03/1990',2003,1002);
INSERT INTO Orders (onum,amt,odate,cnum,snum)
VALUES (3006,1098.16,'10/03/1990',2008,1007);
INSERT INTO Orders (onum,amt,odate,cnum,snum)
VALUES (3009,1713.23,'10/04/1990',2002,1003);
INSERT INTO Orders (onum,amt,odate,cnum,snum)
VALUES (3007,75.75,'10/04/1990',2004,1002);
INSERT INTO Orders (onum,amt,odate,cnum,snum)
VALUES (3008,4723.00,'10/05/1990',2006,1001);
INSERT INTO Orders (onum,amt,odate,cnum,snum)
VALUES (3010,1309.95,'10/06/1990',2004,1002);
INSERT INTO Orders (onum,amt,odate,cnum,snum)
VALUES (3011,9891.88,'10/06/1990',2006,1001);
«конец кода»
- Все должно пройти хорошо.
* Брюки превращаются, превращаются брюки… в элегантную базу данных. Все ОК.
- Теперь заготовка базы у нас есть, и мы можем выполнять запросы из книги [1] выполнятся будут 3 задачи:
- 1. Самообучение SQL.
- 2. Вычитывание книги (с исправлением опечаток)
- 3. Тестирование программы.
* Значит теперь, со всеми переделками, программа сможет выполнить любой запрос?
- Это предстоит проверить.
Прошло три дня.
- Нет, ребята, пулемета я вам не дам.
- В книге оказалось, очень много ошибок. Ну, очень много ошибок, и все они полезные.
* Догадываюсь, задумано издевательство.
- Точно! Мне так понравилась идея с ошибками, что я задумался, не наделать их и в этом тексте.
* Вот этого, не надо!
- Хорошо, но ошибки неизбежны, где-то что-то я упущу, в этом случае я сделаю вид, что все так и задумано…
* Ну, ты и жук!
- Учись, студент. Учись, как сдавать программу заказчику, главное держать невозмутимое выражение морды лица: “Как, при запуске программы включилось форматирование диска? Ну, это у вас устаревший Windows, давайте я его переставлю, это будет стоить… что, при этом утеряны данные за 3 года работы. Но, это же хорошо (хорошо-то хорошо, да ничего хорошего – что бы еще соврать) – Слава, Богу, это был только сон…”
* Хе-хе, ну у тебя и шуточки. Давай все-таки вернемся к книге [1].
- Да! Как я уже раньше думал сказать, если бы все примеры в книге были бы без ошибок, пользы от нее было бы намного меньше. Копируй запросы, выполняй, проверяй результат… скучно. А тут, наполненная описками жизнь бурлит и хлещет.
* И какие там ошибки?
- Например:
SELECT sname, sity
FROM Salespeople;
WHERE city=LONDON;
или еще:
SELECT * FROM Order WHERE NOT
((odate=10/03/1990 AND cnum < > 1002)OR amt > 2000.00);
- Тут пару ошибок достаточно очевидны (лишний символ “;” и нет апострофов вокруг даты ну и прочее, и прочее.
- В процессе поиска ошибок, возникла потребность изменить программу. А именно, при ошибке выводится сообщение, и часто там указывается на какой строке, и в какой позиции найдена ошибка. Проблема в том, что на исполнение мы даем запрос одной строкой, и соотнести место ошибки, с тем, что на экране…
- Посему, изменяем RunSQL
В разделе переменных добавляем:
LPos : integer; // позиция ошибки
- Между строками 330 и 340 добавляем текст:
330 begin // была ошибка
331 Memo1.Clear;
332 Memo1.Lines.Add(S); // перезапись запроса одной строкой
333 LPos := GetSelStart(Mistake); // поиск места ошибки
334 if LPos > -1 then begin
335 Memo1.SelStart := LPos-1; // вкл индикатора
336 Memo1.SelLength := 1;
337 Memo1.SetFocus;
338 Panel5.Caption := IntToStr(LPos); // дополнительная информ.
339 end;
340 ShowMessage(Mistake); // сообщение об ошибке
- Как видишь, GetSelStart получает строку с описанием ошибки и пытается найти там информация о ее позиции:
function GetSelStart(S: string):integer;
var
i, n : integer;
ss : string;
begin
result := -1;
n := pos('column ',S);
if n > 0
then begin
delete(S,1,n+6);
ss := '';
for i := 1 to length(s) do
if S[i] in ['0'..'9']
then ss := ss + s[i]
else break;
if ss <> '' then
result := StrToInt(ss);
// ShowMessage(S);
end;
end;
- Согласись, тут все довольно просто. Но результат, впечатляет.
- Да, как всегда, что-то да упустишь, во-первых, в компоненте Memo1 измени свойство HideSelection на false – очень помогает, и второе под этим Memo поставь панельку (у меня это Panel5), которая будет показывать текущее положение курсора в строке, для этого вставь обработчик:
procedure TFMain.Memo1Click(Sender: TObject);
begin
Panel5.Caption := IntToStr( Memo1.SelStart );
end;
* Ну, ты загонял, то тут добавить, то там исправить.
- С моей точки зрения, это нормальная работа. Программа, как и живое существо, не рождается полностью функционирующей. Растем, развиваемся, главное, четко понимать, почему и для чего производятся эти манипуляции…
- Ну, что, теперь, твоя очередь тестировать программу.

