(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Немного о 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 для сброса данных в текстовые файлы и, иногда, для загрузки данных.

Пример программы

  1. Не мог бы ты показать очень простую программу на Pro*C.
  2. Что нужно для ее сборки.

Ответ Тома Кайта

Здесь:

http://asktom.oracle.com/~tkyte/proc_makefile/

можно найти простой makefile для Unix-систем, работающий практически для всех версий Oracle, начиная с 7.

Вам нужны:
a) прекомпилятор proc
b) компилятор C, поддерживаемый операционной системой

Версия Pro-c

Привет, Том!

У меня есть сомнения в отношении ProC, и мне нужна товя помощь! У нас есть 2 сервера и 2 клиента:

a) Сервер A с Oracle8i и сервер B с Oracle9i
b) Машина C с клиентом Oracle8i и машина D с клиентом Oracle9i

Я создаю приложение на C с использованием ProC. Приложение должно обращаться к базам данных на серверах 8i и 9i. Я не понимаю:

1) Какую версию ProC я должен использовать: 8i или 9i?
Версия зависит от базы, к которой обращается приложение, или от клиента, на котором приложение работает?

2) Если я создам два приложения: App8i и App9i, с помощью ProC 8i и Proc 9i, соответственно, смогу ли я без проблем использовать их оба на любой клиентской машине?

Ответ Тома Кайта

1) Это зависит от клиентского программного обеспечения на машине, где должен работать прекомпилятор pro*c.
8i pro*c может обращаться к 8i и 9i
9i pro*c может обращаться к 8i и 9i

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

Привет, Том!,
В моей программе на pro*c есть оператор insert. При выполнении в качестве параметров передаются недопустимые значения. Например, символьноре значение как параметр для столбца типа number. Нет ли способа найти конкретный столбец в операторе insert, в котором оказалось недопустимое значение.

Ответ Тома Кайта

Идея решения представлена здесь.

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. Возможна ли множественная вставка, выборка, изменение и удаление данных в Pro*C? Если да, не могли бы вы представить пример?
  2. Даст ли повышение производительности помещение бизнес-логики в хранимую процедуру и ее вызов из Pro*c по сравнению с ее реализацией непосредственно в 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;
}

Проблема

Том!
У меня есть запрос с соединением четырех таблиц, в каждой из которых - порядка 100 миллионов строк данных, а результат запроса - около 600000 записей. Но при открытии курсора в Pro C я получаю слендующее сообщение об ошибке.

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)?

Ответ Тома Кайта

Нет.

Ну, я часто смотрю через окна (у меня возле дома - кормушка для птиц, там много красивых птиц), но как программное обеспечение для компьютера - нет.

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 08.04.2010 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Oracle Database Personal Edition Named User Plus Software Update License & Support
Oracle Database Standard Edition 2 Named User Plus License
Oracle Database Personal Edition Named User Plus License
Oracle Database Standard Edition 2 Processor License
SAP® Crystal Reports 2016 WIN INTL NUL
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
СУБД Oracle "с нуля"
Все о PHP и даже больше
ЕRP-Форум. Творческие дискуссии о системах автоматизации
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100