Sql 函数显示错误“关系my_表不存在”

Sql 函数显示错误“关系my_表不存在”,sql,postgresql,function,plpgsql,search-path,Sql,Postgresql,Function,Plpgsql,Search Path,我创建了一个函数来生成发票号,但当我这样做时: select get_generated_kodesj() 它显示了一个错误: 关系transpending_h不存在 第19行:…结束为KodeTrans从transpendi新建 这里是我的函数声明: CREATE FUNCTION get_generated_kodesj() RETURNS CHAR AS $$ DECLARE kodeSJ CHAR; BEGIN SELECT CASE WHE

我创建了一个函数来生成发票号,但当我这样做时:

select get_generated_kodesj()
它显示了一个错误:

关系transpending_h不存在 第19行:…结束为KodeTrans从transpendi新建

这里是我的函数声明:

CREATE FUNCTION get_generated_kodesj()
RETURNS CHAR AS $$
DECLARE kodeSJ CHAR;
BEGIN      
        SELECT
        CASE WHEN MAX(RIGHT("KODETRANS",4)) IS NULL THEN
        CONCAT('SJ-',EXTRACT(YEAR FROM NOW()),LPAD(CAST(EXTRACT(MONTH from NOW()) AS CHAR), 2 ,'0'),'0001')
        ELSE
        CASE WHEN MAX(CAST(RIGHT("KODETRANS",4) AS INTEGER))+1<10 THEN
        CONCAT('SJ-',EXTRACT(YEAR FROM NOW()),LPAD(CAST(EXTRACT(MONTH from NOW()) AS CHAR), 2 ,'0'),'000',
        MAX(CAST(RIGHT("KODETRANS",4) AS INTEGER))+1)
        ELSE
        CASE WHEN MAX(CAST(RIGHT("KODETRANS",4) AS INTEGER))+1<100 AND MAX(CAST(RIGHT("KODETRANS",4) AS INTEGER))+1>=10 THEN
        CONCAT('SJ-',EXTRACT(YEAR FROM NOW()),LPAD(CAST(EXTRACT(MONTH from NOW()) AS CHAR), 2 ,'0'),'00',
        MAX(CAST(RIGHT("KODETRANS",4) AS INTEGER))+1)
        ELSE 
        CASE WHEN MAX(CAST(RIGHT("KODETRANS",4) AS INTEGER))+1<1000 AND MAX(CAST(RIGHT("KODETRANS",4) AS INTEGER))+1>=100 THEN
        CONCAT('SJ-',EXTRACT(YEAR FROM NOW()),LPAD(CAST(EXTRACT(MONTH from NOW()) AS CHAR), 2 ,'0'),'0',
        MAX(CAST(RIGHT("KODETRANS",4) AS INTEGER))+1)
        ELSE 
        CONCAT('SJ-',EXTRACT(YEAR FROM NOW()),LPAD(CAST(EXTRACT(MONTH from NOW()) AS CHAR), 2 ,'0'),
        MAX(CAST(RIGHT("KODETRANS",4) AS INTEGER))+1)
        END END END END AS "KODETRANSNEW" INTO kodeSJ
        FROM transpending_h
        WHERE SUBSTRING("KODETRANS" FROM 5 FOR 4)=CAST(EXTRACT(YEAR from NOW()) AS CHAR)
        AND SUBSTRING("KODETRANS" FROM 9 FOR 2)=CAST(EXTRACT(MONTH from NOW()) AS CHAR);
    RETURN kodeSJ;
END;
$$  LANGUAGE plpgsql
    SECURITY DEFINER
    -- Set a secure search_path: trusted schema(s), then 'pg_temp'.
    SET search_path = admin, pg_temp;
这里可能有什么问题?

您评论道:


但是我已经创建了这个表,在我声明这个函数之前,我运行这个查询,选择一些东西,它就可以工作了

您创建了表,但显然不是在schema admin中,它是函数的自定义搜索路径中除temp schema和隐式pg_目录之外的唯一一个表。检查:

模式限定函数体中的表,错误应该消失。比如:myschema.transpending_h

相关的:

旁白 您使用数据类型char进行操作,这是一个误解:

改为使用文本

如果可以避免的话,不要使用双引号标识符。只会带来开销和混乱

对于这个简单的选择,您不需要plpgsql。我建议使用普通的SQL函数

仔细观察,您的功能几乎所有方面都可以改进。基本上,您每个月都在增加序列号。可以简化为:

CREATE FUNCTION get_generated_kodesj()
  RETURNS text AS
$func$
   SELECT to_char(now(), '"SJ-"YYYYMM')
       || COALESCE(to_char(MAX(RIGHT("KODETRANS",4))::int + 1, 'FM0000'), '0001')
   FROM   transpending_h
   WHERE  "KODETRANS" LIKE to_char(now(), '"SJ-"YYYYMM"%"')
                        -- assuming your codes start with "SJ-"; else adapt
$func$  LANGUAGE sql
        SECURITY DEFINER
        SET search_path = admin, pg_temp;
相关的:

但在多用户环境中,整个方法仍然受到竞争条件的影响。将全局序列或标识列与日期或时间戳结合使用,而不是尝试创建自己的每月序列。见:

如果您需要每月的序列号,请考虑在多用户环境中避免竞争条件的不同方法:


我假设您确定当前模式中确实存在transpending_h关系。对吗?但我已经创建了这个表,在声明这个函数之前,我运行这个查询,选择一些东西,它就可以工作了。我明白了。从语法上来说,你的函数很好。如果您没有在不同的模式/不同的数据库中执行查询和函数,请仔细检查。祝你好运安全定义器意味着您希望与其他用户一起运行此fn,而不是fn创建者-对吗?另一个用户是否具有transpending_h在其搜索路径中所处的架构?。您使用的是区分大小写的列名KODETRANS与KODETRANS不同可能您的表也是全大写创建的?因此,您需要使用从TRANSPENDING_H
CREATE FUNCTION get_generated_kodesj()
  RETURNS text AS
$func$
   SELECT to_char(now(), '"SJ-"YYYYMM')
       || COALESCE(to_char(MAX(RIGHT("KODETRANS",4))::int + 1, 'FM0000'), '0001')
   FROM   transpending_h
   WHERE  "KODETRANS" LIKE to_char(now(), '"SJ-"YYYYMM"%"')
                        -- assuming your codes start with "SJ-"; else adapt
$func$  LANGUAGE sql
        SECURITY DEFINER
        SET search_path = admin, pg_temp;