|
|
|||||||||||||||||||||||||||||
|
Немного о Pro*C...Источник: ln
Основы Pro*CТом! Как лучше всего научиться программировать на Pro*C тому, кто хорошо знает язык C. Почему может потребоваться использовать именно Pro*C, а не PL/SQL? Ответ Тома КайтаНадо хорошо знать C, прежде чем использовать Pro*C. Pro*C просто позволяет встраивать SQL в код на языке C. Если вы не умеете программировать на C, хороших результатов в Pro*C вы не достигнете. Я использую pro*c только когда не могу эффективно решить задачу в PL/SQL или SQL. В 9i, при наличии внешних таблиц, merge, потоковых функций, - мне очень нелегко найти причину для использования C. Я использовал pro*c для сброса данных в текстовые файлы и, иногда, для загрузки данных. Пример программы
Ответ Тома КайтаЗдесь: http://asktom.oracle.com/~tkyte/proc_makefile/ можно найти простой makefile для Unix-систем, работающий практически для всех версий Oracle, начиная с 7. Вам нужны: Версия Pro-cПривет, Том! У меня есть сомнения в отношении ProC, и мне нужна товя помощь! У нас есть 2 сервера и 2 клиента: a) Сервер A с Oracle8i и сервер B с Oracle9i Я создаю приложение на C с использованием ProC. Приложение должно обращаться к базам данных на серверах 8i и 9i. Я не понимаю: 1) Какую версию ProC я должен использовать: 8i или 9i? 2) Если я создам два приложения: App8i и App9i, с помощью ProC 8i и Proc 9i, соответственно, смогу ли я без проблем использовать их оба на любой клиентской машине? Ответ Тома Кайта1) Это зависит от клиентского программного обеспечения на машине, где должен работать прекомпилятор pro*c. 2) Да, поскольку на клиентах можно устанавливать несколько версий ПО Oracle. Надо только убедиться, что для каждой версии правильно установлена ORACLE_HOME. Еще о Pro*C...Мое приложение app8i.exe (C и ProC 8i) обращается к базе данных Oracle9i. Я выполняю это приложение на клиенте 9i, но оно не работает. Приложение требует .dll-файлы Oracle8i (например: oraclient8.dll, oranls8.dll,...). Для выполнения app8i.exe на клиенте 9i, мне что, нужны dll-файлы Oracle8i? Ответ Тома КайтаНет. Вот это: Для выполнения app8i.exe на клиенте 9i, мне что, нужны dll-файлы Oracle8i? неверно (фактически, вопрос весьма хитрый). НЕЛЬЗЯ запускать клиентское приложение 8i в среде клиентского ПО 9i. Для выполнения app8i.exe вам НЕОБХОДИМ клиент 8i -- клиент 9i может тоже быть установлен на этой машине, но это не важно. Для запуска клиентских приложений 8i нужен клиент 8i. Pro*C для написания программ на CМожно ли использовать Pro*C для написания любой программы. которую можно написать на C? Ответ Тома КайтаPro*c - это "больше, чем" C, поскольку, фактически, pro*c - это C со встроенными SQL-операторами. Pro*c - это прекомпилятор , который берет код вида: { ... exec sql open c; exec sql fetch c into :n; .... printf( "n = %d\n", n ); } и превращает его в 100% C. Подключение из C-программы к серверу Oracle9iУ меня есть C-программа, с помощью которой я должен вставить подвергающиеся (сложной) обработке данные (скажем, переменную x в столбец x таблицы xx) в базу данных Oracle 9i. Я (к сожалению) не знаю Oracle и должен предоставить свою программу для тестирования нашему АБД Oracle в ближайшее время. Пожалуйста, скажите, какую строку подключения или драйвер я должен использовать для подключения к серверу и выполнения SQL-оператора insert. Ответ Тома КайтаНадо немного выучить proc. Вот этого будет достаточно: main( argc, argv ) int argc; char * argv[]; { EXEC SQL BEGIN DECLARE SECTION; varchar oracleid[31]; int x; EXEC SQL END DECLARE SECTION; strcpy( oracleid.arr, "scott/tiger@foo" ); oracleid.len = strlen(oracleid.arr); EXEC SQL WHENEVER SQLERROR DO sqlerror_hard(); EXEC SQL CONNECT :oracleid; printf("\nConnected to ORACLE as user: %s\n\n", oracleid.arr); x = really_complex_calculation(); exec sql insert into xx ( x ) values ( :x ); /* Disconnect from ORACLE. */ /* EXEC SQL COMMIT WORK RELEASE; */ exit(0); } Но...После написания представленного выше кода, как его вызывать? Насколько я понимаю, его надо прекомпилировать с помощью прекомпилятора, поставляемого Oracle, а затем скомпилировать поддерживаемым компилятором C. Но как потом вызывать полученный выполняемый файл? В частноcти, можно ли его вызвать из кода pl/sql или sql (как внешнюю процедуру, вероятно)? Или идея этого кода на pro*c в том, чтобы его вызывали отдельно/независимо из командной строки ОС или из приложения? Мне кажется, я не понимаю, зачем нужен pro*c... Ответ Тома КайтаВ результате получится утилита командной строки, подходящая, скажем, для сравнительно быстрой выгрузки больших объемов данных. Она не может быть вызвана непосредственно из plsql (Хотя ничего не мешает сделать из него внешнюю процедуру и вызывать ее. Если у вас есть моя книга "Expert one on one Oracle" - в ней я достаточно детально описываю, как это сделать.) Можно ли сделать код более безопасным?Вы представлили фрагмент кода на Pro*C, очень похожий на тот, что и мы используем в своем приложении для сервера версии 8.1.7. Однако мне не нравится то, что строка подключения жестко задана и выдается на экран. Я хочу, чтобы наши разработчики перешли на аутентификацию операционной системой. Они не хотят разбираться, как это делать, поэтому я хочу спросить об этом у вас. Как это сделать? Ответ Тома Кайтаstrcpy( oracleid.arr, "/" ); и все... Ошибка компоновщикаЯ пытаюсь научиться использовать язык C для Oracle. Я написал одну простую программу: #include <stdio.h> #include <ctype.h> EXEC SQL BEGIN DECLARE SECTION; VARCHAR uid[20]; VARCHAR pwd[20]; EXEC SQL END DECLARE SECTION; EXEC SQL INCLUDE SQLCA; main() { printf("ENTER USER-NAME:"); scanf("%s",uid.arr); printf("ENTER PASSWORD:"); scanf("%s",pwd.arr); uid.len=strlen(uid.arr); pwd.len=strlen(pwd.arr); EXEC SQL WHENEVER SQLERROR GOTO errproc; EXEC SQL CONNECT :uid IDENTIFIED BY :pwd; printf("CONNECTED TO ORACLE.\n"); exit(0); errproc: printf("erroro occured.\n"); exit(1); } и скомпилировал ее с помощью pro C. Затем я скомпилировал полученный C-файл (corc1) с помощью компилятора C, и все прошло без предупреждений. Но при попытке скопоновать выполняемый файл, я получаю следующее отвратительное сообщение об ошибке: linking C:\turboC2\CORC1.exe linker error: undefined symbol '_sqlcxt' in module corc1.c Не могли бы вы помочь понять, в чем причина? Ответ Тома КайтаНеобходимо скомпоновать библиотеки, которые ребуются для pro*c. Посмотрите примеры файлов makefile. Когда я последний раз использовал windoze (во времена версии 816) - использовалась билиотека %ORACLE_HOME%\precomp\lib\msvc\orasql8.lib, вместо 8 теперь может быть что-то другое - поищите. Отладка Pro*cПривет, Том!, Ответ Тома КайтаИдея решения представлена здесь. c или c++Я начал изучать язык c++ для разработки приложений, да и чтобы использовать pro*c++ надо выучить c++. Меня интересует, надо ли использовать чистый C для Pro*c или все, что можно сделать на C, можно и на C++? С точки зрения Pro*c/c++, конечно. Ответ Тома КайтаПочти все можно сделать на C++, хотя есть и ряд ограничений pro*c, таких как установка PARSE= в командной строке, которые требуют использования определенных конструкций (например, необходимо использовать теги exec sql begin/end declare section и т.п.) Множественная вставка, выборка, изменение и удаление данных в Pro*c
Ответ Тома Кайта1) proc .... prefetch=100 - один способ. А здесь описан другой. 2) Да, нет, может быть - это зависит... (Обычно, да по моему опыту, но главное придерживаться здравого смысла. Если ваша бизнес-логика требует вычисления собственного вектора для набора значений, на C это может быть сделано быстрее. Если вы просто проверяете, что A > B+5, лучше использовать PL/SQL) Если можно использовать хранимую процедуру, чтобы избежать выборки данных из базы (по сети), простой обработки и последующей вставки обратно - PL/SQL отлично подойдет. Пример множественного обновленияНе могли бы вы представить пример множественного обновления в Pro*C? Ответ Тома КайтаПосмотрите в каталоге $ORACLE_HOME/precomp/demo/proc, там есть примеры. Кроме того, все это подробно описано в документации. Вопрос об использовании sys_refcursor в PRO*CВ программе на PRO*C мне нужно вызвать хранимую процедуру на PL/SQL, у которой есть выходной параметр типа sys_refcursor. Как мне это сделать? Если это невозможно, что мне делать? (Процедура использует этот параметр потому, что он используется для возврата нескольких строк запроса). Ответ Тома КайтаSQL*Plus: create or replace procedure proc( p_cursor in out sys_refcursor ) as begin open p_cursor for select ename, empno from emp; end; / Pro*C: static void process() { EXEC SQL BEGIN DECLARE SECTION; char ename_data[31] ; int empno_data ; SQL_CURSOR dyn_cursor; EXEC SQL END DECLARE SECTION; EXEC SQL ALLOCATE :dyn_cursor; EXEC SQL EXECUTE BEGIN proc( p_cursor=>:dyn_cursor ); END; END-EXEC; EXEC SQL WHENEVER NOT FOUND DO BREAK ; while (SQLCODE == 0) { EXEC SQL FETCH :dyn_cursor INTO :ename_data, :empno_data; printf("Ename = %s Empno = %d\n", ename_data, empno_data) ; } EXEC SQL WHENEVER NOT FOUND CONTINUE; EXEC SQL CLOSE :dyn_cursor; } ПроблемаТом! ORA-12805: parallel query server died unexpectedly Для открытия курсора и извлечения записей я использую следующий код: EXEC SQL CONTEXT USE DEFAULT; EXEC SQL WHENEVER SQLERROR DO err_report(sqlca); EXEC SQL OPEN OpnCursor USING :x:indx; /* Ошибка выдается при выполнении предыдущего оператора. */ EXEC SQL WHENEVER NOT FOUND DO break; for (;;) { memset(rec, '\0', sizeof(rec)); EXEC SQL FETCH OpnCursor INTO :rec INDICATOR :indRec; . . . Не мог бы ты подсказать, почему возникает эта ошибка и как с этим разобраться? Ответ Тома КайтаПо поводу таких вещей обращайтесь в службу технической поддержки. Файл pcscfg.cfgЯ только что учтановил Oracle 8.1.7 на Mandrake 9.1. Я хочу собрать первую свою программу на Pro*C (просто с помощью "proc my_program.pc", не используя никакой makefile). Я создал следующий файл pcscfg.cfg (после установки он был пустой): sys_include=($ORACLE_HOME/precomp/public,/usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.2.2/include,/usr/include) include=($ORACLE_HOME/precomp/public) include=($ORACLE_HOME/rdbms/demo) При попытке выполнить прекомпиляцию я получаю следующее: ................. Syntax error at line 43, column 9, file /usr/lib/g cc-lib/i586-mandrake-linux-gnu/3.2.2/include/stdarg.h: Error at line 43, column 9 in file /usr/lib/gcc-li b/i586-mandrake-linux-gnu/3.2.2/include/stdarg.h typedef __builtin_va_list __gnuc_va_list; ........1 PCC-S-02201, Encountered the symbol "__builtin_va_list" when expecting one of the following: auto, char, const, double, enum, float, int, long, ulong_varchar, OCIBFileLocator OCIBlobLocator, OCIClobLocator, OCIDateTime, OCIExtProcContext, OCIInterval, OCIRowid, OCIDate, OCINumber, OCIRaw, OCIString, register, short, signed, sql_context, sql_cursor, static, struct, union, unsigned, utext, uvarchar, varchar, void, volatile, a typedef name, The symbol "enum," was substituted for "__builtin_va_list" to continue. ....................... и еще масса ошибок в том же духе. Не подскажете, в чем причина? Ответ Тома КайтаМы не относим mandrake к поддерживаемым дистрибутивам linux. Поддерживаются RedHat and United (Conectiva Linux Enterprise Edition, SuSE Linux Enterprise Server 8 (SLES 8), Turbolinux Enterprise Server 8 Advanced и Basic). Вопрос читателя от 8 января 2004 годаВы используете "окна" (windows)? Ответ Тома КайтаНет. Ну, я часто смотрю через окна (у меня возле дома - кормушка для птиц, там много красивых птиц), но как программное обеспечение для компьютера - нет. Ссылки по теме
|
|