Oracle External Procedure Calls Теодор Иванов Софтуерен инженер.

Slides:



Advertisements
Similar presentations
C: Advanced Topics-II Winter 2013 COMP 2130 Intro Computer Systems Computing Science Thompson Rivers University.
Advertisements

Echo server The client reads a line of text from its standard input and writes the line to the server The server reads the line from its network input.
Numerical Recipes The Art of Scientific Computing (with some applications in computational physics)
STRING AN EXAMPLE OF REFERENCE DATA TYPE. 2 Primitive Data Types  The eight Java primitive data types are:  byte  short  int  long  float  double.
USERSPACE I/O Reporter: R 張凱富.
Указатели, масиви и структури Доц. д-р Владимир Димитров Web: cht_co.tripod.com Wap:
Programming Languages and Paradigms The C Programming Language.
Character String Manipulation. Overview Character string functions sscanf() function sprintf() function.
Character String Manipulation. Overview Character string functions sscanf() function snprintf() function.
Array_strcpy void array_strcpy(char dest[], char src[]) { int i = 0; while (src[i] != '\0') { dest[i] = src[i]; i++; } dest[i] = '\0'; }
SPLINT STATIC CHECKING TOOL Sripriya Subramanian 10/29/2002.
C Intro.
University of Washington Today Midterm grades posted  76. HW 3 due Lab 4 fun! 1.
Zombie and orphan processes. Zombie process (from wikipedia) When a process ends, all of the memory and resources associated with it are deallocated.
#.1 SQL*Net Kyle Hailey http//ashmasters.com/
Unix Continuum of Tools Do something once: use the command line Do something many times: –Use an alias –Use a shell script Do something that is complex.
Declaring Arrays Declare an array of 10 elements: int nums[10]; Best practice: #define SIZE 10 int nums[SIZE]; // cannot be int[SIZE] nums; C99: int nums[someVariable]
Harvard University Oracle Database Administration CSCI E256 Session 7 Oracle Networking.
C Slides and captured lecture (video and sound) are available at:
1 Intro to C/C++ #include using namespace std; int main() { cout
An Introduction to C Programming (assuming that you already know Java; this is not an introduction to C++)
INTRODUCTION TO ORACLE Lynnwood Brown System Managers LLC Client-Server – Lecture 4 Copyright System Managers LLC 2007 all rights reserved.
Oracle for Software Developers. What is a relational database? Data is represented as a set of two- dimensional tables. (rows and columns) One or more.
5 Copyright © 2008, Oracle. All rights reserved. Configuring the Oracle Network Environment.
5 Copyright © 2007, Oracle. All rights reserved. Configuring the Oracle Network Environment.
12 Copyright © 2004, Oracle. All rights reserved. Oracle Net Services.
CAP6135: Malware and Software Vulnerability Analysis Buffer Overflow : Example of Using GDB to Check Stack Memory Cliff Zou Spring 2011.
Introduction to Computer Organization & Systems Topics: Intro to UNIX COMP John Barr.
CS 3630 Database Design and Implementation. Your Oracle Account UserName is the same as your UWP username Followed Not case sensitive Initial.
6 Copyright © 2009, Oracle. All rights reserved. Configuring the Oracle Network Environment.
Creating and Executing Processes
SQL*Net & Other Waits. #.2 Copyright 2006 Kyle Hailey Network Redo Lib Cache Buffer Cache IO Locks Network.
C What you Know* Objective: To introduce some of the features of C. This assumes that you are familiar with C++ or java and concentrates on the features.
CS 241 Section Week #2 9/9/10. 2 Topics This Section MP1 issues MP2 overview Process creation using fork()‏ Debugging tools: valgrind, gdb.
3 Copyright © 2004, Oracle. All rights reserved. Controlling Access to the Oracle Listener.
C By Example 1 The assumption is that you know Java and need to extend that knowledge so you can program in C. 1. Hello world 2. declarations 3. pass by.
Getting Started UNIX InKwan Yu Topics Unix Commands Unix System calls C function calls.
OPERATING SYSTEMS 1 - HARDWARE PIETER HARTEL 1. Hardware 2.
Functions & Pointers in C Jordan Erenrich
Arrays, Strings, and Memory. Command Line Arguments #include int main(int argc, char *argv[]) { int i; printf("Arg# Contents\n"); for (i = 0; i < argc;
Gramming An Introduction to C Programming (assuming that you already know Java; this is not an introduction to C++)
IWR Ideen werden Realität Forschungszentrum Karlsruhe in der Helmholtz-Gemeinschaft Institut für Wissenschaftliches Rechnen Oracle Network Configuration.
External Routines Oracle Database PL/SQL 10g Programming Chapter 12.
Multi-dimensional Arrays and other Array Oddities Rudra Dutta CSC Spring 2007, Section 001.
Arrays and Pointers (part 2) CSE 2031 Fall March 2016.
Basic Oracle Net Services Client-Side Configuration
1 Unix system calls fork( ) wait( ) exit( ). 2 How To Create New Processes? n Underlying mechanism -A process runs fork to create a child process -Parent.
CAP6135: Malware and Software Vulnerability Analysis Buffer Overflow : Example of Using GDB to Check Stack Memory Cliff Zou Spring 2014.
Revisiting building. Preprocessing + Compiling 2 Creates an object file for each code file (.c ->.o) Each.o file contains code of the functions and structs.
Programming in C Project Organization Compiler Directives.
SaaS Cloud Platform Providing Database Access Through RESTful API Learning & Development Telerik Software Academy.
1 Intro to the Shell with Fork, Exec, Wait Sarah Diesburg Operating Systems CS 3430.
An Introduction to C Programming (assuming that you already know Java; this is not an introduction to C++)
Java Programming: JDBC Vyacheslav Grebenyuk CTDE, AI dept., KhNURE.
Buffer Overflow By Collin Donaldson.
A bit of C programming Lecture 3 Uli Raich.
Command line arguments
An Introduction to C Programming
CS 537 Section 1 Programming in Unix and C
Cs288 Intensive Programming in Linux
null, true, and false are also reserved.
نوع داده هاي انتزاعي Abstract Data Types
C What you Know* Objective: To introduce some of the features of C. This assumes that you are familiar with C++ or java and concentrates on the features.
Programming in C Miscellaneous Topics.
Programming in C Miscellaneous Topics.
CAP6135: Malware and Software Vulnerability Analysis Buffer Overflow : Example of Using GDB to Check Stack Memory Cliff Zou Spring 2015.
C By Example The assumption is that you know Java and need to extend that knowledge so you can program in C. 1. Hello world 2. declarations 3. pass.
Strings #include <stdio.h>
Programming Languages and Paradigms
CAP6135: Malware and Software Vulnerability Analysis Buffer Overflow : Example of Using GDB to Check Stack Memory Cliff Zou Spring 2013.
Presentation transcript:

