| 
| 
 | Вопрос # 1 873/ вопрос открыт / | 
 |  Здравствуйте! Помогите пожалусто . вопрос на самом деле (мне почему то кажеться) легкий....Я использую БД Акцессовскую, делфи7.  При обнавлении базы я должна обнавить существующие записи и добавить новые.
 но вот сложность возникает при переходе к инсерту...
 т.е. при обработке блока if  происходит пошаговое сравнение данных ... и если табель <> табелю из БД ...то естественно возникает ошибка : вставка записи... т.к. табель - д/б уникальным
 Приложение:Переключить в обычный режим      while not DataModule1.ADOQuery3.Eof do         begin If (StrToInt(Edit8.Text)=DataModule1.ADOQuery3.Fields.Fields[1].AsInteger)  then            beginDataModule1.ADOQuery1.Close;DataModule1.ADOQuery1.SQL.Clear;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+'');DataModule1.ADOQuery1.ExecSQL; end  else begin    DataModule1.ADOQuery1.Close;DataModule1.ADOQuery1.SQL.Clear;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+'');DataModule1.ADOQuery1.ExecSQL;  end;DataModule1.ADOQuery3.Next;  end;
|  |   Вопрос задала: Танюшка (статус: Посетитель)Вопрос отправлен: 4 сентября 2008, 11:27
 Состояние вопроса: открыт, ответов: 2.
 |  Ответ #1. Отвечает эксперт: Шичко Игорь Здравствуйте, Танюшка!У Вас небольшая ошибка. Прежде чем заносить новые данные надо проверить весь набор табелей и при отсутствии тогда заносить. код ниже.
 А вообще для нахождения табеля лучше воспользоваться SQL запросом с номером табеля.
 Типа: Select tab_nam from sotrudniky where tab_nam = QuotedStr(Edit8.Text)
 Если количество записей > 0 то табель есть, а если = 0 то вставляем новую запись.
 Если есть вопросы пишите.
 Приложение:Переключить в обычный режим var    DataModule1.ADOQuery3.First;//   priznak:= False;   while not DataModule1.ADOQuery3.Eof do   begin //   If (StrToInt(Edit8.Text)=DataModule1.ADOQuery3.Fields.Fields[1].AsInteger)  then     begin     DataModule1.ADOQuery1.Close;     DataModule1.ADOQuery1.SQL.Clear;     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+'');     DataModule1.ADOQuery1.ExecSQL;      end;   DataModule1.ADOQuery3.Next;   end;     ///      begin     DataModule1.ADOQuery1.Close;     DataModule1.ADOQuery1.SQL.Clear;     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)+')');     DataModule1.ADOQuery1.ExecSQL;    end; 
|  | Ответ отправил: Шичко Игорь (статус: 9-ый класс)Время отправки: 4 сентября 2008, 12:10
 Оценка за ответ: 5
 |  Ответ #2. Отвечает эксперт: ANBsoft Здравствуйте, Танюшка!По логике, все совсем не так.
 Смотрите приложение.
 Примерно так, далее разберетесь.
 Приложение:Переключить в обычный режим    //If (StrToInt(Edit8.Text)=DataModule1.ADOQuery3.Fields.Fields[1].AsInteger)  then begin DataModule1.ADOQuery1.Close;DataModule1.ADOQuery1.SQL.Clear; DataModule1.ADOQuery1.ExecSQL; end  else begin    DataModule1.ADOQuery1.Close;DataModule1.ADOQuery1.SQL.Clear;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+'');DataModule1.ADOQuery1.ExecSQL;  end;//DataModule1.ADOQuery3.Next;//  end;
|  | Ответ отправил: ANBsoft (статус: Студент)Время отправки: 4 сентября 2008, 12:10
 Оценка за ответ: 4
 |  
 Мини-форум вопросаВсего сообщений: 20; последнее сообщение — 4 сентября 2008, 23:19; участников в обсуждении: 4. 
|   | 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 (статус: Студент), 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 (статус: Студент), 4 сентября 2008, 13:19 [#5]:Это при условии что tab_nam - текстовое |  
|   | Вадим К (статус: Академик), 4 сентября 2008, 13:25 [#6]:to  Бубырь Александр Николаевич стоп-стоп.  tab_nam это число или строка? Конструкция
 '''+QuotedStr(Edit8.Text)+'''
 сделает чистый ужас в результируей строке.
 На сколько я вижу, там кавычки не нужны и QuotedStr также.
 
 to Танюшка
 Менять с помощью insert автоинкрементное поле нельзя. Может в этом вся загвоздка?
 Галочка "подтверждения прочтения" - вселенское зло. |  
|   | ANBsoft (статус: Студент), 4 сентября 2008, 13:41 [#7]:Согласен, протормозил. Сам никогда не пользовался QuotedStr, проще было писать '''.
 |  
|   | Вадим К (статус: Академик), 4 сентября 2008, 13:54 [#8]:и ещё раз замечание. QuotedStr - хорошая функция. Но она для строк. Ведь представьте себе, что в запросе выглядит так
 +'bla-bla="'+s+'"';
 и переменная s  попадает с внешнего мира, например напрямую с Edit. Всё вроде хорошо, пока кто то не додумается написать там что то вида
 test"; drop table xxx; ---
 Синтаксис будет конечно меняться от языка к языку, но идея думаю понятна.
 Галочка "подтверждения прочтения" - вселенское зло. |  
|   | ANBsoft (статус: Студент), 4 сентября 2008, 14:47 [#9]:Интересная мысль, за 10 лет ниразу не сталкивался с таким. Хотя вредителя, который такое сможет написать QuotedStr, думаю, не остановит. А вообще, спасибо, буду иметь в виду.
 |  
|   | Вадим К (статус: Академик), 4 сентября 2008, 14:54 [#10]:Это не "интересная мысль", а реальная технология, с помощью которой падают сервера в интернете. QuotedStr таких остановит, так как он не только берёт в кавычки, а и экранирует лишние кавычки. А в базу они попадают так как надо - там лишних кавычек уже не будет. Правда есть ещё десяток путей для вредительства.
 есть такое правило " не доверяй входным данным, даже если они полученны от тебя и подписаны хорошим crc"
 Галочка "подтверждения прочтения" - вселенское зло. |  
|   | 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 (статус: Студент), 4 сентября 2008, 17:15 [#13]:Не буду спорить, для меня это не актуально. Если бы эта функция вызывалась хотябы тысячами раз, стоило б париться, а так как написал давным давно, потом только вызывал. На заре компьютеров все бились ради экономии каждого байта, сейчас время программистов стоит дороже мощностей компьютеров.
 Я не призываю писать тормознутые, кривые программы, просто есть вещи которые стоит оптимизировать и вылизывать (тратить на это свое время), а есть те, которые работают правильно!, и это главное.
 |  
|   | Вадим К (статус: Академик), 4 сентября 2008, 17:39 [#14]:Вы случайно в разработке Висты не участвовали? там точно такая же идеолония. Я не призываю к преждевременной оптимизации - я призываю писать красивый код. Вот к примеру в Вашем коде есть присваивание ss:=s; - без него всё будет работать, даже быстрее, и это не оптимизация, это просто нормальное написание кода.
 Галочка "подтверждения прочтения" - вселенское зло. |  
|   | ANBsoft (статус: Студент), 4 сентября 2008, 18:00 [#15]:В разработке Висты не участвовал, но при всех нареканиях на MicroSoft, это самая успешная софтверная компания (в финансовом плане), а это повод задуматься. Как по мне, так красота кода стоит после надежности и скорости написания.
 По поводу присваивания ss:=s, это просто привычка работать с локальными переменными. Да, передаваемое значение s и так локальное, а функция простая, но возможен вариант, что функция будет на несколько сотен строк, и в какой-то момент разработки появится необходимость объявить Var S (переменная перестанет быть локальной), прийдется полностью переделывать весь код функции.
 Есть хорошее выражение, с которым я согласен:
 "Клиенту лучше неоптимальная, большая, медленная, некрасивая программа, но работающая сейчас, чем маленькая, быстрая удобная, но которая будет через год".
 Будет необходимость (и финансирование), всегда можно доработать и улучшить, а с вылизыванием мелочей часто теряешь клиента.
 P.S. Нет предела совершенству, а лучшее - враг хорошего.
 |  
|   | ANBsoft (статус: Студент), 4 сентября 2008, 18:13 [#16]:Еще, может ошибаюсь, но все ускорение выльется в несколько тактов процессора на выполнение ss:=s; (увеличится счетчик использования для этой строки) и немного лишней памяти на хранение S до конца программы (так бы память освободилась после первого же while). |  
|   | Вадим К (статус: Академик), 4 сентября 2008, 18:36 [#17]:ещё раз повторю я не говорю о вылизывании и оптимизации. Есть такая специальность "индус-кодер" (к национальности не имеет отношения - "индус" - от слова "индустриальный"). Так вот, таким ребятам платят за строки кода. Чем больше строк, тем лучше.
 
 К тому же сами себе противоречите. Вы говорите, что не надо думать об оптимизации, а сами заведомо заводите переменную, что бы поменяв тип параметра на var, не иметь проблем.
 Вообще то принято, что функции за редким исключением меняют входные параметры, поэтому у нормального программиста даже не возникает мысли о таком.
 Мне на работе за подобный код просто сразу руки отрывают. Нет, я не оптимизирую, но если можно написать 3 строки, а я пишу 10, то это плохо, очень плохо. Даже если эти 10 работают быстрее. Только в редких случаях надо пойти на это.
 Галочка "подтверждения прочтения" - вселенское зло. |  
|   | ANBsoft (статус: Студент), 4 сентября 2008, 19:22 [#18]:Все зависит от требований, требуют от Вас писать кратко - куда ж деваться. Я работаю на себя, и как по мне, если 10 строк работают быстрее чем 3 красивых - я напишу 10. При работе с однокристалками (на уровне ASM или опциями компилятора) нужно выбирать что важнее размер кода, занимаемая память или скорость выполнения. Делфи в отличие от Си не предлагает таких опций в компиляторе, к тому же компилятор может сам свернуть лишнее и в вышеописанном коде скорее всего сам сразу освободит s, так как она более не используется (это видно при пошаговой трассировке алгоритма - variable inaccessible here due to optimization). Повторюсь, все зависит от поставленных задач:
 Вам платят деньги на работе, но требуют определенный вид кода,
 мне платят деньги клиенты и требуют скорость реализации задачи и надежность работы, а код в исходниках вообще никто не увидит.
 |  
|   | ANBsoft (статус: Студент), 4 сентября 2008, 19:28 [#19]:----К тому же сами себе противоречите. Вы говорите, что не надо думать об оптимизации, а сами заведомо заводите переменную, что бы поменяв тип параметра на var, не иметь проблем. В чем противоречие, я писал что мне важна надежность кода и скорость разработки, для этого и введена переменная, чтобы при дальнейших модернизациях функции максимально уменьшить переделки и убрать вероятность ошибки при пропуске одной из переменных при подобной переделке. Я написал, это привычка, выработанная через грабли, на которые наступал когда-то (опыт - сын ошибок трудных).
 |  
|   | Вадим К (статус: Академик), 4 сентября 2008, 23:19 [#20]:ой. не буду больше учить. через пару лет наткнётесь на какую то примитивную ошибку и будете мучиться. А всё потому, что делали как Вы хотели. Красивый код пишеться быстрее и в последствии понимается быстрее
  что ещё важнее. "код в исходниках вообще никто не увидит". Увидит. Вы. когда надо будет через полгода доделать немного. И на то, на что у меня уходит пара минут, у Вас может уйти недели дебагинга. Хотя ...
 Галочка "подтверждения прочтения" - вселенское зло. |  Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |