jdo*_*dot 5 sql postgresql views
我从 PostgreSQL 视图开始,因为它们对我的用例很有用,并且会提供比函数更好的性能。
(这无关紧要,但我在 Heroku Postgres 上使用 Django 1.7 以防万一)。
我已经创建了一个视图并且可以很好地查询它。我想围绕视图编写一个 Django 包装器,以便我可以将它视为一个表,并相应地查询和写入它。我一直在查看
Postgres 文档INSERT和UPDATE查看意见,但老实说,我发现他们的文档很难阅读,我几乎无法解析他们在说什么。
假设我有以下观点:
CREATE OR REPLACE VIEW links AS
SELECT
listing.id AS listing_id,
CONCAT('/i-', industry.slug, '-j-', listing.slug, '/') AS link,
'https://www.example.com' || CONCAT(industry.slug, '-SEP-', listing.slug, '/') AS full_link,
listing.slug AS listing_slug,
industry.slug AS industry_slug
FROM listing
INNER JOIN company ON company.id = listing.company_id
INNER JOIN industry ON industry.id = company.industry_id
Run Code Online (Sandbox Code Playgroud)
在这里,我正在使用industry.slug和listing.slug来构建链接。我希望能够从此视图更新这两个字段,例如:
UPDATE links
SET listing_slug = 'my-new-slug'
WHERE listing_id = 5;
Run Code Online (Sandbox Code Playgroud)
如何创建规则以正确执行此操作?
由于双重连接,最好使用触发器过程。要更新行业表,您需要首先使用外键listing-company-industry查找industry.id。程序可能如下所示:
CREATE OR REPLACE FUNCTION update_listing_and_industry() RETURNS TRIGGER AS
$$
DECLARE _company_id int; _industry_id int;
BEGIN
_company_id = (SELECT company_id FROM listing WHERE id = OLD.listing_id);
_industry_id = (SELECT industry_id FROM company WHERE id = _company_id);
UPDATE listing SET slug = NEW.listing_slug WHERE id = OLD.listing_id;
UPDATE industry SET slug = NEW.industry_slug WHERE id = _industry_id;
RETURN NEW;
END;
$$
LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
注意:触发器过程是返回 TRIGGER 的正常过程。根据触发器执行的操作,过程必须返回 NEW 或 OLD(在本例中为 NEW)。
以及带有子句的触发器INSTEAD OF UPDATE:
CREATE trigger update_view INSTEAD OF UPDATE ON links
FOR EACH ROW EXECUTE PROCEDURE update_listing_and_industry();
Run Code Online (Sandbox Code Playgroud)