SQL 中的 Extern C 函数



如何拆分带有未知分隔符的字符串?

我需要像这样拆分一个字符串

'3.584731 60.739211,3.590472

60.738030,3.592740:60.736220', * *(

在 * * 之间,我想输入一个分隔符,他会用分隔符拆分这个字符串。

例如

 If *:*
 3.584731 60.739211,3.590472 60.738030,3.592740
 60.736220

我知道 strtok(( 拆分了字符串。但是我如何使用它,代码不知道分隔符,用户必须插入它。这是我的代码。

PG_FUNCTION_INFO_V1(benchmark);
Datum
benchmark(PG_FUNCTION_ARGS)
{
FuncCallContext     *funcctx;
int                  call_cntr;
int                  max_calls;
TupleDesc            tupdesc;
AttInMetadata       *attinmeta;
//As Counters
int i = 0, j = 0;
//To get the every SingleString from the Table
char *k = text_to_cstring(PG_GETARG_TEXT_P(0));
//The Delimiter
char *c (0);
//the temporary "memory"
char * temp = NULL;
//The final result
//Need as an Array
//From ["x1 y1,x2 y2,...xn yn"] Split on the ',' 
//to   ["x1 y1","x2 y2",..."xn yn"] Split on the ' ' 
//to the final ["x1","y1","x2","y2"..."xn","yn"]
char**result[a] = {0};
if (SRF_IS_FIRSTCALL())
    {
        {
        MemoryContext   oldcontext;
        //create a function context for cross-call persistence 
        funcctx = SRF_FIRSTCALL_INIT();
        //reqdim = (PG_NARGS()  MAXDIM)
   //         SRF_RETURN_DONE(funcctx);
        // switch to memory context appropriate for multiple function calls 
        oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
        /* total number of tuples to be returned */
        funcctx->max_calls = PG_GETARG_UINT32(0);
        /* Build a tuple descriptor for our result type */
        if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
            ereport(ERROR,
                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                 errmsg("function returning record called in context "
                        "that cannot accept type record")));
        //Still dont know what attinmeta is
        attinmeta = TupleDescGetAttInMetadata(tupdesc);
        funcctx->attinmeta = attinmeta;
        MemoryContextSwitchTo(oldcontext);
    }
            call_cntr = funcctx->call_cntr;
            max_calls = funcctx->max_calls;
            attinmeta = funcctx->attinmeta;
            result[a] = funcctx->result[a];
            temp      = funcctx->temp;
            *k        = funcctx->*k;
            delim     = funcctx->delim;
            c         = funcctx->c;

            //here is the difficult part
            if(*k)
            {
                temp = strtok(k,delim) //the delimiter
                while (temp)
                {
                //palloc or malloc whats the difference ?
                result[a] = palloc...
                strcpy(result[a],temp)
                temp = strtok (NULL,delim)
                i++;
                }
                    for (j = 0; j < i; j++)
                    printf("[%d] sub-string is %sn", (j+1), result[j]);
                    for (j = 0; j < i; j++)
                    SRF_RETURN_NEXT(funcctx,result[a]);

            }
            else
            {
                SRF_RETURN_DONE(funcctx);
            }
}

这是对的吗?帕洛克还是马洛克?在这种情况下有什么区别以及如何使用它?我试着做很多笔记,因为我希望你能理解这个:)不要太难,我只是从程序开始:)

PostgreSQL源代码是采取一些想法和模式的良好开端。当你喜欢写SETOF函数时,你应该从一些SETOF函数开始。谷歌关键词是"SRF_RETURN_NEXT"。PostgreSQL 文档 http://www.postgresql.org/docs/9.3/static/xfunc-c.html 中有一些示例 - 您可以找到其他一些示例。

几年前我写了数组迭代器:

#include "funcapi.h"Typedef struct generate_iterator_fctx{        INT4 更低;        INT4 鞋面;        布尔反转;} generate_iterator_fctx;基准面array_subscripts(PG_FUNCTION_ARGS(;PG_FUNCTION_INFO_V1(array_subscripts(;/* * array_subscripts(数组任意数组、暗淡整数、反向布尔值( */基准array_subscripts(PG_FUNCTION_ARGS({        FuncCallContext *funcctx;        记忆上下文旧上下文;        generate_iterator_fctx *fctx;       /* 仅在第一次调用函数时完成的事情 */       如果 (SRF_IS_FIRSTCALL(((        {                数组类型 *v = PG_GETARG_ARRAYTYPE_P(0(;                int reqdim;                int *lb, *dimv;               /* 为交叉调用持久性创建函数上下文 */               funcctx = SRF_FIRSTCALL_INIT((;                reqdim = (PG_NARGS(( MAXDIM(                        SRF_RETURN_DONE(funcctx(;               /* 健全性检查:请求的暗淡是否有效 */               如果(要求ARR_NDIM(v((                        SRF_RETURN_DONE(funcctx(;               /*                 * 切换到适用于多个函数调用的内存上下文                 */               oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx(;                fctx = (generate_iterator_fctx *( palloc(sizeof(generate_iterator_fctx((;                磅 = ARR_LBOUND(v(;                dimv = ARR_DIMS(v(;                FCTX->lower = lb[reqdim - 1];                FCTX->上部 = DIMv[要求 - 1] + LB[要求 - 1] - 1;                fctx->reverse = (PG_NARGS(( user_fctx = fctx;                MemoryContextSwitchTo(oldcontext(;        }        funcctx = SRF_PERCALL_SETUP((;        FCTX = funcctx->user_fctx;        如果(FCTX->下部(        {                如果(!fctx->反向(                        SRF_RETURN_NEXT(funcctx, Int32GetDatum(fctx->lower++((;                还                        SRF_RETURN_NEXT(funcctx, Int32GetDatum(fctx->upper--((;        }        还               /* 当没有更多的时候做 */               SRF_RETURN_DONE(funcctx(;}

注册:

创建函数array_subscripts(任意数组(返回整数集作为"MODULE_PATHNAME"语言 C 严格;创建函数array_subscripts(任意数组,整数(返回整数集作为"MODULE_PATHNAME"语言 C 严格;创建函数array_subscripts(任意数组,整数,布尔值(返回整数集作为"MODULE_PATHNAME"语言 C 严格;

用法:

创建函数array_expand(任意数组(返回任意元素集如$$  选择 $1[i]     从array_subscripts($1(克(i(;$$ 语言 SQL;
请检查

下面的代码。希望它不言自明。

如果您有任何理解困难,请告诉我们。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZ 128
int main()
{
    char *op[SIZ];              //array to hold the o/p
    int i = 0, j = 0;           //used as counters
    char input[] = "3.584731 60.739211, / 3.590472 60.738030,3.592740 / 60.736220"; //the input
    char *delim = "/";          //the delimiter
    char * temp = NULL;
    temp = strtok(input, delim);
    while (temp)
    {
        op[i] = malloc(SIZ);
        strcpy(op[i], temp);
        temp = strtok(NULL, delim);
        i++;
    }
    for (j = 0; j < i; j++)
    printf("[%d] sub-string is %sn", (j+1), op[j]);
    for (j = 0; j < i; j++)
    free(op[j]);
    return 0;
}

编辑

版本 0.5。希望这个split_string()功能能解决你的问题。现在,使用 fgets() 询问用户输入。在此处阅读手册页。它不应该太难。祝你好运。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZ 128
void split_string(char * ip, char * sep);
int main()
{
        char input[] = "3.584731 60.739211, / 3.590472 60.738030,3.592740 / 60.736220"; //the input
        char *delim = "/";          //the delimiter
        split_string(input, delim);
        return 0;
}
void split_string(char * ip, char * sep)
{
        char * op[SIZ] = {0};
        int i = 0, j = 0;           //used as counters
        char * temp = NULL;
        if (ip)
        {
                temp = strtok(ip, sep);
                while (temp)
                {
                        op[i] = malloc(SIZ);
                        strcpy(op[i], temp);
                        temp = strtok(NULL, sep);
                        i++;
                }
                for (j = 0; j < i; j++)
                        printf("[%d] sub-string is %sn", (j+1), op[j]);
                for (j = 0; j < i; j++)
                        free(op[j]);
        }
}

最新更新