在許多情況下,應用程式需要執行的特定 SQL 語句在編寫應用程式時是已知的。然而,在某些情況下,SQL 語句是在執行時組合的,或是由外部來源提供的。在這些情況下,您無法將 SQL 語句直接嵌入到 C 原始碼中,但有一種機制允許您呼叫在字串變數中提供的任意 SQL 語句。
執行任意 SQL 語句最簡單的方法是使用 EXECUTE IMMEDIATE
命令。例如
EXEC SQL BEGIN DECLARE SECTION; const char *stmt = "CREATE TABLE test1 (...);"; EXEC SQL END DECLARE SECTION; EXEC SQL EXECUTE IMMEDIATE :stmt;
EXECUTE IMMEDIATE
可以用於不返回結果集的 SQL 語句(例如,DDL、INSERT
、UPDATE
、DELETE
)。您不能以這種方式執行檢索資料的語句(例如,SELECT
)。下一節描述如何做到這一點。
執行任意 SQL 語句更強大的方法是準備語句一次,然後根據需要多次執行準備好的語句。也可以準備語句的通用版本,然後通過替換參數來執行其特定版本。準備語句時,在要稍後替換參數的地方寫入問號。例如
EXEC SQL BEGIN DECLARE SECTION; const char *stmt = "INSERT INTO test1 VALUES(?, ?);"; EXEC SQL END DECLARE SECTION; EXEC SQL PREPARE mystmt FROM :stmt; ... EXEC SQL EXECUTE mystmt USING 42, 'foobar';
當您不再需要預先準備的語句時,應該將其釋放
EXEC SQL DEALLOCATE PREPARE name
;
要執行帶有單個結果列的 SQL 語句,可以使用 EXECUTE
。 要儲存結果,請添加 INTO
子句。
EXEC SQL BEGIN DECLARE SECTION; const char *stmt = "SELECT a, b, c FROM test1 WHERE a > ?"; int v1, v2; VARCHAR v3[50]; EXEC SQL END DECLARE SECTION; EXEC SQL PREPARE mystmt FROM :stmt; ... EXEC SQL EXECUTE mystmt INTO :v1, :v2, :v3 USING 37;
EXECUTE
命令可以具有 INTO
子句、USING
子句、兩者都有或兩者都沒有。
如果預期查詢返回多個結果列,則應使用游標,如下例所示。(有關游標的更多詳細資訊,請參閱第 34.3.2 節。)
EXEC SQL BEGIN DECLARE SECTION; char dbaname[128]; char datname[128]; char *stmt = "SELECT u.usename as dbaname, d.datname " " FROM pg_database d, pg_user u " " WHERE d.datdba = u.usesysid"; EXEC SQL END DECLARE SECTION; EXEC SQL CONNECT TO testdb AS con1 USER testuser; EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT; EXEC SQL PREPARE stmt1 FROM :stmt; EXEC SQL DECLARE cursor1 CURSOR FOR stmt1; EXEC SQL OPEN cursor1; EXEC SQL WHENEVER NOT FOUND DO BREAK; while (1) { EXEC SQL FETCH cursor1 INTO :dbaname,:datname; printf("dbaname=%s, datname=%s\n", dbaname, datname); } EXEC SQL CLOSE cursor1; EXEC SQL COMMIT; EXEC SQL DISCONNECT ALL;
如果您在文件中看到任何不正確的地方、與特定功能的經驗不符或需要進一步說明的地方,請使用此表單來報告文件問題。