我正在运行PostgreSQL 9.3.5,并且发现在PSQL中创建函数与pgAdmin SQL窗口之间存在差异。我有一个我想通过PSQL创建(和部署)的功能。
代码是:
CREATE OR REPLACE FUNCTION sync_division_owner_customer_owner_number()
RETURNS trigger AS
$BODY$
DECLARE
row_count integer := 0;
cust_uid customer.customer_uid%TYPE := 0;
cust_date_last_paid customer_owner_number.date_last_paid%TYPE;
BEGIN
SELECT COALESCE(customer_uid,0) INTO cust_uid FROM division_order D WHERE D.division_order_uid = NEW.division_order_uid;
IF cust_uid = 0 THEN
RAISE EXCEPTION 'customer_uid found for function sync_division_owner_customer_owner_number';
END IF;
SELECT count(*) INTO row_count FROM customer_owner_number A WHERE A.customer_uid = cust_uid AND A.owner_number = NEW.owner_number;
CASE row_count
WHEN 0 THEN
INSERT INTO customer_owner_number(owner_number, date_first_paid, date_last_paid, customer_uid, deadfiled)
VALUES(NEW.owner_number, NEW.date_last_paid, NEW.date_last_paid, cust_uid, TRUE);
WHEN 1 THEN
SELECT A.date_last_paid INTO cust_date_last_paid FROM customer_owner_number A WHERE A.customer_uid = cust_uid AND A.owner_number = NEW.owner_number;
IF cust_date_last_paid < NEW.date_last_paid THEN
UPDATE customer_owner_number A SET A.date_last_paid = cust_date_last_paid
WHERE A.customer_uid = cust_uid AND A.owner_number = NEW.owner_number;
END IF;
END CASE;
RETURN NEW;
END
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
当我使用:psql -U (user) -d test -f "C:\test\function.sql"
运行此文件时出现错误:
ERROR: invalid type name "customer.customer_uid%TYPE"
然而,如果我在SQL窗口中运行这个完全相同的代码,我完全没有问题,并且它创建了它应该的功能。我需要使用%TYPE
变量,因此不能更改它。
我很感激有人告诉我还有什么办法可以解决PSQL问题。
答案 0 :(得分:0)
如果customer.customer_uid
对一个客户端中的%TYPE
declaration有效,但对另一个客户端无效,则必须是可见性的问题。
您的search_path
设置不同或临时表发挥作用(仅在同一会话中可见)。您可以通过多种方式抵御所有可能的原因。这是两个:
假设表格customer
位于架构my_schema
:
cust_uid my_schema.customer.customer_uid%TYPE := 0;
SET
search_path
表示函数范围:CREATE OR REPLACE FUNCTION sync_division_owner_customer_owner_number()
RETURNS void AS
$func$
...
$func$ LANGUAGE plpgsql
SET search_path = my_schema,public,pg_temp;
注意您的触发器功能仍然无法正常工作,因为至少还有一个语法错误:
UPDATE customer_owner_number A SET A.date_last_paid = cust_date_last_paid
每份文件:
不要在目标规范中包含表格的名称 列 - 例如,
UPDATE tab SET tab.col = 1
无效。
我没有进一步审核。