返回首页

gbase数据、南大通用产品文档:GBase8s外部例程引用

更新日期:2024年09月11日

当编写外部例程时使用外部例程引用。该项对 SPL 例程无效。
外部例程引用

用法

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1612
如果 IFX_EXTEND_ROLE 配置参数设置为 ON 或 1,则只能授予数据库服务器
管理员(DBSA)及 DBSA 已经授予 EXTEND 角色的用户使用这个段的权限。
缺省情况下,DBSA 是用户 gbasedbt。此外,您不能创建外部例程除非您持有数
据库的 Resource 或 DBA 特权,并且还拥有编写此例程的外部程序语言的
Usage 特权。有关 GRANT USAGE ON LANGUAGE C 和 GRANT USAGE ON
LANGUAGE JAVA 语句的语法,请参阅 语言级权限。
这个段指定以下关于外部例程的信息:

存储在共享对象文件中的可执行目标代码的路径名
对于 C 例程,这个文件可以是 DLL 或共享库,这取决于您的操作系
统。

对于 Java 例程,这个文件是 jar 文件。在能够创建用 Java 语句编写的
UDR 之前,必须用 sqlj.install_jar 过程分配一个 jar 标识符给外部 jar
文件。有关更多信息,请参阅 sqlj.install_jar。

用来编写 UDR 的编程语言的名称

UDR 的参数样式
缺省情况下,参数样式是 GBASEDBT。(这意味着如果指定 OUT 或
INOUT 参数,则 OUT 或 INOUT 值通过引用来传递。)

VARIANT 或 NOT VARIANT 选项。如果指定其中一个,缺省为
VARIANT。如果例程包含任何 SQL 语句,它是一个 VARIANT 例程。
如果包含外部例程引用子句的 DDL 语句还包含例程修改符子句,那么请
不要在其中一个子句中将相同的 UDR 分类为 VARIANT ,而在其它子
句中将 VARIANT 分类为 NOT VARIANT 。
示例
下面的示例包含 Java 语言编写 UDR 引用的外部例程。您必须首先使用过程
install_jar(,name>)注册 demo_jar。
CREATE FUNCTION delete_order(int) RETURNING int
EXTERNAL NAME 'gbasedbt.demo_jar:delete_order.delete_order()'
LANGUAGE JAVA;

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1613
VARIANT 或 NOT VARIANT 选项
如果函数以相同参量调用时返回不同结果,或者如果它修改数据库或变量的状
态,则函数是 variant。例如,返回当前日期和时间的函数就是一个可变函数。
缺省情况下,用户定义函数是可变的。如果在创建或修改函数时指定 NOT
VARIANT,那么函数就不能包含任何 SQL 语句。
如果函数是不变的,数据库服务器可以存储返回可变函数。更多关于函数型索引
的信息,请参阅 CREATE INDEX 语句。
要注册一个不变函数,在这个子句或例程修饰符讨论的例程修饰符子句中添加
NOT VARIANT 选项。然而,如果在两处都指定修饰符,必须在两个子句中都使
用同一修饰符(VARIANT 或 NOT VARIANT)。
用户定义的函数的示例
下面的例子注册了一个名为 equal( ) 的外部函数,接受两个 point 数据类型值
作为参量。在这个例子中,point 是不透明数据类型,指定一个二维点的 x 和 y
坐标。
CREATE FUNCTION equal( a point, b point ) RETURNING BOOLEAN;
EXTERNAL NAME "/usr/lib/point/lib/libbtype1.so(point1_equal)"
LANGUAGE C
END FUNCTION;
函数返回一个 BOOLEAN 类型的值。外部名称指定存储函数目标代码的 C 共享
对象文件的路径。外部名称指出库包含另一个函数 point1_equal( ),它在 equal( )
执行时调用。

修改语法:
增强SELECT FOR NO KEY UPDATE 语法
3
新功能说明
支持docker 部署。
执行计划:
stream 支持列存表SMP 功能,
insert 执行计划优化,
remote query
执行计划支持merge into 等方式。
l2k 工具支持wal2json 生成ogg 的json 格式。
支持json 格式的WDR 报告。
支持列存复制表的更新操作。