Oracle External Procedure Calls Теодор Иванов Софтуерен инженер

2 Oracle Documentation Oracle Course Oracle Database 10g: Advanced PL/SQL D17220GC10&p_org_id=1001&lang=US&source_call= Помощ от приятел … Как да се научим да използваме EPC

3 Моят подход... Oracle® Database SQL Reference 10g Release 1 (10.1), Part No. B PL/SQL User's Guide and Reference 10g Release 1 (10.1), Part No. B Oracle® Data Cartridge Developer's Guide 10g Release 1 (10.1), Part No. B Implementing Data Cartridges in C, C++ and Java

4 Моят подход... Oracle® Database Application Developer's Guide – Fundamentals 10g Release 1 (10.1), Part Number B Programmatic Environments Overview of Pro*C/C++ Overview of OCI and OCCI Choosing a Programming Environment 8 Calling External Procedures

5 Моят подход... Oracle® Call Interface - Programmer's Guide 10g Release 1 (10.1), Part No. B Introduction and Upgrading 2. OCI Programming Basics 3. Datatypes 18. OCI Datatype Mapping and Manipulation Functions 19. OCI Cartridge Functions

6 Какво е Oracle EPC ? Начин да се използват функции от външни за Oracle RDBMS библиотеки (.lib,.so,.dll ) - SQL - PL/SQL - Java Oracle RDBMS C interface Java interface C procedures or functions Java procedures or functions

7 Кога се използва Oracle EPC ? Липса на функционалност в Oracle RDBMS или недостатачна ефективност на PL/SQL: Многократни сметки с плаваща запетая и работа с едномерни и многомерни масиви и указатели Описание или пресмятания, свързани със сложни информационни обекти – графи, матрици, и т.н. Използване на вече готови библиотеки Пълноценнo използване възможностите на операционната система

