Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql 错误28“;“堆栈空间不足”;用VB6执行大型查询&;ADO 2.8_Postgresql_Vb6_Oledb_Ado_Postgis - Fatal编程技术网

Postgresql 错误28“;“堆栈空间不足”;用VB6执行大型查询&;ADO 2.8

Postgresql 错误28“;“堆栈空间不足”;用VB6执行大型查询&;ADO 2.8,postgresql,vb6,oledb,ado,postgis,Postgresql,Vb6,Oledb,Ado,Postgis,场景: 使用ADO连接从Visual Basic 6应用程序执行SQL命令。通过PostgreSQL OLEDB提供程序执行方法到PostgreSQL 9.2数据库 查询: 这是一个简单的EXECUTE prepared_statement_name(x,y,z),尽管它涉及PostGIS几何体类型,因此它类似于: EXECUTE prepared_statement_name (1, ST_GeomFromText('POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))', 9

场景:
使用ADO连接从Visual Basic 6应用程序执行SQL命令。通过PostgreSQL OLEDB提供程序执行方法到PostgreSQL 9.2数据库

查询:
这是一个简单的
EXECUTE prepared_statement_name(x,y,z)
,尽管它涉及PostGIS几何体类型,因此它类似于:

EXECUTE prepared_statement_name (1, ST_GeomFromText('POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))', 900001));
问题:
当几何体是一个包含许多顶点的巨大而复杂的多边形时,查询会变得非常长(几千个字符),并且
连接.Execute
方法会导致错误28:“堆栈空间不足”

这个过程中没有递归或嵌套循环,很明显错误是由于查询长度过长造成的

我想如果我在执行之前将大查询以“块”的形式传递给提供者,我可以避免这个错误,但这只是一个想法,我不知道这是否可能以及如何实现


我不知道,非常感谢您的帮助。

因为这听起来像是一个VB6级别的问题,而且您已经使用了当前的Pg版本,我担心您可能需要使用一些特别难看的解决方法

如果可能的话,尝试找到一种增加VB6查询缓冲区大小的方法,通过VB6 ODBC接口在块中发送查询等。 也许这会给你一些更理智的线索。我不会说VB6(谢天谢地),所以我无法对其进行评估:

只有在所有其他方法都失败的情况下,才将以下方法作为最后手段使用

  • 创建一个
    TEMPORARY
    表,如
    Create TEMPORARY table my\u query(id integer,text querychunk)

  • 将语句逐块插入到临时表中,使用参数化查询避免引用问题

  • 创建一个包装器PL/PgSQL函数,该函数执行
    返回查询执行格式('EXECUTE stm_name(…)”
    ,将临时表的
    字符串作为参数传递。是的,这非常难看

下面是一个演示,是我写过的最可怕的代码:

CREATE TABLE real_table (blah text);

PREPARE test_stm2(text) AS INSERT INTO real_table VALUES ($1);

CREATE TEMPORARY TABLE data_chunks(datord integer, datchunk text);

PREPARE chunk_insert(integer, text) AS INSERT INTO data_chunks(datord,datchunk) VALUES ($1,$2);

-- You'll really want to do this via proper parameterised statements
-- to avoid quoting nightmares; I'm using dollar-quoting as a workaround
EXECUTE chunk_insert(0, $val$POLYGON((0 0, 0 1, 1 1,$val$);
EXECUTE chunk_insert(1, $val$ 1, 1 0, 0 0))$val$);

DO
$$
BEGIN
    EXECUTE 'EXECUTE test_stm2($1);'
        USING 
        (SELECT string_agg(datchunk,'' ORDER BY datord) FROM data_chunks);
END;
$$ LANGUAGE plpgsql;
结果:

regress=> SELECT * FROM real_table ;
                 blah                  
---------------------------------------
 POLYGON((0 0, 0 1, 1 1, 1, 1 0, 0 0))
(1 row)
SELECT
也可以采用类似的方法。您可以在由
CREATE或REPLACE function
定义的函数中使用
RETURN QUERY EXECUTE
,因为
DO
块不能返回结果。例如,对于返回一组
整数的查询,您可以编写:

CREATE OR REPLACE FUNCTION test_wrapper_func() RETURNS SETOF integer AS $$
BEGIN
    RETURN QUERY EXECUTE format('EXECUTE test_stm(%L);', (SELECT string_agg(datchunk,'' ORDER BY datord) FROM data_chunks));
END;
$$ LANGUAGE plpgsql;
您将注意到两级
EXECUTE
。这是因为PL/PgSQL
EXECUTE
与SQL级
EXECUTE
是完全不同的语句。PL/PgSQL
EXECUTE
以动态SQL的形式运行字符串,而SQL
EXECUTE
则运行一条准备好的语句。这里我们通过动态SQL运行一条准备好的语句

想知道我为什么要使用PL/PgSQL吗?因为您不能将子查询用作
EXECUTE
参数。如果您不将其作为预处理语句运行,则可以避免查询的PL/PgSQL包装

regress=> EXECUTE test_stm2( (SELECT string_agg(datchunk,'' ORDER BY datord) FROM data_chunks) );
ERROR:  cannot use subquery in EXECUTE parameter

您的代码中可能没有递归或循环,但Postgre/PostGIS很可能是内部的。我希望您唯一的选择是重新构造yoru查询或分块执行。如果您可以提供一个溢出查询的示例,可能有人可以进一步提供帮助。嗯,VB6?从1998年开始,2005年结束?使用PostGIS?看起来很奇怪combo。您似乎忘记提及您的PostgreSQL、PostGIS和PSQLDBC版本。@Deanna感谢您的评论,但它与递归没有任何关系。同一查询在任何其他客户端(例如pgAdminIII)中都可以正常执行。查询正是问题中的一个,只需向多边形添加几千个顶点。@Craig Ringer是的,我知道VB6已经过时,听起来像是一个“奇怪的组合”(有趣的组合),但这就是我得到的,我必须修复它,遗留软件是最差的软件。PostgreSQL 9.2、PostGIS 2.0、pgFoundry PgOleDb 1.0.20是这些版本(是的,那些最新的版本使vb6组合更加糟糕…@Eggplant足够公平了…我在1983年做过一些(!!)去年微软Xenix/386的软件,所以我知道痛苦是什么样的。不管怎样,首先:如果你直接通过
psql
在VB6中执行一个失败的查询,它会因为同样的错误而失败吗?或者直接通过
psql
运行它会成功吗?哇,这是一个巧妙的解决方案,它可能“丑陋”,但它也是“安全的”:它将所有内容保留在一些查询中,我仍然可以将所有“丑陋的东西”打包到事务中!与此同时,我正在开发一个更丑陋的解决方案,该解决方案涉及db类和ado之间的应用程序中的一个附加层,该层应该拦截所有命令并在硬盘上编写脚本文件,然后使用psql执行它(是的,从vb6启动psql…。现在这很难看!!!:)我喜欢你的解决方案,它需要更改一些查询,但避免了外部交互。非常感谢!我非常感谢你付出的努力和时间。我现在能够自己实现整个概念,你为我节省了一些时间损失!vb6又得分了!-)