2012-12-29 39 views
0

你能告诉我,为什么这个查询中pgAdmin的工作,但不与软件使用ODBC:的PostgreSQL,ODBC和临时表

CREATE TEMP TABLE temp296 WITH (OIDS) ON COMMIT DROP AS 
SELECT age_group AS a,male AS m,mode AS t,AVG(speed) AS speed 
FROM person JOIN info ON person.ppid=info.ppid 
WHERE info.mode=2 
GROUP BY age_group,male,mode; 

SELECT age_group,male,mode, 
CASE 
WHEN age_group=1 AND male=0 THEN (info_dist_km/(SELECT avg_speed FROM temp296 WHERE a=1 AND m=0))*60 
ELSE 0 
END AS info_durn_min 
FROM person JOIN info ON person.ppid=info.ppid 
WHERE info.mode IN (7) AND info.info_dist_km>2; 

我“42P01:ERROR:关系‘temp296’不存在”。

我也尝试过“BEGIN; COMMIT;” - “HY010:光标打开”。

PostgreSQL的9.0.10,采用Visual C++编译建立1500,64位 psqlODBC 09.01.0200 Windows 7的64位

+0

你可以重写使用临时表到CTE的查询吗?在这种情况下你仍然会遇到错误吗? – SingleNegationElimination

+0

我不熟悉CTE-I在第二个** SELECT **之前,我用** temp296 AS(**和**)** **取代了整个** CREATE **行。它是否正确?现在它可以工作。两个问题:为什么不是** CREATE TEMP TABLE **版本OK?CTE如何在具有多个连接的环境中同时运行(使用相同的凭据) - 用户不会覆盖第一个结果** SELECT **? – Tom

回答

3

我认为它为什么没有,因为在默认情况下为你工作的原因ODBC工程自动提交模式。如果您连续执行您的语句,第一条语句

CREATE TEMP TABLE temp296 ON COMMIT DROP ... ; 

必须在完成后自动提交,从而删除临时表。

不幸的是,ODBC不支持直接使用像BEGIN TRANSACTION; ... COMMIT;这样的语句来处理事务。

相反,你可以禁止使用SQLSetConnectAttr功能类似这样的自动提交:

SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0); 

但是,你这样做之后,你一定要记住使用SQLEndTran这样犯任何变化:

SQLEndTran(SQL_HANDLE_DBC, hdbc, SQL_COMMIT); 

尽管使用WITH方法作为解决方法已经奏效,但值得注意的是,正确使用事务比在自动提交模式下运行更快。例如,如果您需要在表中插入许多行(成千上万或上百万),则使用事务处理的速度可能比自动提交快几十万倍。

+0

听起来对我很好,但目前我无法在我使用的软件中使用额外的功能。我正在联系开发人员,希望他们能弄清楚如何运行这个功能。我会公布结果。 – Tom

+0

嗨,你知道如何在VB/VBA for Informix ODBC驱动程序中执行此操作吗? – phoenies

+0

我不认为VBA提供了任何方式来调用我提到的开始和提交事务的C API函数:'SQLSetConnectAttr()'和'SQLEndTran()' – mvp

0

临时表在ODBC中不能通过SQLPrepare/SQLExecute使用,例如在准备的语句上,例如MS SQL Server就是这样。解决方案通常使用SQLExecDirect。