Поради по клієнт-сервер на Оракл, FoxPro, Бази даних, статті

Visual FoxPro CLUB

Два роки тому мені довелося взяти участь у великому проекті VFP (клієнт)-Oracle (сервер). Хоча до цього досить довго грався з персональним Оракл сервером, на перших порах кожен наш крок при виконанні проекту видобувався важко і розглядався як маленька перемога. Після цього по гарячих слідах довелося для інших клієнтів зробити ще проект. За після часу всі ці перемоги здаються нічого не значащамі дрібницями. Але може комусь знадобляться і ці поношені речі. Знову наголошую, знавцям тут читати нічого. Інформація в основному для початківців.

  1. Якщо Команда послана на сервер Оракл дає Вам помилку, перевірте її в Oracle SQL sheet Interprise? Якщо вона там не йде, марно посилати її через ФОКС. Ніколи б не давав би цієї ради, якби не бачив десятки разів, як проблему з посилкою команди годинами шукають в Фокса.

  2. На відміну від MS SQL Server виклик процедури Оракл не породжує жодних курсорів на клієнтській частині ФОКСПРО. Це тому, що він не пораждает їх і в самому Оракл. Їх результат іноді повертається в змінні Оракл. Щоб дізнатися, що змінилося на сервері, пошліть на сервер соответсвующй SQL select command Між іншим, на відміну від MS SQL server, де досить послати тільки ім’я процедури, виклик процедури Оракл складніший і має вигляд. sqlexec(con,’begin demo.procname; end;’) Деякі Оракл процедури працюють зі змінними Оракл типу in-out, тобто пременно, які передаються в процедуру, там змінюються і змінене значення повертається з процедури, Якщо передати значення в процедуру з клієнтської сторони нічого не коштує, наприклад через знак питання, отримати їх змінилися значення на клієнті дуже складно. Наприклад
    m.var='first value'
    sqlexec(con,'declare vr=?m.var begin demo.procname(vr) ; end ; select vr from dual ;')

    Мінлива повернеться до нас на ФОКС в курсорі, породженому другою частиною команди. Тільки там її і можна дістати.

  3. Всі об’єкти Оракл-таблиці, процедури, тригера, функції живуть там всередині так званих схем. Схема співпадає з ім’ям користувача, заведши ці об’єкти на Оракл. Оскільки з клієнтською сторонимогут працювати користувачі з різними іменами, звернення до цих об’єктів повинно включати ім’я схеми. Наприклад [sqlexec(con,'select demo.tr() from dual')],
    Оскільки в Оракл нелльзя викликати SQL пропозицію без імені таблиці, а у виклику Оракл функцій таких може не бути, ім’я не існуючої таблиці замінюється dual
    sqlexec (con, ‘select sysdate from dual’) породить на Фокса курсор з системною датою.
    Приклад-виклик функції
    Sqlexec(con,’select demo.func(1) as rtval from dual’)
    Часто на Оракл заводять одні й ті ж об’єкти в різних схемах, однією для тестування ще не готовою програми, інші для бойової роботи. Ми можемо на цей випадок у файлі ФОКС config.fpw помістити ім’я схеми і підставляти його в Фокса при виклику серверних команд.
    m.sql = ‘insert into’ + schema + tablename (fieldnames) values ​​(values) У професійному посібнику ФОКС є рада-зробіть клієнтську програму на фоксовскіх таблицях, зробіть на них локальні уявлення, отладте програми та майстром upsize імпортуйте таблиці на сервер а локальні подання у віддалені. З моєї точки зору це казка про білого бичка, таблиці звичайно так можна на Оракл поцупити, але працювати все буде дуже дуже повільно і купу проблем зовсім не вирішити. Перевірте самі. Створіть віддалене уявлення на Оракл і його прямий виклик через sqlexec, заміряйте час виконання-велика різниця. Не забудьте налаштувати фокс на роботу з поділюваним з’єднанням, а інакше будь віддалене уявлення викличе свою коннекцію і всі вони витратяться.

  4. Зазвичай Оракл сервер (куплений він чи вкрадений) розрахований на певне число коннекцій, що у випадку покупки робить прямий вплив на його ціну. А користувачів хочеться посадити побільше. Тому бідним і слаборозвиненим зразок нас Росіян варто поборотися за коннекціі. Просте спостереження показує, що в багатьох користувацьких інтерфейсах люди вибачте за непристойні подробиці) вводять і редагують дані і витрачають на це досить багато часу. Їх коннекціей інші клієнти в цей час могли б скористатися , Щоб послати або отримати що або з сервера. Взагалі не слід тримати коннекцію відкритими без необхідності. При роботі з обмеженим числом коннекцій і закриттям їх коли вони не потрібні, при їх запиті потрібно передбачити ситуацію з тим, що в даний момент коннекціі немає, і її потрібно почекати.
    sqlsetprop(0,'DispLogin',3)
    do while sqlconnect('poracle','username','userpassword')<0
    aerror(err)
    if err [1] = 1526 and err [4] = 8008! чекаємо коннекцію деякий час
    endif
    enddo
    Іноді виклик команди або процедур Оракл може йти довго. Таку коннекцію закрити не можна. Тому порада така. На цей випадок завести особливу, довго не закривається коннекцію . Відомі мені люди називають такуюстратегію-півтори коннекціі. Одна коннекція є, а інша то є, а то ні. Такий фокус де роблять при виклику асинхронної команди. Коротку в часі команду посилаємо з синхронного протоколу, отримуємо результат, а довге в часі посилаємо по асинхронному протоколу, і час від часу перевіряємо, є Чи від неї результат. .

  5. Завдання присвоєння значень первинних ключів існує для будь-якої бази даних. У Оракл для цієї та інших цілей є спеціальний о’ект-послідовність, що має первинне значени і приріст. Перше, що спадає на думку, щоб привласнити ізначеніе ключа і дізнатися його, наприклад, для присвоєння його в дитячій таблиці це код начебто нижче наступного
    sqlexec(con,' insert into schemaname.tablename (primaryfiledname, ..) values (schemaname.seqtablename.nextval,...)')
    sqlexec(con,'select schemaname. Seqtablename.curval as lstval from dual').
    Але тоді потрібно у всякій команді для всіх таблиць при додаванні записів пам’ятати значення послідовностей. Як мінімум потрібен якийсь автомат визначення імені послідовності по імені таблиці, поміщений в бібліотеку класів роботи з сервером, щоб при додаванні нових записів не турбується про присвоєння ключів. До того ж не дуже по науці обчислювати ключ на клієнті і посилати його назад на сервер. Можна зробити по іншому, написати на Фокса процедуру, яка піде за таблицями, заведе для кожної з них послідовність і посилається на неї тригер before insert, який автоматом при додаванні запису на сервері присвоїть там ключ. Залишиться його тільки повернути.
    Тригер може мати вигляд
    declare runval number ; begin select DEMO. seqtablename.nextval into
    runval from dual ; :new.CUSTOMER_ID:=runval ; insert into lstkey
    (tbname,lstval,ses_id) values (tbname,runval, userenv(sessionid));
    end ;

    Після створення нової запісізначеніе ключа можна дізнатися як select DEMO. seqtablename.curval from dual А можна вчинити по іншому Привласнення значення ключа можна зберігати в спец таблиці (в тригера ми це робимо), на зразок того, як ми робимо це в Фокса. Потрібно тільки відмітити, чий ключ якому клієнтові належить. Для цього можна застосувати Оракл змінну – У Оракл для цього є мінлива sessionid, унікальна для кожної коннекціі, навіть якщо кілька користувачів увійшли з однаковим ім’ям. А її дізнаються з функції userenv (sessionid)

  6. Оракл має одну чудову річ, Котара відсутнє під вного серверах і язикаж баз даних. Покладемо є таблиця з неопорядоченнимі записами, яких дуже багато. Хочеться отримати результат з обмеженим числом записів, але впорядкований.
    Дані потрібно спочатку впорядкувати в малій вибірці, а торлько потім повернути, не перші 100 записів, а перші 100 упорядкованих записів, скажімо клієнти за алфавітом. Адже Алексєєв може бути яким небудь десяти мільйонним.
    Ось тут то Оракл можна сказати-зроби мені вибірку по тому індексу, що в тебе є, а не у фізичному порядку записів. Не дістає тільки чого небудь, що обмежить кількість записів. Потрібно відзначити, що розробники машин тут на рідко “логічні” З першої до останньої сторінки керівництв вони втовкмачують нам у мізки, що на серверах немає поняття номер запису. Але самі біс кінця наштовхуються на введення чогось на зразок цього номера (або навіть декількох змінних) заднім числом. Оракл не виняток – rownum обмежить кількість записів.
    m.sql=m.sql+" SELECT DISTINCT "
    m.sql=m.sql+" /*INDEX(TICK IND_NUM) */"
    m.sql=m.sql+schema+"tick.NUM FROM "+schema+"tick "
    m.sql=m.sql+" WHERE rownum<=100 order by num"

    / * INDEX (TICK IND_NUM) * / – тут так званий хинт Оракл, який говорить серверу використовувати для упорядивачінія індекс а не таблицю. Номер запису вони сказати не хочуть. Але риса як не поминай, він все одно вилізе.

  7. Як зробити зовнішній джоін, тобто зв’язати таблиці, когдамежду німіне завжди є відповідність
    Select nvl(gdname,’ ‘) as gdname from demo.goodsln, demo.goods Where goodsln.gd_id=goods.gd_id(+)
    Таблиця з плюсом-зразок довідника, на який не завжди є посилання, але потрібно повернути всі записи основної таблиці, не залежно від того є там посилання на довідку чи ні.

  8. Хочеш не хочеш, а ось ще простецький приклад, коли потрібно щось на зразок номера запису, унікально її визначає. Хочеться дані з одного поля перетягнути в інше але в кожній запису. Цикл по записах делять не полювання, Ну що ж скористаємося змінної “rowid.” Ось тоді, як update змусить спрацювати “оптом”
    sqlexec(con,'update demo.table set fielda=(select fieldb from demo.table tb1 where table.rowid=tb1.rowid)')

  9. Ось питання, яке має значення не тільки для Оракл, а й для всіх серверів. Мені його часто в тому чи іншому вигляді задають. Тому ось відповідь
    У Фокса є два режими управління транзакціями сервера-явний і неявний. Їх Змішувати не можна-отримаєте дивні результати. Якщо у Вас sqlprop (‘transaction’, 1)-кожна Команда автоматично коммитет, якщо тільки ви самі не напишете sqlexec (con, ‘begin transaction’) команди sqlexec (con, ‘Commit’)
    Але якщо у Вас sqlprop (‘transaction’, 2) То для завершення транзакції треба писати sqlcommit (con)
    ‘Begin transaction’ і sqlexec (con, ‘Commit’) писати всередині такої установки не слід.

  10. У Оракл ціла купа функцій і команд, які не згадаєш, тому витратьте час на те, чтобви перенести їх виклик у відповідні методи бібліотек на Фокса. Заощадите час.

  11. Серед прикладів, які поставляються з ФОКС є клас, який залазить до реєстру (registry.prg), Він зокрема на ім’я ОДБС може дізнатися який сервер мається на увазі, і скористатися цим для написання гілок
    серверочувствітельного коду.

  12. Якщо хочете, щоб запити на Оракл працювали швидко-побудуйте для вхідних в них змінних індекси. На великих вибірках різниця в сотні разів. Всі про це знають, але не всі роблять.

  13. Ну це не порада, а хакерський трюк начебто фокуса.
    Ми знаємо, що віддаленої уявлення можна зробити updateble А результати sqlexec немає і відредаговані дані потрібно нести на сервер самим. Але другий спосіб швидше працює і для великих випадків годиться. Виявляється можна схрестити коня і трепетну лань разом Зробимо віддалене уявлення на Оракл і зробимо його updateble Запустимо на нашу базу даних процедуру gendbc і видерем весь код після визначення уявлення. Тепер пошлемо команду sqlexec із запитом подання на сервер, а отримавши на фоксовской стороні запустимо той шматок, що видерли з коду Тепер змінимо що небудь у курсорі. Гляньте тепер на сервер-наші зміни там без комманд і згадки полів!!

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*