我們經常使用快速的一次性SQL文件來插入或更新現有數據庫中的數據。 SQL通常由開發人員編寫,在開發系統上進行測試,然後使用psql -U dbuser dbname < file.sql
導入生產數據庫。替代PostgreSQL中的MySQL變量?
A(簡單)的例子可能是這樣的:
INSERT INTO employees (
company_id,
name,
position,
created_by,
last_modified_by
) VALUES
(
(SELECT id FROM companies WHERE name = 'Acme Fellowship'),
'Frodo Baggins',
'Ring bearer',
(SELECT id FROM users WHERE login = 'admin'),
(SELECT id FROM users WHERE login = 'admin')
),
(
(SELECT id FROM companies WHERE name = 'Acme Fellowship'),
'Samwise Gamgee',
'Rope bearer',
(SELECT id FROM users WHERE login = 'admin'),
(SELECT id FROM users WHERE login = 'admin')
),
(
(SELECT id FROM companies WHERE name = 'Acme Fellowship'),
'Peregrin Took',
'Ent rider',
(SELECT id FROM users WHERE login = 'admin'),
(SELECT id FROM users WHERE login = 'admin')
);
雖然這個作品,有很多的子查詢重複的代碼。如果將臨時變量中的和users.id
的相關值存儲在臨時變量中,那將會更好(更高效且更少錯誤)。在這個解釋的例子中,性能差異可能很小,但實際上我們確實有更復雜的查詢和更新,並且通常有三個以上的更新/插入記錄。
爲MySQL寫同樣的例子是這樣的:
SELECT @company_id := id FROM companies WHERE name = 'Acme Fellowship';
SELECT @admin_id := id FROM users WHERE login = 'admin';
INSERT INTO employees (
company_id,
name,
position,
created_by,
last_modified_by
) VALUES
(@company_id, 'Frodo Baggins', 'Ring bearer', @admin_id, @admin_id),
(@company_id, 'Samwise Gamgee', 'Rope bearer', @admin_id, @admin_id),
(@company_id, 'Peregrin Took', 'Ent rider', @admin_id, @admin_id);
有沒有辦法實現的PostgreSQL類似的東西?
我已經看了:
- psql的會話變量(與
\set
):不能用於存儲查詢結果 - PLPGSQL:只能在過程中使用(我們仍在運行8.4)
- 臨時表:我不知道怎樣使用它們不會產生難看的和令人費解的語句
如果沒有直接的等價物的Postgres,你覺得什麼W¯¯應該是產生這種更新文件的最笨拙的方式?
非常優雅,謝謝。 – Zilk 2012-01-08 12:01:46
CTE不能在8.4版本中工作,它不支持INSERT。你至少需要9.1版本。 – 2012-01-08 12:35:02
@FrankHeikens:好點。這就是爲什麼我最終在這裏使用子查詢。 – 2012-01-08 14:20:14