8 Как работи Oracle EPC ? Oracle RDBMS begin res := a_plus_b( a, b ); end; / PL/SQL SQL> select a_plus_b( a, b ) from dual; SQL PL/SQL function a_plus_b(…), sum_lib OCI network libraries, using tnsnames.ora Oracle Listener process LISTENER using listener.ora extproc agent $ORACLE_HOME/bin/extproc Library sum_lib, sum.so EXTPROC_CONNECTION_DATA using: EPC_IPC_KEY looking for: EPC_SID using: EPC_SID executing: extproc agent using: OS.so load calls: sum.so/a_plus_b_c() OS create or replace function a_plus_b( a in binary_integer, b in binary_integer ) return binary_integer is language C library sum_lib name "a_plus_b_c" parameters( a int, b int, return int ); / tnsnames.ora EXTPROC_CONNECTION_DATA = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = IPC)(KEY = EPC_IPC_KEY)) ) (CONNECT_DATA = (SID = EPC_SID) ) create or replace library sum_lib as '${ORACLE_HOME}/lib/sum.so'; / listener.ora SID_LIST_LISTENER = (SID_LIST =... (SID_DESC = (PROGRAM = extproc) (SID_NAME = EPC_SID) (ORACLE_HOME = /oracle/10.1) (ENVS = "EXTPROC_DLLS=ANY") ) LISTENER = (DESCRIPTION_LIST =... (DESCRIPTION = (ADDRESS = (PROTOCOL = IPC)(KEY = EPC_IPC_KEY)) ) $ORACLE_HOME/lib/sum.so a_plus_b_c() { … }

9 Как работи Oracle EPC ? - 2 Oracle RDBMS begin res := a_plus_b( a, b ); end; / PL/SQL SQL> select a_plus_b( a, b ) from dual; SQL PL/SQL function a_plus_b(…), sum_lib OCI network libraries, using tnsnames.ora Oracle Listener process LISTENER using listener.ora extproc agent $ORACLE_HOME/bin/extproc Library sum_lib, sum.so EXTPROC_CONNECTION_DATA using: EPC_IPC_KEY looking for: EPC_SID using: EPC_SID executing: extproc agent using: OS.so load calls: sum.so/a_plus_b_c() OS $ORACLE_HOME/lib/sum.so a_plus_b_c() { … }

10 Пример за EPC С функция epc_demo_func_c() и Linux библиотека epc_demo.so C Тест на функцията epc_demo_func_c Съдържание на tnsnames.ora Съдържание на sqlnet.ora Съдържание на listener.ora Oracle библиотека epc_demo_lib PL/SQL функция epc_demo_func() Тест на PL/SQL функцията epc_demo_func() makefile

11 Какво прави epc_demo_func() Приема два параметара: a - целочислено число s - символен низ ( стринг ) Ако а е NULL, тогава epc_demo_func() връща 0 Ако а не е NULL, тогава разпечатва стойностите на всички входящи за функцията параметри в стринг buff и връща стойността на buff в s, а epc_demo_func() връща стойността на a

12 PL/SQL библиотека и функция - epc_demo_func.sql create or replace library epc_demo_lib as '${ORACLE_HOME}/lib/epc_demo.so'; / create or replace function epc_demo_func( a in pls_integer, s in out varchar2 ) return pls_integer is language C library epc_demo_lib name "epc_demo_func_c" parameters( a int, a indicator, s string, s length by reference int, s maxlen by reference int, return int ); / exit при wrap на библиотеката, не може да се използва обращение към shell environment variables

13 Съответствие на PL/SQL и C параметрите PL/SQLPARAMETERSC epc_demo_func(parameters( int epc_demo_func_c( a in pls_integer, a int, a indicator, int a, short a_ind, s in out varchar2 s string, s length by reference int, s maxlen by reference int, char *s, int *s_length, int *s_maxlen ) return pls_integerreturn int ) )

14 С функция - epc_demo_func_c.c #include #include "oci.h" int epc_demo_func_c( int a, short a_ind, char *s, int *s_length, int *s_maxlen ) { // if a is NULL then return 0 if( a_ind == OCI_IND_NULL ) return( 0 ); продължава на следващият слайд...

15 продължение от предишният слайд... // prepare the new return value for s char buff[200]; sprintf( buff, "%s\na=%d, a_ind=%d, s='%s', s_length=%d, s_maxlen=%d", "C func epc_demo_func_c()\nreceived the following input paramters:", a, a_ind, s, *s_length, *s_maxlen ); // copy the prepared value into y strncpy( s, buff, *s_maxlen ); // set new s length *s_length = strlen( s ); // return the value of a return( a ); }

16 Тест на С функцията - epc_demo_func_c.c #ifdef TEST int main( int argc, char *argv[] ) { char ss[200] = { "123" }; int aa = -7, res = 0, ss_len = strlen( ss ), ss_maxl = sizeof( ss ) - 1; printf( "\nC test: begins\n\n" ); printf( "C test main(): will call C epc_demo_func_c() with parameters:\n" ); printf( "C test main(): not NULL a = %d\n", aa ); printf( "C test main(): and s = >>>%s<<<\n\n", ss ); res = epc_demo_func_c( aa, OCI_IND_NOTNULL, ss, &ss_len, &ss_maxl ); продължава на следващият слайд...

17 продължение от предишният слайд... printf( "C test main(): epc_demo_func_c() returns %d\n", res ); printf( "C test main(): and resulted s is >>>%s<<<\n", ss ); printf( "C test main(): and resulted s length is %d\n", ss_len ); printf( "\nC test: ends\n\n" ); return( 0 ); } #endif

18 Тест на PL/SQL функцията - epc_demo_func_test.sql set serveroutput on declare aa pls_integer := -7; ss varchar2( 200 ) := '123'; res pls_integer := 0; begin dbms_output.enable; dbms_output.put_line( chr( 10 ) || 'PL/SQL test: begins' || chr( 10 ) ); dbms_output.put_line( 'PL/SQL test: will call PL/SQL epc_demo_func() ' || || 'with parameters' ); dbms_output.put_line( 'PL/SQL test: not NULL a = ' || aa ); dbms_output.put_line( 'PL/SQL test: s = >>>' || ss || '<<<' || chr( 10 ) ); res := epc_demo_func( aa, ss ); dbms_output.put_line( 'PL/SQL test: epc_demo_func() returns ' || res ); dbms_output.put_line( 'PL/SQL test: and resulted s is >>>' || ss || '<<<' ); dbms_output.put_line( chr( 10 ) || 'PL/SQL test: ends' || chr( 10 ) ); end; /

19 Редактиране на tnsnames.ora Файлът се намира в $TNS_ADMIN или в $ОRACLE_HOME/network/admin EXTPROC_CONNECTION_DATA[.default_domain] = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = IPC)(KEY = EPC_IPC_KEY)) ) (CONNECT_DATA = (SID = EPC_SID) )