Release Notes
南大通用数据技术股份有限公司
2
支持pgcrypto 插件。
4
修复问题说明
分布式首次发版不涉及。
5
遗留问题
备份恢复完成后,drop table 超时。
极端场景高可用测试,2gtm、1cn、2dn 同时故障,丢失数据。
gha_server 主节点网络闪断故障恢复后,新主节点宕机,丢失一条数据。
修改全局临时的表名后先查询修改前的表再查询修改后的表时,
查询结果变
为空。
创建物化视图,扩容失败,报错"gs_redis on cn1 failed"。
删除作用在视图的行级触发器失败报错has no distribute type。
6
使用限制

7
注意事项


Release Notes
南大通用数据技术股份有限公司
3

代码示例 locreate.c 展示如何创建智能大对象。
在 UNIX™ 平台上的 %GBS_HOME%/demo/clidemo 中,以及在 Windows™ 环境中
的 %GBS_HOME%\demo\odbcdemo 目录中,可找到 locreate.c 文件。在同一位置,您还
可以找到关于如何构建 odbc_demo 数据库的指导。
/*
** locreate.c
**
** To create a smart large object
**
** OBDC Functions:
** SQLAllocHandle
** SQLBindParameter
** SQLConnect
** SQLFreeStmt
** SQLGetInfo
** SQLDisconnect
** SQLExecDirect
*/

#include
#include

GBase 8s ODBC Driver 程序员指南
南大通用数据技术股份有限公司
- 94 -

#include

#ifndef NO_WIN32
#include
#include
#include
#endif /*NO_WIN32*/

#include "infxcli.h"

#define BUFFER_LEN 12
#define ERRMSG_LEN 200

UCHAR defDsn[] = "odbc_demo";


int checkError (SQLRETURN rc,
SQLSMALLINT handleType,
SQLHANDLE handle,
char *errmsg)
{
SQLRETURN retcode = SQL_SUCCESS;

SQLSMALLINT errNum = 1;
SQLCHAR sqlState[6];
SQLINTEGER nativeError;
SQLCHAR errMsg[ERRMSG_LEN];
SQLSMALLINT textLengthPtr;

if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO))
{
while (retcode != SQL_NO_DATA)
{
retcode = SQLGetDiagRec (handleType, handle, errNum, sqlState,
&nativeError, errMsg, ERRMSG_LEN, &textLengthPtr);

if (retcode == SQL_INVALID_HANDLE)
{
fprintf (stderr, "checkError function was called with an
invalid handle!!\n");
return 1;
}


GBase 8s ODBC Driver 程序员指南
南大通用数据技术股份有限公司
- 95 -

if ((retcode == SQL_SUCCESS) || (retcode ==
SQL_SUCCESS_WITH_INFO))
fprintf (stderr, "ERROR: %d: %s : %s \n", nativeError,
sqlState, errMsg);

errNum++;
}

fprintf (stderr, "%s\n", errmsg);
return 1; /* all errors on this handle have been reported */
}
else
return 0; /* no errors to report */
}

int main (long argc,
char *argv[])
{
/* Declare variables
*/

/* Handles */
SQLHDBC hdbc;
SQLHENV henv;
SQLHSTMT hstmt;

/* Smart large object file descriptor */
long lofd;
long lofd_valsize = 0;

/* Smart large object pointer structure */
char* loptr_buffer;
short loptr_size;
long loptr_valsize = 0;

/* Smart large object specification structure */
char* lospec_buffer;
short lospec_size;
long lospec_valsize = 0;

/* Write buffer */
char* write_buffer;
short write_size;

GBase 8s ODBC Driver 程序员指南
南大通用数据技术股份有限公司
- 96 -

long write_valsize = 0;

/* Miscellaneous variables */
UCHAR dsn[20];/*name of the DSN used for connecting to the
database*/
SQLRETURN rc = 0;
int in;

FILE* hfile;
char* lo_file_name = "advert.txt";

char colname[BUFFER_LEN] = "item.advert";
long colname_size = SQL_NTS;

long mode = LO_RDWR;
long cbMode = 0;

char* insertStmt = "INSERT INTO item VALUES (1005, 'Helmet', 235,
'Each', ?, '39.95')";


/* STEP 1. Get data source name from command line (or use default).
** Allocate environment handle and set ODBC version.
** Allocate connection handle.
** Establish the database connection.
** Allocate the statement handle.
*/

/* If (dsn is not explicitly passed in as arg) */
if (argc != 2)
{
/* Use default dsn - odbc_demo */
fprintf (stdout, "\nUsing default DSN : %s\n", defDsn);
strcpy ((char *)dsn, (char *)defDsn);
}
else
{
/* Use specified dsn */
strcpy ((char *)dsn, (char *)argv[1]);
fprintf (stdout, "\nUsing specified DSN : %s\n", dsn);
}

/* Allocate the Environment handle */

GBase 8s ODBC Driver 程序员指南
南大通用数据技术股份有限公司
- 97 -

rc = SQLAllocHandle (SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
if (rc != SQL_SUCCESS)
{
fprintf (stdout, "Environment Handle Allocation failed\nExiting!!");
return (1);
}

/* Set the ODBC version to 3.5 */
rc = SQLSetEnvAttr (henv, SQL_ATTR_ODBC_VERSION,
(SQLPOINTER)SQL_OV_ODBC3, 0);
if (checkError (rc, SQL_HANDLE_ENV, henv, "Error in Step 1 --
SQLSetEnvAttr failed\nExiting!!"))
return (1);

/* Allocate the connection handle */
rc = SQLAllocHandle (SQL_HANDLE_DBC, henv, &hdbc);
if (checkError (rc, SQL_HANDLE_ENV, henv, "Error in Step 1 -- Connection
Handle Allocation failed\nExiting!!"))
return (1);

/* Establish the database connection */
rc = SQLConnect (hdbc, dsn, SQL_NTS, "", SQL_NTS, "", SQL_NTS);
if (checkError (rc, SQL_HANDLE_DBC, hdbc, "Error in Step 1 -- SQLConnect
failed\n"))
return (1);

/* Allocate the statement handle */
rc = SQLAllocHandle (SQL_HANDLE_STMT, hdbc, &hstmt);
if (checkError (rc, SQL_HANDLE_DBC, hdbc, "Error in Step 1 -- Statement
Handle Allocation failed\nExiting!!"))
return (1);

fprintf (stdout, "STEP 1 done...connected to database\n");


/* STEP 2. Get the size of the smart large object specification
** structure.
** Allocate a buffer to hold the structure.
** Create a default smart large object specification structure.
** Reset the statement parameters.
*/

/* Get the size of a smart large object specification structure */

GBase 8s ODBC Driver 程序员指南
南大通用数据技术股份有限公司
- 98 -

rc = SQLGetInfo (hdbc, SQL_INFX_LO_SPEC_LENGTH, &lospec_size,
sizeof(lospec_size), NULL);
if (checkError (rc, SQL_HANDLE_DBC, hdbc, "Error in Step 2 -- SQLGetInfo
failed\n"))
goto Exit;

/* Allocate a buffer to hold the smart large object specification
structure*/
lospec_buffer = malloc (lospec_size);

/* Create a default smart large object specification structure */
rc = SQLBindParameter (hstmt, 1, SQL_PARAM_INPUT_OUTPUT,
SQL_C_BINARY,
SQL_INFX_UDT_FIXED, (UDWORD)lospec_size, 0, lospec_buffer,
lospec_size, &lospec_valsize);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 2 --
SQLBindParameter failed\n"))
goto Exit;
rc = SQLExecDirect (hstmt, "{call ifx_lo_def_create_spec(?)}", SQL_NTS);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 2 --
SQLExecDirect failed\n"))
goto Exit;

/* Reset the statement parameters */
rc = SQLFreeStmt (hstmt, SQL_RESET_PARAMS);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 2 --
SQLFreeStmt failed\n"))
goto Exit;

fprintf (stdout, "STEP 2 done...default smart large object specification
structure created\n");


/* STEP 3. Initialise the smart large object specification structure
** with values for the database column where the smart large
** object is being inserted.
** Reset the statement parameters.
*/

/* Initialise the smart large object specification structure */
rc = SQLBindParameter (hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR,
SQL_CHAR,
BUFFER_LEN, 0, colname, BUFFER_LEN, &colname_size);

GBase 8s ODBC Driver 程序员指南
南大通用数据技术股份有限公司
- 99 -

if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 3 --
SQLBindParameter failed (param 1)\n"))
goto Exit;

lospec_valsize = lospec_size;

rc = SQLBindParameter (hstmt, 2, SQL_PARAM_INPUT_OUTPUT,
SQL_C_BINARY,
SQL_INFX_UDT_FIXED, (UDWORD)lospec_size, 0, lospec_buffer,
lospec_size, &lospec_valsize);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 3 --
SQLBindParameter failed (param 2)\n"))
goto Exit;

rc = SQLExecDirect (hstmt, "{call ifx_lo_col_info(?, ?)}", SQL_NTS);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 3 --
SQLExecDirect failed\n"))
goto Exit;

/* Reset the statement parameters */
rc = SQLFreeStmt (hstmt, SQL_RESET_PARAMS);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 3 --
SQLFreeStm failed\n"))
goto Exit;

fprintf(stdout, "STEP 3 done...smart large object specification
structure initialised\n");


/* STEP 4. Get the size of the smart large object pointer structure.
** Allocate a buffer to hold the structure.
*/

/* Get the size of the smart large object pointer structure */
rc = SQLGetInfo (hdbc, SQL_INFX_LO_PTR_LENGTH, &loptr_size,
sizeof(loptr_size), NULL);
if (checkError (rc, SQL_HANDLE_DBC, hdbc, "Error in Step 4 --
SQLGetInfo failed\n"))
goto Exit;

/* Allocate a buffer to hold the smart large object pointer structure */
loptr_buffer = malloc (loptr_size);


GBase 8s ODBC Driver 程序员指南
南大通用数据技术股份有限公司
- 100 -

fprintf (stdout, "STEP 4 done...smart large object pointer structure
allocated\n");


/* STEP 5. Create a new smart large object.
** Reset the statement parameters.
*/

/* Create a new smart large object */
rc = SQLBindParameter (hstmt, 1, SQL_PARAM_INPUT, SQL_C_BINARY,
SQL_INFX_UDT_FIXED, (UDWORD)lospec_size, 0, lospec_buffer,
lospec_size, &lospec_valsize);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 5 --
SQLBindParameter failed (param 1)\n"))
goto Exit;

rc = SQLBindParameter (hstmt, 2, SQL_PARAM_INPUT, SQL_C_SLONG,
SQL_INTEGER, (UDWORD)0, 0, &mode, sizeof(mode), &cbMode);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 5 --
SQLBindParameter failed (param 2)\n"))
goto Exit;

loptr_valsize = loptr_size;

rc = SQLBindParameter (hstmt, 3, SQL_PARAM_INPUT_OUTPUT,
SQL_C_BINARY,
SQL_INFX_UDT_FIXED, (UDWORD)loptr_size, 0, loptr_buffer,
loptr_size, &loptr_valsize);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 5 --
SQLBindParameter failed (param 3)\n"))
goto Exit;

rc = SQLBindParameter (hstmt, 4, SQL_PARAM_OUTPUT, SQL_C_SLONG,
SQL_INTEGER, (UDWORD)0, 0, &lofd, sizeof(lofd), &lofd_valsize);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 5 --
SQLBindParameter failed (param 4)\n"))
goto Exit;

rc = SQLExecDirect (hstmt, "{call ifx_lo_create(?, ?, ?, ?)}", SQL_NTS);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 5 --
SQLExecDirect failed\n"))
goto Exit;


GBase 8s ODBC Driver 程序员指南
南大通用数据技术股份有限公司
- 101 -

/* Reset the statement parameters */
rc = SQLFreeStmt (hstmt, SQL_RESET_PARAMS);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 5 --
SQLFreeStmt failed\n"))
goto Exit;

fprintf (stdout, "STEP 5 done...smart large object created\n");


/* STEP 6. Open the file containing data for the new smart large object.
** Allocate a buffer to hold the smart large object data.
** Read data from the input file into the smart large object.
** data buffer
** Write data from the data buffer into the new smart large.
** object.
** Reset the statement parameters.
*/

/* Open the file containing data for the new smart large object */
hfile = open (lo_file_name, "rt");
/* sneaky way to get the size of the file */
write_size = lseek (open (lo_file_name, "rt"), 0L, SEEK_END);

/* Allocate a buffer to hold the smart large object data */
write_buffer = malloc (write_size + 1);

/* Read smart large object data from file */
read (hfile, write_buffer, write_size);

write_buffer[write_size] = '\0';
write_valsize = write_size;
/* Write data from the data buffer into the new smart large object */
rc = SQLBindParameter (hstmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG,
SQL_INTEGER, (UDWORD)0, 0, &lofd, sizeof(lofd), &lofd_valsize);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 6 --
SQLBindParameter failed (param 1)\n"))
goto Exit;

rc = SQLBindParameter (hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR,
SQL_CHAR,
(UDWORD)write_size, 0, write_buffer, write_size, &write_valsize);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 6 --
SQLBindParameter failed (param 2)\n"))

GBase 8s ODBC Driver 程序员指南
南大通用数据技术股份有限公司
- 102 -

goto Exit;

rc = SQLExecDirect (hstmt, "{call ifx_lo_write(?, ?)}", SQL_NTS);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 6 --
SQLExecDirect failed\n"))
goto Exit;

/* Reset the statement parameters */
rc = SQLFreeStmt (hstmt, SQL_RESET_PARAMS);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 6 --
SQLFreeStmt failed\n"))
goto Exit;

fprintf (stdout, "STEP 6 done...data written to new smart large
object\n");


/* STEP 7. Insert the new smart large object into the database.
** Reset the statement parameters.
*/

/* Insert the new smart large object into the database */
loptr_valsize = loptr_size;

rc = SQLBindParameter (hstmt, 1, SQL_PARAM_INPUT, SQL_C_BINARY,
SQL_INFX_UDT_FIXED, (UDWORD)loptr_size, 0, loptr_buffer,
loptr_size, &loptr_valsize);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 7 --
SQLBindParameter failed\n"))
goto Exit;

rc = SQLExecDirect (hstmt, insertStmt, SQL_NTS);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 7 --
SQLExecDirect failed\n"))
goto Exit;

/* Reset the statement parameters */
rc = SQLFreeStmt (hstmt, SQL_RESET_PARAMS);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 7 --
SQLFreeStmt failed\n"))
goto Exit;

fprintf (stdout, "STEP 7 done...smart large object inserted into the

GBase 8s ODBC Driver 程序员指南
南大通用数据技术股份有限公司
- 103 -

database\n");


/* STEP 8. Close the smart large object.
*/

rc = SQLBindParameter (hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG,
SQL_INTEGER, (UDWORD)0, 0, &lofd, sizeof(lofd), &lofd_valsize);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 8 --
SQLBindParameter failed\n"))
goto Exit;

rc = SQLExecDirect (hstmt, "{call ifx_lo_close(?)}", SQL_NTS);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 8 --
SQLExecDirect failed\n"))
goto Exit;

fprintf (stdout, "STEP 8 done...smart large object closed\n");


/* STEP 9. Free the allocated buffers.
*/

free (lospec_buffer);
free (loptr_buffer);
free (write_buffer);

fprintf (stdout, "STEP 9 done...smart large object buffers freed\n");

Exit:

/* CLEANUP: Close the statement handle
** Free the statement handle
** Disconnect from the datasource
** Free the connection and environment handles
** Exit
*/

/* Close the statement handle */
SQLFreeStmt (hstmt, SQL_CLOSE);

/* Free the statement handle */
SQLFreeHandle (SQL_HANDLE_STMT, hstmt);

GBase 8s ODBC Driver 程序员指南
南大通用数据技术股份有限公司
- 104 -


/* Disconnect from the data source */
SQLDisconnect (hdbc);

/* Free the environment handle and the database connection handle */
SQLFreeHandle (SQL_HANDLE_DBC, hdbc);
SQLFreeHandle (SQL_HANDLE_ENV, henv);

fprintf (stdout,"\n\nHit to terminate the program...\n\n");
in = getchar ();
return (rc);
}