C-Sprache einfache Tabellenfunktion
In diesem Beispiel wird der folgende Dateiname verwendet: ' sstring.c
Code erstellen
Der Code in diesem Beispiel erstellt eine Funktion, die eine Zeichenkette auf der Grundlage des Trennzeichens in mehrere Zeichenketten aufteilt. Dieses Beispiel kann mehr Zeilen mit Ausgaben als mit Eingaben liefern. Beachten Sie die zusätzliche Schleifenlogik in run.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "nzaeapis.h"
static int run(NZAE_HANDLE h);
int main(int argc, char * argv[])
{
if (nzaeIsLocal())
{
NzaeInitialization arg;
memset(&arg, 0, sizeof(arg));
arg.ldkVersion = NZAE_LDK_VERSION;
if (nzaeInitialize(&arg))
{
fprintf(stderr, "initialization failed\n");
return -1;
}
run(arg.handle);
nzaeClose(arg.handle);
}
else {
NZAECONPT_HANDLE hConpt = nzaeconptCreate();
if (!hConpt)
{
fprintf(stderr, "error creating connection point\n");
fflush(stderr);
return -1;
}
const char * conPtName = nzaeRemprotGetRemoteName();
if (!conPtName)
{
fprintf(stderr, "error getting connection point name\n");
fflush(stderr);
exit(-1);
}
if (nzaeconptSetName(hConpt, conPtName))
{
fprintf(stderr, "error setting connection point name\n");
fflush(stderr);
nzaeconptClose(hConpt);
return -1;
}
NzaeremprotInitialization args;
memset(&args, 0, sizeof(args));
args.ldkVersion = NZAE_LDK_VERSION;
args.hConpt = hConpt;
if (nzaeRemprotCreateListener(&args))
{
fprintf(stderr, "unable to create listener - %s\n", \
args.errorMessage);
fflush(stderr);
nzaeconptClose(hConpt);
return -1;
}
NZAEREMPROT_HANDLE hRemprot = args.handle;
NzaeApi api;
int i;
for (i = 0; i < 5; i++)
{
if (nzaeRemprotAcceptApi(hRemprot, &api))
{
fprintf(stderr, "unable to accept API - %s\n", \
nzaeRemprotGetLastErrorText(hRemprot));
fflush(stderr);
nzaeconptClose(hConpt);
nzaeRemprotClose(hRemprot);
return -1;
}
if (api.apiType != NZAE_API_FUNCTION)
{
fprintf(stderr, "unexpected API returned\n");
fflush(stderr);
nzaeconptClose(hConpt);
nzaeRemprotClose(hRemprot);
return -1;
}
printf("testcapi: accepted a remote request\n");
fflush(stdout);
run(api.handle.function);
}
nzaeRemprotClose(hRemprot);
nzaeconptClose(hConpt);
}
return 0;
}
static int run(NZAE_HANDLE h)
{
NzaeMetadata metadata;
if (nzaeGetMetadata(h, &metadata))
{
fprintf(stderr, "get metadata failed\n");
return -1;
}
#define CHECK(value) \
{ \
NzaeRcCode rc = value; \
if (rc) \
{ \
const char * format = "%s in %s at %d"; \
fprintf(stderr, format, \
nzaeGetLastErrorText(h), __FILE__, __LINE__); \
nzaeUserError(h, format, \
nzaeGetLastErrorText(h), __FILE__, __LINE__); \
exit(-1); \
} \
}
if (metadata.outputColumnCount != 1 ||
metadata.outputTypes[0] != NZUDSUDX_VARIABLE)
{
nzaeUserError(h, "expecting one output column of type string");
nzaeDone(h);
return -1;
}
if (metadata.inputColumnCount != 1)
{
nzaeUserError(h, "expecting one input column");
nzaeDone(h);
return -1;
}
if (metadata.inputTypes[0] != NZUDSUDX_FIXED
&& metadata.inputTypes[0] != NZUDSUDX_VARIABLE)
{
nzaeUserError(h, "first input column expected to be a string type");
nzaeDone(h);
return -1;
}
for (;;)
{
int i;
double result = 0;
NzaeRcCode rc = nzaeGetNext(h);
if (rc == NZAE_RC_END)
{
break;
}
NzudsData * input = NULL;
CHECK(nzaeGetInputColumn(h, 0, &input));
const char * opString;
if (input->isNull)
{
nzaeUserError(h, "first input column may not be null");
nzaeDone(h);
return -1;
}
if (input->type == NZUDSUDX_FIXED)
{
opString = input->data.pFixedString;
} else if (input->type == NZUDSUDX_VARIABLE)
{
opString = input->data.pVariableString;
} else
{
nzaeUserError(h, "first input column expected to be a string \
type");
nzaeDone(h);
return -1;
}
const char *ptr = opString;
char *token;
while ((token = strtok(ptr, ",")) != NULL) {
ptr = NULL;
CHECK(nzaeSetOutputString(h, 0, token));
CHECK(nzaeOutputResult(h));
}
}
nzaeDone(h);
return 0;
}
Kompilierung
Verwenden Sie die Standardkompilierung:
$NZ_EXPORT_DIR/ae/utilities/bin/compile_ae --language system --version 3 \
--template compile sstring.c --exe sstring
Registrierung
Registrieren Sie die neu erstellte ausführbare Datei "
"sstring"
:$NZ_EXPORT_DIR/ae/utilities/bin/register_ae --language system --version 3 \
--template udtf --exe sstring --sig "sstring_c(VARCHAR(ANY))" \
--return "TABLE (val varchar(2000))"
Aktiv
Führen Sie die Abfrage in nzsql aus:
SELECT * FROM TABLE WITH FINAL(sstring_c('12:30:15'));
VAL
----------
12:30:15
(1 row)
SELECT * FROM TABLE WITH FINAL(sstring_c('12:30:15,two,three'));
VAL
----------
12:30:15
two
three
(3 rows)
SELECT * FROM TABLE WITH FINAL(sstring_c(NULL));
ERROR: first input COLUMN may NOT be NULL