20 [.default_domain] Трябва да съответствува на стойността на: NAMES.DEFAULT_DOMAIN = semantec.bg от файла sqlnet.ora

21 Редактиране на listener.ora Спиране на лисънъра, редактиране на listener.ora и стартиране на лисънъра SID_LIST_LISTENER = (SID_LIST =... (SID_DESC = (PROGRAM = extproc) (SID_NAME = EPC_SID) (ORACLE_HOME = /oracle/10.1) (ENVS = "EXTPROC_DLLS=ANY") ) LISTENER = (DESCRIPTION_LIST =... (DESCRIPTION = (ADDRESS = (PROTOCOL = IPC)(KEY = EPC_IPC_KEY)) ) тези стойности трябва да съответстват на маркираните в зелено от tnsnames.ora

22 Тест на редактираните *.ora файловете ~]$ tnsping EXTPROC_CONNECTION_DATA.SEMANTEC.BG TNS Ping Utility for Linux: Version Production on 24-OCT :59:47 Copyright (c) 1997, 2003, Oracle. All rights reserved. Used parameter files: /oracle/10.1/network/admin/sqlnet.ora Used TNSNAMES adapter to resolve the alias Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = IPC)(KEY = EPC_IPC_KEY))) (CONNECT_DATA = (SID = EPC_SID))) OK (10 msec) ~]$ tnsping EXTPROC_CONNECTION_DATA TNS Ping Utility for Linux: Version Production on 24-OCT :59:51 Copyright (c) 1997, 2003, Oracle. All rights reserved. Used parameter files: /oracle/10.1/network/admin/sqlnet.ora Used TNSNAMES adapter to resolve the alias Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = IPC)(KEY = EPC_IPC_KEY))) (CONNECT_DATA = (SID = EPC_SID))) OK (10 msec)

