Программирование >>  Oracle 

1 ... 306 307 308 [ 309 ] 310 311 312 ... 469


Внешние процедуры на языке С 1341

raise application error (myCtx,

ERROR FILENAME IS NULL,

Функции lobToFile передано пустое имя файла или каталога; ->недостый аргумент ) ; }

Теперь откроем файл. Мы открываем его на запись в двоичном режиме. Мы хотим просто сбросить байты из базы данных в файл.

else if (OCIFileOpen(myCtx->envhp, myCtx->errhp, &output, filename,path,

OCI FILE WRITE ONLY, OCI FILE CREATE, OCI FILE BIN) != OCI SUCCESS)

raise application error(myCtx,

ERROR OPEN FILE, Ошибка открытия файла %s ,

lastOciError(myCtx));

else

debugf(myCtx, lobToFile(filename => %s%s, lob => %X) , path, filename, blob) ;

Теперь мы будем читать большой объект с помощью средств Рго*С методом без опроса (non-polling). Это важно, поскольку опрашивать большой объект во внешней процедуре нельзя. Таким образом, мы никогда не запросим больше данных, чем можем получить в одном вызове (non-polling). Мы начинаем со смещения 1 (с первого байта) и будем читать по BUFSIZE байтов за раз (64 Кбайт в данном случае). Каждый раз увеличивая смещение на прочитанное количество байтов, мы выйдем из цикла только когда считано будет столько байтов, сколько запрошено - это будет означать, что прочитан весь большой объект.

for( offset = 1, amt = buffsize; amt = buffsize; offset += amt )

debugf(myCtx,

Попытка прочитать %d байт из большого объекта , amt) ; EXEC SQL LOB

READ :amt

FROM :blob AT :offset INTO :data

WITH LENGTH :buffsize;

Проверяйте вcе возможные ошибки - при их возникновении в]давайте cобcтвен-сообщения об ошибках в стек ошибок среды PL/SQL.

Обратите внимание, как мы освобождаем все использованные ресурсы (открытый файл) перед завершением работы. Это важно. По возможности, надо предотвращать



1342

Глава 18

утечку ресурсов. Для этого мы возвращаем управление только в одном месте (ниже) и перед этим вызываем функцию term:

if (sqlca.sqlcode < 0) break;

if (writeToFile(myCtx, output, data.buf, amt, &bytesWritte break;

Осталось закрыть файл и вернуть управление:

if (output != NULL)

debugf(myCtx, Закончили запись и закрываем файл ) ; OCIFileClose(myCtx->envhp, myCtx->errhp, output);

*return indicator = OCI IND NOTNULL;

debugf(myCtx,

Возвращаем значение %d как количество прочитанн1х байтов , bytesWritten) ;

term(myCtx) ;

return bytesWritten;

Создание внешней процедуры

Процесс создания библиотеки lobtofile почти совпадает с рассмотренным ранее для библиотеки demo passing. Универсальный файл управления проектом (make-файл) использовался как в среде Windows, так и в ОС UNIX с минимальными изменениями. В Windows мы используем:

CPU=i386

MSDEV = c:\msdev

ORACLE H0ME = c:\oracle

!include <$(MSDEV)\include\win32.mak>

TGTDLL = extproc.dll OBJS = lobtofile.obj

NTUSER32LIBS = $(MSDEV)\lib\user32.lib \ $ (MSDEV)\lib\msvcrt.lib \ $(MSDEV)\lib\oldnames.lib \ $(MSDEV)\lib\kernel32.lib \ $(MSDEV)\lib\advapi32.lib

SQLLIB = $(0RACLE H0ME)\precomp\lib\msvc\orasql8.1ib \ $(ORACLE HOME)\oci\lib\msvc\oci.lib

INCLS = -I$(MSDEV)\include \

-I$(ORACLE HOME)\oci\include \



Внешние процедуры на языке С 1343

CFIAGS = $(INCLS) -DWIN32 -DWIN NT -D DLL

all: $(TGTDLL)

clean:

erase *.obj *.lib *.exp lobtofile.c

$(TGTDLL): $(OBJS)

$(link) -DLL $(dllflags) \

/NODEFAULTLIB:LIBC.LIB -out:$(TGTDLL) \

$(OBJS) \ $(NTUSER32LIBS) \

${SQLLIB) \

lobtofile.c: lobtofile.pc proc \

lnclude=$(ORACLE HOME)\network\public \ include=$(ORACXE HCME)\proc\lib \ include=$(ORACLE HCME)\rdbnis\deroo \ lnclude=$(ORACLE HCME)\oci\lnclude \ include=$(MSDEV) \include \ lines=yes \ parse=full \ iname=lobtofile.pc

Изменения выделены полужирн1м шрифтом. Было изменено имя компонуемого объектного файла и добавлено правило для автоматического преобразования lobtofile.pc в lobtofile.c. Вызванному прекомпилятору Рго*С мы сообщаем, где находятся заголовоч-н1е файлы (INCLUDE=), что номера строк следует сохранить в полученном .с-файле (lines=yes), что требуется проанализировать код на языке С (parse=full) и что имя преобразуемого файла - lobtofile.pc (iname=). Теперь осталось выполнить команду nmake, и DLL-библиотека будет создана.

В ОС UNIX make-файл имеет следующий вид:

MAKEFILE= $(ORACLE HOME)/rdbms/demo/demo rdbms.mk

INCLUDE= -I$(ORACLE HOME)/rdbms/demo \

-I$(ORACLE HOME)/rdbms/public \ -I$(ORACLE HOME)/plsql/public \

-I$(ORACLE HOME)/network/public

TGTDLL= extproc.so OBJS = lobtofile.o

all: $(TGTDLL)

clean:

rm *.o

lobtofile.c: lobtofile.pc proc \

include=$(ORACLE HOME)/network/public \ include=$(ORACLE HOME)/proc/lib \ include=$(ORACLE HOME)/rdbms/deino \ include=$(ORACLE HOME)/rdbms/public \



1 ... 306 307 308 [ 309 ] 310 311 312 ... 469

© 2006 - 2025 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика