我正在与 postgres 合作,尝试从时间戳列中提取纪元时间
这是存储过程:
CREATE OR REPLACE FUNCTION epochtime(sampleid integer, starttime timestamp without time zone, stoptime timestamp without time zone)
RETURNS text AS
$BODY$DECLARE
result text;
BEGIN
SELECT INTO result string_agg(concat_ws(',',epochres), ',')
FROM (
Select extract('epoch' from "Timestamp") as epochres from "Results"
where "SampleID"=sampleid and "Timestamp" >= starttime
and "Timestamp" <= stoptime order by "Timestamp" asc ) res;
return result;
END$BODY$
LANGUAGE plpgsql VOLATILE
调用存储过程的 C 函数:
static int getEpoch(ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj *const
objv[]){
Tcl_Obj *result;
char sampleid[15];
char repStartTime[256];
char repStopTime[256];
int length;
int lengthTwo;
int lengthThree;
if (objc != 4) {
Tcl_WrongNumArgs(interp, 2, objv, "number of argument error");
return TCL_ERROR;
}
strcpy(sampleid, Tcl_GetStringFromObj(objv[1], &lengthThree));
strcpy(repStartTime, Tcl_GetStringFromObj(objv[2], &length));
strcpy(repStopTime, Tcl_GetStringFromObj(objv[3], &lengthTwo));
char command[256];
PQclear(res);
strcpy(command, "Select \"epochtime\"('");
strcat(command, sampleid);
strcat(command,"','");
strcat(command, repStartTime);
strcat(command,"','");
strcat(command, repStopTime);
strcat(command, "')");
res = PQexec(conn,command);
result = Tcl_GetObjResult(interp);
Tcl_SetStringObj(result, PQgetvalue(res,0,0), strlen(PQgetvalue(res,0,0)));
return TCL_OK;
}
对于少量数据,我想说大约 700 个数字它工作得很好,但是如果我尝试获取很多数字,例如 10000 或类似的数字,它会导致程序中出现段错误,并且如果我在命令行它重叠了所有结果,从字面上看,数字看起来像是在彼此之上
列中少量记录的示例:
列中记录数量较多的示例:
就像我说的那样,对于少量记录,一切都可以正常工作,但我需要它以同样的方式处理大量记录。
最佳答案
您遇到的问题是,您将所有纪元连接成一个字符串,当您有许多纪元时,这会导致缓冲区溢出。换句话说,当返回多个纪元时,结果字符串大于为结果分配的内存,从而导致段错误。
pgAdmin 中的叠印问题只是一个副作用。 pgAdmin 不擅长处理长字符串。
解决方案是简单地将纪元的选择作为单独的记录返回到您的 C 程序,并在那里进行任何串联。您应该分配一个足够大的字符串缓冲区,以将所有纪元保存在单个字符串中,您可以根据返回的纪元数量乘以典型的纪元长度来估计该长度,在您的情况下,该长度似乎是 10 个字符(加上分隔符和空格,显然,使其成为 12)。
但是你真的需要将所有纪元放在一个字符串中吗?
关于c - extract epoch 导致数据重叠 postgres,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23770852/