我写了一个PLpgSQL函数,它应该返回SETOF products
table:
CREATE OR REPLACE FUNCTION get_products_by_category
(selected_category_id smallint DEFAULT 1) RETURNS SETOF products AS
$BODY
$BEGIN
RETURN QUERY (SELECT * FROM products WHERE CategoryID = selected_category_id);
END;
$BODY$
LANGUAGE plpgsql VOLATILE NOT LEAKPROOF
COST 100
ROWS 1000;
接下来我想在另一个函数中迭代结果(未完成的视图,因为我尝试添加PgAdmin III并且我有错误):
DECLARE
R RECORD;
BEGIN
IF TG_TABLE_NAME != 'Categories' THEN
RAISE 'This trigger function is for Categories, but was called for %', TG_TABLE_NAME;
FOR R IN get_products_by_category(1) LOOP
UPDATE products SET CategoryID = NEW.id WHERE id = R.id;
RETURN NEW;
我的想法是我在数据库中有一些产品,其默认类别ID为1.然后,当添加新类别时,会触发触发器,更新CategoryID
(来自新添加的对象)默认CategoryID
- 也许这听起来很愚蠢,但我正在学习Northwind数据库的触发器,我不得不为自己创建任务。 :)
但由于错误near get_products_by_category(1)
,我无法保存。
在PLpgSQL(我使用的是9.3版本)中,有可能编写类似Java的东西:
for (Product product: dao.getProductsByCategory(categoryId))
更新的代码:
DECLARE
selected_products products[];
product products;
BEGIN
IF TG_TABLE_NAME != 'categories' THEN
RAISE 'This trigger function is for Categories, but was called for %', TG_TABLE_NAME;
END IF;
selected_products := get_products_by_category(1);
FOR product IN selected_products LOOP
UPDATE products SET CategoryID = NEW.id
WHERE id = R.id;
END LOOP;
RETURN NEW;
END;
答案 0 :(得分:2)
基本上,您需要阅读手册中的这一章:Looping Through Query Results 关于plpgsql trigger functions。
CREATE OR REPLACE FUNCTION my_trigger_func()
RETURNS trigger AS
$func$
DECLARE
_prod products;
BEGIN
IF TG_TABLE_NAME <> 'categories' THEN
RAISE EXCEPTION 'Trigger func for "categories", not for %', TG_TABLE_NAME;
END IF;
FOR _prod IN
SELECT * FROM get_products_by_category(1)
LOOP
UPDATE products p
SET categoryid = NEW.id
WHERE p.id = _prod.id;
END LOOP;
RETURN NEW;
END
$func$ LANGUAGE plpgsql
或者:
...
DECLARE
_id int;
BEGIN
...
FOR _id IN
SELECT id FROM get_products_by_category(1)
LOOP
...
WHERE p.id = _id;
...
两者都只是作为概念的证明。大多数时候,基于集合的解决方案即将推出。像这里:
UPDATE products p
SET categoryid = NEW.id
FROM get_products_by_category(1) x
WHERE p.id = x.id;
您可以使用像get_products_by_category(1)
这样的集合返回函数,就像在大多数情况下使用表格一样。
你必须理解美元报价:
!=
也是有效的,而是使用SQL标准运算符<>
。
表名不是唯一的。确保您必须检查TG_TABLE_NAME
和TG_TABLE_SCHEMA
。