【问题标题】:Differences in SQL Window vs. PSQLSQL Window 与 PSQL 的区别
【发布时间】:2015-01-02 06:23:23
【问题描述】:

我正在运行 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 解决这个问题,我将不胜感激。

【问题讨论】:

  • 我认为psql -U (user) -d test -f "C:\test\function.sql 之间必须有一个空格如果它工作正常试试这个,然后我会解释它为什么会发生。
  • 绝对确定在这两种情况下你都连接到同一个 PostgreSQL 实例上的同一个数据库吗?
  • 您确定在这两种情况下您都以同一用户的身份连接。
  • psql 和 pgAdmin 一样是客户端。如果您的代码在使用 pgAdmin 的数据库上工作,它也适用于使用不同客户端(如 pgsql)的同一个数据库(!)。
  • @snm_onrocks 这是输入错误。

标签: postgresql plpgsql psql postgresql-9.3 pgadmin


【解决方案1】:

如果customer.customer_uid 在一个客户端中对%TYPE declaration 有效,但在另一个客户端中无效,则一定是可见性 的问题。

您的search_path 设置不同或临时表起作用(仅在同一会话中可见)。您可以通过多种方式防御所有可能的原因。这里有两个:

假设表 customer 存在于架构 my_schema 中:

1。架构限定参考:

cust_uid  <b>my_schema.</b>customer.customer_uid%TYPE := 0;

2。 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 <strike>A.</strike>date_last_paid = cust_date_last_paid

根据文档:

不要在目标规范中包含表的名称 列 — 例如,UPDATE tab SET tab.col = 1 无效。

我没有进一步审核。

【讨论】:

    猜你喜欢
    • 2012-03-14
    • 1970-01-01
    • 2021-03-10
    • 1970-01-01
    • 2015-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多