Заранее прошу прощения у ассов клиент-сервер. Им совсем незачем читать эти заметки и ругать меня за изложение тривиальных вещей. Безусловно этот материал для начинающих делать клиент-сервер. Ну не сразу же в конце концов человек становиться ассом. Когда то нужно с чего то начинать. Возможно я не совсем знаком с нашим уровнем знаний, но лично для меня тайна вопросительного знака стала своего рода откровением около двух с половиной лет назад. А когда я ее осознал, то стал ее применять и налево и направо и сэкономил кучу времени и кода. Написание клиент -сервер из Фокса требует двух вещей - знание Фокса и знание сервера. Но наш Российский заказчик , впрочем как и зарубежный, бывает очень не стабилен. Вот говорит он тебе- я твердо решил взять сервером Интербейс. И если что имеешь против - гуляй дальше-программистов навалом. Вот сидишь ты , сидишь, мучаешься с кодом, и наконец, некоторый успех. Вроде научился плавать и ждешь от босса или клиента хоть маленькой похвалы. ( на материальные вознаграждения только слабая надежда.) И тут это гражданин(ка) или контора вдруг и говорит , мы решили -Оракл. ( а ты их сам умолял и просил до этого про это) И все -код-коту под хвост. Только ты освоился с Оракл, а они как капризная девица говорят- мы твердо решили -MS SQL. Ну вот, посколько у нас в стране любой даже самый захудалый заказчик или клиент очень редок, ты на все соглашаешья и молча учишь все это подряд. В такой ситуевине нужно все, что только можно сделать менее зависимым от сервера ( хотя реальной инвариатности кода все равно нет) и все , что только можно засунуть в классы библиотек, работающих с серверами. Тогда любой выворот уже и не страшен. Так вот огромную роль в этой самой инвариантности кода играет вопросительный знак. Кое что про него найдете в ссылках : http://support.microsoft.com/subbort/kb/articles/q156/6/31.asp?LNG=ENG&AS=PER http://support.microsoft.com/support/kb/articles/q157/5/25.asp?LNG=ENG&AS=PER
К большому сожалению во всех этих ссылках есть примеры с вопросительным знаком для команд сервера типа SELECT * from mytable where mytable.pid=?m.pid. Однако простая проверка показывает, что вопросительный знак работает и в других командах. Будь моя воля, я как всякий ленивый программист поставил бы памятник тому разработчику, кто придумал и реализовал этот самый вопросительный знак. Ну а теперь поближе к нашим баранам. Что это нам дает . Как скажем послать на Оракл ( другие сервера или куда подальше ) обычную переменную с полем типа дата , на MS SQL переменную с парой двойных одинарных или обратных апострофов, вообще целый файл с текстом, в котором вообще не известно какие спец символы и кавычки есть в бинарное поле Оракл. Техника , которую обычно советуют-замена одних кавычек на другие , что ломает текст. Ну всем известно, что есть функция SQLEXEC с командой сервера, а команда -это текстовая строка. Ну думаем мы-сделаем эту строку на Фоксе и все дела . Пусть мы имеем фоксовскую переменную vfpdateofbirth типа дата и хотим ее присвоить дню рождения работника на сервере Оракл . Напишем следующую переменную типа текст и пошлем ее на Оракл m.sql='insert into demo.employee (dateofbirth) values('+dtoc(vfpdateofbirth)+')' - Переменная хоть куда - весь текст с чем надо. Посылаем на сервер =sqlexec(con,m.sql) И:. Оракл посылает нас к чертовой бабушке. Открываем справочник по Оракл и обнаруживаем, что данный сервер жутко чувствителен к формату Нужно еще знать Оракловскую функцию to_date и кучу ее правильных форматов,не всякий из которых годиться для Фокс переменной. То есть нужно написать что то вроде Cdt=dtoc(vfpdateofbirth) (to_date('"+cdt+"','DD.MM.YYYY'))". А то может быть и to_date('"+cdt+"',"DD.MM.YYYY HH24.MM.SS'). если фоксовская переменная типа дэйттайм. Дальше-больше , для Интербейс нужно знать функцию преобразования типов cast , для MS SQL функцию convert. Так или иначе, все это все равно узнаешь, но ей богу это мнговато для такого старого маразматика , как я. Но вопросительный знак сам делает всю работу дез всяких таких функций. Перепишем нашу первую команду так m.sql='insert into demo.employee (dateofbirth) values (?dtoc(vfpdateofbirth)' =sqlexec(con,m.sql)
Посылаем на любой сервер- и все хорошо. Есть правда несколько несколько небольших тонкостей на разных серверах. Скажем если послать пустую дату на MS SQL SERVER , он вместо нее запишет дату начала века ( зависит от текущих серверных установок). Следует заменить ее на NULL Проблема с апострофами для вопросительного знака не существует m.sql0='insert into table (fieldname) values ('m.sql2=")" m.sql=' "" '+" '' "+ . . . .! Сколько хочешь любых одиночных и парных апострофов m.sqlr=m.sql0+'?m.sql'+msql2 sqlexec(con,.mqlr) Переменная m.sqlr может быть даже содержанием файла, в котором бох знает что лежит . Вот фрагмент одной моей программы , где Фоксовые переменные разного типа посылаются на разные типы полей в MS SQL server aa='insert into 'thisform.port('Karti') SELECT karti rc=recc() j=0 GO top bb+aa+'documents(documentcodeid,controltime,dateofcreation,outgono,incomno,corrdate,soprovno,contents, execdate,documenttypeid,soprovnodate,folder,correspondent) values('DO while not eof('karti') j=j+1 select karti kd=0 IF seek(int(val(kodd)),'docc','numcode') kd=docc.documentcodeid ELSE kd=0 ENDIF sod=sodd+''+sodd1+''+sodd2+''+sodd3 dl+iif(isdigit(delo),delo,'00') *** Решение проблемы пустой даты, чтобы не было 01.01.1900 01.01.2000 srokt=iif(empty(sroki),null,sroki) datpt+iif(empty(datp),null,datp) soprdatt+iif(empty(soprdat),null,soprdat) datot=iif(empty(dato),null,dato) dap1t=iif(empty(dap1),null,dap1) select karti cc=bb+"?kd,?srokt,?datpt,?isn,?vxn,?datot,?soprnom,?sod,?dap1t,1,?sorpdatt,?dl,?korr1)" IF sqlexec(con,cc)>0 ELSE thisform.write_error("karti",line()) *messagebox(str(recno(karti))) ENDIF
Все переменные с вопросительным знаком -это переменные Фокса.