Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 1 873

/ вопрос открыт /

Здравствуйте! Помогите пожалусто . вопрос на самом деле (мне почему то кажеться) легкий....
Я использую БД Акцессовскую, делфи7. При обнавлении базы я должна обнавить существующие записи и добавить новые.
но вот сложность возникает при переходе к инсерту...
т.е. при обработке блока if происходит пошаговое сравнение данных ... и если табель <> табелю из БД ...то естественно возникает ошибка : вставка записи... т.к. табель - д/б уникальным

Приложение:
  1.  
  2.  
  3. while not DataModule1.ADOQuery3.Eof do
  4. begin
  5.  
  6. If (StrToInt(Edit8.Text)=DataModule1.ADOQuery3.Fields.Fields[1].AsInteger) then
  7. begin
  8. DataModule1.ADOQuery1.Close;
  9. DataModule1.ADOQuery1.SQL.Clear;
  10. DataModule1.ADOQuery1.SQL.Add('update sotrudniky set adress='+ QuotedStr(Edit11.Text)+',data_roz ='+ QuotedStr(Edit7.Text)+',fio=' + QuotedStr(Edit6.Text) + ',UNN='+ QuotedStr(Edit9.Text)+',data_vidachi='+ QuotedStr(Edit10.Text)+',vidan='+ QuotedStr(Edit12.Text)+',seria='+ QuotedStr(Edit13.Text)+',ctaz_v_ap='+ QuotedStr(Edit14.Text)+' where tab_nam = '+DataModule1.ADOQuery3.Fields.Fields[1].AsString+'');
  11. DataModule1.ADOQuery1.ExecSQL;
  12. end
  13.  
  14. else begin
  15. DataModule1.ADOQuery1.Close;
  16. DataModule1.ADOQuery1.SQL.Clear;
  17. DataModule1.ADOQuery1.SQL.Add('insert into sotrudniky (adress,data_roz,fio,UNN,data_vidachi,vidan,seria,ctaz_v_ap,tab_nam) values('+ QuotedStr(Edit11.Text)+','+ QuotedStr(Edit7.Text)+',' + QuotedStr(Edit6.Text) + ','+ QuotedStr(Edit9.Text)+','+ QuotedStr(Edit10.Text)+','+ QuotedStr(Edit12.Text)+','+ QuotedStr(Edit13.Text)+','+ QuotedStr(Edit14.Text)+','+ QuotedStr(Edit8.Text)+')');//ctaz_v_ap='+ QuotedStr(Edit14.Text)+' where tab_nam = '+DataModule1.ADOQuery3.Fields.Fields[1].AsString+'');
  18. DataModule1.ADOQuery1.ExecSQL;
  19. end;
  20. DataModule1.ADOQuery3.Next;
  21. end;


Танюшка Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задала: Танюшка (статус: Посетитель)
Вопрос отправлен: 4 сентября 2008, 11:27
Состояние вопроса: открыт, ответов: 2.

Ответ #1. Отвечает эксперт: Шичко Игорь

Здравствуйте, Танюшка!
У Вас небольшая ошибка. Прежде чем заносить новые данные надо проверить весь набор табелей и при отсутствии тогда заносить. код ниже.
А вообще для нахождения табеля лучше воспользоваться SQL запросом с номером табеля.
Типа: Select tab_nam from sotrudniky where tab_nam = QuotedStr(Edit8.Text)
Если количество записей > 0 то табель есть, а если = 0 то вставляем новую запись.
Если есть вопросы пишите.

Приложение:
  1. var
  2.  
  3.  
  4. DataModule1.ADOQuery3.First;//
  5. priznak:= False;
  6. while not DataModule1.ADOQuery3.Eof do
  7. begin //
  8. If (StrToInt(Edit8.Text)=DataModule1.ADOQuery3.Fields.Fields[1].AsInteger) then
  9. begin
  10. DataModule1.ADOQuery1.Close;
  11. DataModule1.ADOQuery1.SQL.Clear;
  12. DataModule1.ADOQuery1.SQL.Add('update sotrudniky set adress='+ QuotedStr(Edit11.Text)+',data_roz ='+ QuotedStr(Edit7.Text)+',fio=' + QuotedStr(Edit6.Text) + ',UNN='+ QuotedStr(Edit9.Text)+',data_vidachi='+ QuotedStr(Edit10.Text)+',vidan='+ QuotedStr(Edit12.Text)+',seria='+ QuotedStr(Edit13.Text)+',ctaz_v_ap='+ QuotedStr(Edit14.Text)+' where tab_nam = '+DataModule1.ADOQuery3.Fields.Fields[1].AsString+'');
  13. DataModule1.ADOQuery1.ExecSQL;
  14.  
  15. end;
  16. DataModule1.ADOQuery3.Next;
  17. end;
  18. ///
  19.  
  20. begin
  21. DataModule1.ADOQuery1.Close;
  22. DataModule1.ADOQuery1.SQL.Clear;
  23. DataModule1.ADOQuery1.SQL.Add('insert into (adress,data_roz,fio,UNN,data_vidachi,vidan,seria,ctaz_v_ap,tab_nam) values('+ QuotedStr(Edit11.Text)+','+ QuotedStr(Edit7.Text)+',' + QuotedStr(Edit6.Text) + ','+ QuotedStr(Edit9.Text)+','+ QuotedStr(Edit10.Text)+','+ QuotedStr(Edit12.Text)+','+ QuotedStr(Edit13.Text)+','+ QuotedStr(Edit14.Text)+','+ QuotedStr(Edit8.Text)+')');
  24. DataModule1.ADOQuery1.ExecSQL;
  25. end;
  26.  


