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++ ビルド 1500 でコンパイル、64 ビット psqlODBC 09.01.0200 Windows 7 x64

4

2 に答える 2

3

デフォルトでODBCは自動コミットモードで動作するため、動作しなかった理由だと思います。ステートメントを連続して実行した場合、最初のステートメント

CREATE TEMP TABLE temp296 ON COMMIT DROP ... ;

終了後に自動コミットされている必要があるため、一時テーブルを削除しました。

BEGIN TRANSACTION; ... COMMIT;残念ながら、ODBCはトランザクションの処理などのステートメントの直接使用をサポートしていません。

代わりに、次のような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を介して一時テーブルを使用できないことは珍しくありません。つまり、プリペアドステートメントでは、MSSQLServerは次のようになります。解決策は通常、SQLExecDirectを使用することです。

于 2013-01-07T17:30:10.673 に答える