0

你能告诉我为什么这个查询在 pgAdmin 中有效,但在使用 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:错误:关系“temp296”不存在”。

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

PostgreSQL 9.0.10,由 Visual C++ build 1500 编译,64 位 psqlODBC 09.01.0200 Windows 7 x64

4

2 回答 2

3

我认为它对您不起作用的原因是因为默认情况下 OD​​BC 在自动提交模式下工作。如果你连续执行你的语句,第一个语句

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 方法作为一种解决方法对您有用,但值得注意的是,适当地使用事务比在自动提交模式下运行更快。

例如,如果您需要向表中插入许多行(数千或数百万),使用事务可以比自动提交快成百上千倍。

于 2012-12-30T09:31:31.667 回答
0

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

于 2013-01-07T17:30:10.673 回答