Ответ отправил: Шичко Игорь (статус: 9-ый класс)
Время отправки: 4 сентября 2008, 12:10
Оценка за ответ: 5

Ответ #2. Отвечает эксперт: ANBsoft

Здравствуйте, Танюшка!
По логике, все совсем не так.
Смотрите приложение.
Примерно так, далее разберетесь.

Приложение:
  1.  
  2.  
  3.  
  4. //If (StrToInt(Edit8.Text)=DataModule1.ADOQuery3.Fields.Fields[1].AsInteger) then begin
  5.  
  6. DataModule1.ADOQuery1.Close;
  7. DataModule1.ADOQuery1.SQL.Clear;
  8.  
  9. DataModule1.ADOQuery1.ExecSQL;
  10. end
  11.  
  12. else begin
  13. DataModule1.ADOQuery1.Close;
  14. DataModule1.ADOQuery1.SQL.Clear;
  15. DataModule1.ADOQuery1.SQL.Add('insert into sotrudniky (adress,data_roz,fio,UNN,data_vidachi,vidan,seria,ctaz_v_ap,tab_nam) values('+ QuotedStr(Edit11.Text)+','+ QuotedStr(Edit7.Text)+',' + QuotedStr(Edit6.Text) + ','+ QuotedStr(Edit9.Text)+','+ QuotedStr(Edit10.Text)+','+ QuotedStr(Edit12.Text)+','+ QuotedStr(Edit13.Text)+','+ QuotedStr(Edit14.Text)+','+ QuotedStr(Edit8.Text)+')');//ctaz_v_ap='+ QuotedStr(Edit14.Text)+' where tab_nam = '+DataModule1.ADOQuery3.Fields.Fields[1].AsString+'');
  16. DataModule1.ADOQuery1.ExecSQL;
  17. end;
  18. //DataModule1.ADOQuery3.Next;
  19. // end;


Ответ отправил: ANBsoft (статус: Студент)
Время отправки: 4 сентября 2008, 12:10
Оценка за ответ: 4


Мини-форум вопроса

Всего сообщений: 20; последнее сообщение — 4 сентября 2008, 23:19; участников в обсуждении: 4.
ANBsoft

ANBsoft (статус: Студент), 4 сентября 2008, 12:22 [#1]:

По логике у Вас нет двух сотрудников с одинаковым табельным номером. Соответственно если Locate нашел табельный номер, то можно его редактировать, иначе - вставлять.
Сам с ADO не работал (больше FireBird привлекает), но может быть будет проще нормально настроить компоненты и использовать обычный Insert/Edit - Post чем такие глобальные Update и Insert?
Танюшка

Танюшка (статус: Посетитель), 4 сентября 2008, 12:36 [#2]:

DataModule1.Query.Close;
DataModule1.Query.sql.Clear;
DataModule1.Query.sql.Add('select tab_nam from sotrudniky where tab_nam ='+QuotedStr(Edit8.Text)+');
DataModule1.Query.Open;
выскакивает ошибка: несоотв. типов в условии отбора ....
как можно ее обойти????
ANBsoft

ANBsoft (статус: Студент), 4 сентября 2008, 13:18 [#3]:

Я же написал про кавычки, попробуйте так:
DataModule1.Query.sql.Add('select tab_nam from sotrudniky where tab_nam ='''+QuotedStr(Edit8.Text)+''');
Шичко Игорь

Шичко Игорь (статус: 9-ый класс), 4 сентября 2008, 13:19 [#4]:

Так как tab_nam это числовое значение (насколько я понял) поэтому и запрос нужно писать для числового значения
DataModule1.Query.sql.Add('select tab_nam from sotrudniky where tab_nam =' + Edit8.Text);
Только перед этим необходимо проверять точно ли числовое значение в Edit8.Text.
Кстати в запросе на вставку записи нужно подкорректировать под числовое значение.
ANBsoft

ANBsoft (статус: Студент), 4 сентября 2008, 13:19 [#5]:

Это при условии что tab_nam - текстовое
Вадим К

Вадим К (статус: Академик), 4 сентября 2008, 13:25 [#6]:

to Бубырь Александр Николаевич
стоп-стоп. tab_nam это число или строка? Конструкция
'''+QuotedStr(Edit8.Text)+'''
сделает чистый ужас в результируей строке.
На сколько я вижу, там кавычки не нужны и QuotedStr также.

to Танюшка
Менять с помощью insert автоинкрементное поле нельзя. Может в этом вся загвоздка?
Галочка "подтверждения прочтения" - вселенское зло.
ANBsoft

ANBsoft (статус: Студент), 4 сентября 2008, 13:41 [#7]:

Согласен, протормозил.
Сам никогда не пользовался QuotedStr, проще было писать '''.
Вадим К

Вадим К (статус: Академик), 4 сентября 2008, 13:54 [#8]:

и ещё раз замечание.
QuotedStr - хорошая функция. Но она для строк. Ведь представьте себе, что в запросе выглядит так
+'bla-bla="'+s+'"';
и переменная s попадает с внешнего мира, например напрямую с Edit. Всё вроде хорошо, пока кто то не додумается написать там что то вида
test"; drop table xxx; ---
Синтаксис будет конечно меняться от языка к языку, но идея думаю понятна.
Галочка "подтверждения прочтения" - вселенское зло.
ANBsoft

ANBsoft (статус: Студент), 4 сентября 2008, 14:47 [#9]:

Интересная мысль, за 10 лет ниразу не сталкивался с таким.
Хотя вредителя, который такое сможет написать QuotedStr, думаю, не остановит. А вообще, спасибо, буду иметь в виду.
Вадим К

Вадим К (статус: Академик), 4 сентября 2008, 14:54 [#10]:

Это не "интересная мысль", а реальная технология, с помощью которой падают сервера в интернете. QuotedStr таких остановит, так как он не только берёт в кавычки, а и экранирует лишние кавычки. А в базу они попадают так как надо - там лишних кавычек уже не будет.
Правда есть ещё десяток путей для вредительства.
есть такое правило " не доверяй входным данным, даже если они полученны от тебя и подписаны хорошим crc"
Галочка "подтверждения прочтения" - вселенское зло.
ANBsoft

ANBsoft (статус: Студент), 4 сентября 2008, 15:26 [#11]:

Я для решения подобных проблем использовал свою функцию:
Function CheckName(s:String):String;
Var ss:String;
f:Integer;
Begin
//Ограничение на значения ячеек при импорте в Excel
ss:=s;
while (Length(ss)>0) and (ss[1] in ['=','-','+']) do Delete(ss,1,1);
//Ограничение на значения имен в SQL операторе
f:=1;
while (f<=Length(ss)) do
if ss[f] in [''''{,'*','/','=','-','+'}] then Delete(ss,f,1) //Часть ограничений потом снял
else Inc(f);
Result:=ss;
End;
Вадим К

Вадим К (статус: Академик), 4 сентября 2008, 15:39 [#12]:

за код - натянутая троечка. Мло того, что медленный код будет, так ещё ужас некрасивый (его можно переписать как минимум на пару строк короче.
При длине строки в 30-40 символов, уже будет давать заметные тормоза.
Галочка "подтверждения прочтения" - вселенское зло.
ANBsoft

ANBsoft (статус: Студент), 4 сентября 2008, 17:15 [#13]:

Не буду спорить, для меня это не актуально. Если бы эта функция вызывалась хотябы тысячами раз, стоило б париться, а так как написал давным давно, потом только вызывал.
На заре компьютеров все бились ради экономии каждого байта, сейчас время программистов стоит дороже мощностей компьютеров.
Я не призываю писать тормознутые, кривые программы, просто есть вещи которые стоит оптимизировать и вылизывать (тратить на это свое время), а есть те, которые работают правильно!, и это главное.
Вадим К

Вадим К (статус: Академик), 4 сентября 2008, 17:39 [#14]:

Вы случайно в разработке Висты не участвовали? там точно такая же идеолония. Я не призываю к преждевременной оптимизации - я призываю писать красивый код.
Вот к примеру в Вашем коде есть присваивание ss:=s; - без него всё будет работать, даже быстрее, и это не оптимизация, это просто нормальное написание кода.
Галочка "подтверждения прочтения" - вселенское зло.
ANBsoft

ANBsoft (статус: Студент), 4 сентября 2008, 18:00 [#15]:

В разработке Висты не участвовал, но при всех нареканиях на MicroSoft, это самая успешная софтверная компания (в финансовом плане), а это повод задуматься.
Как по мне, так красота кода стоит после надежности и скорости написания.
По поводу присваивания ss:=s, это просто привычка работать с локальными переменными. Да, передаваемое значение s и так локальное, а функция простая, но возможен вариант, что функция будет на несколько сотен строк, и в какой-то момент разработки появится необходимость объявить Var S (переменная перестанет быть локальной), прийдется полностью переделывать весь код функции.
Есть хорошее выражение, с которым я согласен:
"Клиенту лучше неоптимальная, большая, медленная, некрасивая программа, но работающая сейчас, чем маленькая, быстрая удобная, но которая будет через год".
Будет необходимость (и финансирование), всегда можно доработать и улучшить, а с вылизыванием мелочей часто теряешь клиента.
P.S. Нет предела совершенству, а лучшее - враг хорошего.
ANBsoft

ANBsoft (статус: Студент), 4 сентября 2008, 18:13 [#16]:

Еще, может ошибаюсь, но все ускорение выльется в несколько тактов процессора на выполнение ss:=s; (увеличится счетчик использования для этой строки) и немного лишней памяти на хранение S до конца программы (так бы память освободилась после первого же while).
Вадим К

Вадим К (статус: Академик), 4 сентября 2008, 18:36 [#17]:

ещё раз повторю
я не говорю о вылизывании и оптимизации. Есть такая специальность "индус-кодер" (к национальности не имеет отношения - "индус" - от слова "индустриальный"). Так вот, таким ребятам платят за строки кода. Чем больше строк, тем лучше.

К тому же сами себе противоречите. Вы говорите, что не надо думать об оптимизации, а сами заведомо заводите переменную, что бы поменяв тип параметра на var, не иметь проблем.
Вообще то принято, что функции за редким исключением меняют входные параметры, поэтому у нормального программиста даже не возникает мысли о таком.
Мне на работе за подобный код просто сразу руки отрывают. Нет, я не оптимизирую, но если можно написать 3 строки, а я пишу 10, то это плохо, очень плохо. Даже если эти 10 работают быстрее. Только в редких случаях надо пойти на это.
Галочка "подтверждения прочтения" - вселенское зло.
ANBsoft

ANBsoft (статус: Студент), 4 сентября 2008, 19:22 [#18]:

Все зависит от требований, требуют от Вас писать кратко - куда ж деваться. Я работаю на себя, и как по мне, если 10 строк работают быстрее чем 3 красивых - я напишу 10. При работе с однокристалками (на уровне ASM или опциями компилятора) нужно выбирать что важнее размер кода, занимаемая память или скорость выполнения. Делфи в отличие от Си не предлагает таких опций в компиляторе, к тому же компилятор может сам свернуть лишнее и в вышеописанном коде скорее всего сам сразу освободит s, так как она более не используется (это видно при пошаговой трассировке алгоритма - variable inaccessible here due to optimization).
Повторюсь, все зависит от поставленных задач:
Вам платят деньги на работе, но требуют определенный вид кода,
мне платят деньги клиенты и требуют скорость реализации задачи и надежность работы, а код в исходниках вообще никто не увидит.
ANBsoft

ANBsoft (статус: Студент), 4 сентября 2008, 19:28 [#19]:

----К тому же сами себе противоречите. Вы говорите, что не надо думать об оптимизации, а сами заведомо заводите переменную, что бы поменяв тип параметра на var, не иметь проблем.
В чем противоречие, я писал что мне важна надежность кода и скорость разработки, для этого и введена переменная, чтобы при дальнейших модернизациях функции максимально уменьшить переделки и убрать вероятность ошибки при пропуске одной из переменных при подобной переделке. Я написал, это привычка, выработанная через грабли, на которые наступал когда-то (опыт - сын ошибок трудных).
Вадим К

Вадим К (статус: Академик), 4 сентября 2008, 23:19 [#20]:

ой. не буду больше учить. через пару лет наткнётесь на какую то примитивную ошибку и будете мучиться. А всё потому, что делали как Вы хотели.
Красивый код пишеться быстрее и в последствии понимается быстрее:) что ещё важнее.
"код в исходниках вообще никто не увидит". Увидит. Вы. когда надо будет через полгода доделать немного. И на то, на что у меня уходит пара минут, у Вас может уйти недели дебагинга. Хотя ...
Галочка "подтверждения прочтения" - вселенское зло.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:29
Выполнено за 0.02 сек.