|
Программирование >> Oracle
Внешние процедуры на языке С 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 \
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |