我将为DB2开发新的(外部)函数。我的第一次测试:
db2crypt.h
#ifndef DB2CRYPT_H
#define DB2CRYPT_H
#include <string.h>
#include <stdlib.h>
char *encryptAes(const char *source, const char *key);
#endif /* DB2CRYPT_H */
db2crypt.cpp
#include "db2crypt.h"
#include <string>
char *encryptAes(const char *source, const char *key) {
std::string test("abc");
return (char *)test.c_str();
}
编译时没有错误。
g++ -fPIC -c db2crypt.cpp -std=c++14
g++ -shared -o db2crypt db2crypt.o -L$DB2PATH -ldb2
我还将新文件复制到$ DB2PATH / function中,并在$ DB2PATH / function / unfenced中创建了一个软链接。
然后我创建了函数
create function aes(VARCHAR(4096), VARCHAR(4096))
SPECIFIC encryptAes
RETURNS VARCHAR(4069)
NOT FENCED
DETERMINISTIC
NO SQL
NO EXTERNAL ACTION
LANGUAGE C
RETURNS NULL ON NULL
INPUT PARAMETER STYLE SQL
EXTERNAL NAME "db2crypt!encryptAes"
这也没关系。
但是,当我做select db2inst1.aes('a', 'b') from SYSIBM.SYSDUMMY1
我得到错误
SQL0444N Die Routine "DB2INST1.AES" (spezifischer Name "ENCRYPTAES") ist
durch Code in Bibliothek oder Pfad ".../sqllib/function/db2crypt", Funktion
"encryptAes" implementiert, auf die kein Zugriff möglich ist. Ursachencode:
"6". SQLSTATE=42724
(抱歉,我不知道如何将错误输出更改为英文)
我做错了什么?
好的,我得到了答案。谢谢@mao,你确实帮了我。但我还需要一些其他的帮助。如果有人搜索答案:
首先,您必须使用一些重要参数进行编译:
g++ -m64 -fPIC -c <yourfile>.cpp -std=c++14 -I/opt/ibm/db2/V11.1/include/ -D_REENTRANT
g++ -m64 -shared -o <yourfile> <yourfile>.o -L$DB2PATH -ldb2 -Wl,-rpath,$DB2PATH/$LIB -lpthread
第二:函数声明,你还必须为空值添加参数并且返回值不能是函数返回,它必须是一个参数。您还必须使用sqludf.h中定义的类型:
void SQL_API_FN encryptAes(SQLUDF_CHAR *source,
SQLUDF_CHAR *key,
SQLUDF_CHAR out[4096],
SQLUDF_SMALLINT *sourcenull,
SQLUDF_SMALLINT *keynull,
SQLUDF_SMALLINT *outnull,
SQLUDF_TRAIL_ARGS) {
...
}
此外,当您使用C ++而不是C时,您必须告诉脚本它必须将函数作为C来处理:
#ifdef __cplusplus
extern "C"
#endif
void SQL_API_FN ...