23 makefile all: so test sql so ${ORACLE_HOME}/lib/epc_demo.so: epc_demo_func_c.c gcc -shared -o epc_demo.so epc_demo_func_c.c cp epc_demo.so ${ORACLE_HOME}/lib chmod 0755 ${ORACLE_HOME}/lib/epc_demo.so ls -l ${ORACLE_HOME}/lib/epc_demo.so test: epc_demo_func_c.c gcc -o epc_demo_func_c epc_demo_func_c.c -D TEST ls -l epc_demo_func_c./epc_demo_func_c sql: epc_demo_func.sql ${ORACLE_HOME}/lib/epc_demo.so sqlplus -S sqlplus -S

24 epc_demo]$ ls -l total 16 -rw-r--r-- 1 oracle users 449 Oct 23 19:58 epc_demo_func.sql -rw-r--r-- 1 oracle users 793 Oct 23 20:22 epc_demo_func_c.c -rw-r--r-- 1 oracle users 326 Oct 23 20:07 epc_demo_func_test.sql -rw-r--r-- 1 oracle users 456 Oct 23 20:57 makefile epc_demo]$ Файловете от примера за EPC

25 make test epc_demo]$./epc_demo_func_c C test: begins C test main(): will call C epc_demo_func_c() with parameters: C test main(): not NULL a = -7 C test main(): and s = >>>123<<< C test main(): epc_demo_func_c() returns -7 C test main(): and resulted s is >>>C func epc_demo_func_c() received the following input paramters: a=-7, a_ind=0, s='123', s_length=3, s_maxlen=199<<< C test main(): and resulted s length is 113 C test: ends gcc -o epc_demo_func_c -I /oracle/10.1/rdbms/public -D TEST epc_demo_func_c.c ls -l epc_demo_func_c -rwxr-xr-x 1 oracle users 6175 Oct 25 18:59 epc_demo_func_c

26 make sql epc_demo]$ sqlplus -S PL/SQL test: begins PL/SQL test: will call PL/SQL epc_demo_func() with parameters PL/SQL test: not NULL a = -7 PL/SQL test: s = >>>123<<< PL/SQL test: epc_demo_func() returns -7 PL/SQL test: and resulted s is >>>C func epc_demo_func_c() received the following input paramters: a=-7, a_ind=0, s='123', s_length=3, s_maxlen=200<<< PL/SQL test: ends PL/SQL procedure successfully completed. sqlplus -S Library created. Function created.

27 Дебъгване на EPC Oracle RDBMS SQL> select a_plus_b( 2, 3 ) from dual; … SQL> SQL*Plus extproc agent $ORACLE_HOME/bin/extproc using: OS.so load calls: sum.so/a_plus_b_c() OS $ORACLE_HOME/lib/sum.so a_plus_b_c() { … } (gdb) attach 9380 <Enter> Attaching to process 9380 … (gdb) break pextproc <Enter> Breakpoint 1 at 0xb7d77782 (gdb) select function_for_debugging(…) from dual; <Enter> [Switching to Thread (LWP 9380)] Breakpoint 1, 0xb7d77782 in pextproc () from /…/libagtsh.so (gdb) (gdb) break function_for_debugging <Enter> Breakpoint 2 at 0xb6e9e564 (gdb) Debugger - gdb, ddd !ps -ef | grep extproc <Enter> … oracle extprocEPC_SID (LOCAL=NO) … SQL> (gdb) cont <Enter> Continuing. (gdb) cont Continuing. Breakpoint 2, 0xb6e9e564 in function_for_debugging () from /…/sum.so (gdb) _ ~]$ ps -ef | grep extproc UID PID PPID C STIME TTY TIME CMD oracle :32 ? 00:00:00 extprocEPC_SID (LOCAL=NO) oracle :33 pts/1 00:00:00 grep extproc ~]$

28 Допълнителна информация на EPC Синтаксис на 'parameters' Предизвикване на exception от EPC Памет, указатели, стойности, променливи Предаване на масиви като параметри Изпълнение на DDL и DML от EPC

29 Синтаксис на 'parameters' PARAMETERS (external_parameter[, external_parameter]...) external_parameter stands for: { CONTEXT | SELF [{TDO | property}] | {parameter_name | RETURN} [property] [BY REFERENCE] [external_datatype] } property stands for: { INDICATOR [{STRUCT | TDO}] | LENGTH | DURATION | MAXLEN | CHARSETID | -- OCI_ATTR_CHARSET_ID CHARSETFORM-- OCI_ATTR_CHARSET_FORM }

30 Съответствие на типовете PL/SQL – C PL/SQL data typePARAMETERS ext.data typeC data type BOOLEAN, BINARY_INTEGER, PLS_INTEGER [UNSIGNED] CHAR [UNSIGNED] SHORT [UNSIGNED] INT [UNSIGNED] LONG [unsigned] char [unsigned] short [unsigned] int [unsigned] long CHAR, LONG, VARCHAR2 STRING OCISTRING char * OCIString * BLOB, CLOB OCILOBLOCATOROCILobLocator * NUMBER OCINUMBEROCINumber * DATE OCIDATEOCIDate * VARRAY, TABLE OCICOLLOCITable * CONTEXTOCIExtProcContext *

31 Съответствие на типовете PARAMETERS Property – C PropertyAllowed ext.data typeC data type INDICATOR SHORTshort LENGTH, MAXLEN [UNSIGNED] SHORT [UNSIGNED] INT [UNSIGNED] LONG [unsigned] short int [unsigned] long

32 Предизвикване на exception от EPC CREATE OR REPLACE PROCEDURE plsTo_divide_proc ( dividend IN BINARY_INTEGER, divisor IN BINARY_INTEGER, result OUT FLOAT ) AS LANGUAGE C NAME "C_divide" LIBRARY MathLib WITH CONTEXT PARAMETERS ( CONTEXT, dividend INT, divisor INT, result FLOAT ); /

33 void C_divide ( OCIExtProcContext *ctx; int dividend; int divisor; float *result ) { /* Check for zero divisor. */ if( divisor == (int)0 ) { /* Raise exception ZERO_DIVIDE, which is Oracle error */ if( OCIExtProcRaiseExcp( ctx, (int)1476 ) == OCIEXTPROC_SUCCESS ) return; else assert( 0 ); /* Incorrect parameters were passed. */ } *result = (float)dividend / (float)divisor; }

34 void C_divide ( OCIExtProcContext *ctx; int dividend; int divisor; float *result ) { /* Check for zero divisor. */ if( divisor == (int)0 ) { /* Raise exception 20100, which is user defined */ if( OCIExtProcRaiseExcpWithMsg( ctx, (int)20100, "divisor is zero", 0 ) == OCIEXTPROC_SUCCESS ) return; else assert( 0 ); /* Incorrect parameters were passed. */ } *result = (float)dividend / (float)divisor; }

35 Памет, указатели, стойности, променливи Области на действие на променливите и използване на стойностите им Необходимост от OCIExtProcAllocCallMemory Начин за заобикаляне необходимостта от OCIExtProcAllocCallMemory

36 С функция - epc_demo_func_c() int global_definition = 0; int epc_demo_func_c(... ) { char buf[200]; static char large_buf[ ];// 10 MBytes int initialize_every_time = 8; static int static_initialized_every_time = 10; static int not_initialized;... }

37 Необходимост от OCIExtProcAllocCallMemory например във функция за обединяване на два стринга: функцията приема като параметри два стринга, който трябва да обединят и да върне резултът от обединието

38 Начин за заобикаляне необходимостта от OCIExtProcAllocCallMemory вместо 'out' параметри да се използват 'in out' параметри, чиито стойности да бъдат инициализирани преди извикването на външна C функция: declare aa pls_integer := -7; ss varchar2( 200 ) := '123'; res pls_integer := 0; begin... res := epc_demo_func( aa, ss );... end; /

39 Предаване на масиви като параметри PL/SQL create or replace TYPE T_String_Array AS TABLE OF VARCHAR2(4000); / create or replace function func_with_varray( pls_sql_table_of_stringsin out T_String_Array, ) return pls_integer as language C name "c_func_with_varray" library SOME_LIB calling standard C with context parameters( context, pls_sql_table_of_strings OCICOLL, returnint ); /

40 Предаване на масиви като параметри C int c_func_with_varray( OCIExtProcContext *ctx, OCITable **pls_sql_table_of_strings, ) { // get the current number of elements into pls_sql_table_array status = OCICollSize(... ); // remove all current elements from pls_sql_table_array status = OCICollTrim(... ); // makes an OCI string from 'char *' status = OCIStringAssignText(... ); // append one more element to the pls_sql_table_array status = OCICollAppend(... ); }

41 Изпълнение на DDL и DML във EPC int c_func_with_varray( OCIExtProcContext *ctx,... ) { OCIEnv *envhp; OCISvcCtx *svchp; OCIError *errhp; sword err;... // get the environment handles for reuse the existing connection err = OCIExtProcGetEnv( ctx, &envhp, &svchp, &errhp );... // executing all other kind of OCI calls... }

42 Q & A

43 Благодаря за Вашето внимание!