Внешняя функция db2 заканчивается на SQL0444N, код причины 6, SQLSTATE 42724 - PullRequest
0 голосов
/ 27 апреля 2019

Я буду разрабатывать новые (внешние) функции для 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

Iтакже скопировал новый файл в $ DB2PATH / function и сделал мягкую ссылку в $ DB2PATH / function / unenced.

Затем я создал функцию с помощью

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

(извините, я не знаю, как изменить вывод ошибки на английский)

Что я сделалнеправильно?

1 Ответ

0 голосов
/ 27 апреля 2019

Хорошо, я получил ответ.Спасибо на @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 ...
...