search_path在PostgreSQL函数开发中的注意事项

背景

PostgreSQL 与大多数数据库一样,通过schema,逻辑上划分对象的归属,如图。

用户还可以参考《PostgreSQL 逻辑结构 和 权限体系 介绍》

因为有了schema的概念,在访问数据库中的对象时,我们需要指定是哪个schema下面的。

例如schema_a.table。

为了方便用户使用,PostgreSQL 还有一个客户端的环境参数叫search_path,用来控制搜索路径的顺序。

例如 search_path= '"$user",public' 表示优先搜索与当前用户名同名的schema,如果没有则搜索public schema。

例如 当前用户为a, 在数据库中有一张表是a.tbl还有一张表public.tbl。 那么select * from tbl,访问的是a.tbl。

函数编写注意事项

我们在写函数时,很容易忽略一点,就是搜索路径。

比如我写了一个这样的函数

sanity=> CREATE OR REPLACE FUNCTION "digoal"."getbusinessname"("ptypeno" varchar)
  RETURNS "pg_catalog"."varchar" AS $BODY$

        BEGIN

                RETURN (select typename from tbl_core_bus where typeno= ptypeno);

        END;

$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
CREATE FUNCTION

会有点乱哦,tbl_core_bus表到底是哪个schema下的呢?
与search_path有关,所以如果在search_path中没有这个表时,访问这个函数就会报错。

因此在写函数时务必注意,使用schema,避免这种问题。

上面的函数可以改成如下,在访问对象的前面加上schema表示

CREATE OR REPLACE FUNCTION "digoal"."getbusinessname"("ptypeno" varchar)
  RETURNS "pg_catalog"."varchar" AS $BODY$

        BEGIN

                RETURN (select typename from digoal.tbl_core_bus where typeno= ptypeno);

        END;

$BODY$
  LANGUAGE 'plpgsql' VOLATILE;

或者改成如下,设置函数的参数search_path

CREATE OR REPLACE FUNCTION "digoal"."getbusinessname"("ptypeno" varchar)
  RETURNS "pg_catalog"."varchar" AS $BODY$

        BEGIN

                RETURN (select typename from tbl_core_bus where typeno= ptypeno);

        END;

$BODY$
  LANGUAGE 'plpgsql' VOLATILE set search_path='digoal';

或者改成如下,在函数内使用set命令设置search_path

CREATE OR REPLACE FUNCTION "digoal"."getbusinessname"("ptypeno" varchar)
  RETURNS "pg_catalog"."varchar" AS $BODY$

        BEGIN
        set search_path='digoal';

                RETURN (select typename from tbl_core_bus where typeno= ptypeno);

        END;

$BODY$
  LANGUAGE 'plpgsql' VOLATILE ;

祝大家玩得开心,欢迎随时来 阿里云促膝长谈业务需求 ,恭候光临。

阿里云的小伙伴们加油,努力 做好内核与服务,打造最贴地气的云数据库

时间: 2024-09-23 01:22:08

search_path在PostgreSQL函数开发中的注意事项的相关文章

c++ 在AUTOCAD的二次开发中的注意事项,求大神指点!万分感谢

问题描述 c++ 在AUTOCAD的二次开发中的注意事项,求大神指点!万分感谢 c++ 在AutoCAD开发中的应用 ,是不是最适合的开发工具,怎么进行学习开发,我是一个小白 ,求各位大神指点 解决方案 C++对AutoCAD的二次开发主要引用AutoCAD发布的函数库,也就是SDK.AutoCAD有针对C++的编程模型,你可以用AutoCAD发布的C++函数库来操作该模型,最后编译生成arx文件文件,在arx文件里面有注册AutoCAD命令的语句,然后在AutoCAD里面加载编译生成的arx文

Android生存指南之:开发中的注意事项_Android

1. 为Activity声明系统配置变更事件系统配置变更事件是指转屏,区域语言发生变化,屏幕尺寸发生变化等等,如果Activity没有声明处理这些事件,发生事件时,系统会把Activity杀掉然后重启,并尝试恢复状态,Activity有机会通过onSaveInstanceState()保存一些基本数据到Bundle中,然后此Bundle会在Activity的onCreate()中传递过去.虽然这貌似正常,但是这会引发问题,因为很多其他的东西比如Dialog等是要依赖于具体Activity实例的.

Android生存指南之:开发中的注意事项

1. 为Activity声明系统配置变更事件 系统配置变更事件是指转屏,区域语言发生变化,屏幕尺寸发生变化等等,如果Activity没有声明处理这些事件,发生事件时,系统会把Activity杀掉然后重启,并尝试恢复状态,Activity有机会通过onSaveInstanceState()保存一些基本数据到Bundle中,然后此Bundle会在Activity的onCreate()中传递过去.虽然这貌似正常,但是这会引发问题,因为很多其他的东西比如Dialog等是要依赖于具体Activity实例的

iOS开发中常用的数学函数

iOS开发中常用的数学函数   /*---- 常用数学公式 ----*/ //指数运算 3^2 3^3 NSLog(@"结果 %.f", pow(3,2)); //result 9 NSLog(@"结果 %.f", pow(3,3)); //result 27 //开平方运算 NSLog(@"结果 %.f", sqrt(16)); //result 4 NSLog(@"结果 %.f", sqrt(81)); //result

在PL/SQL 开发中调试存储过程和函数的一般性方法

存储过程|函数 在PL/SQL 开发中调试存储过程和函数的一般性方法摘要: Oracle 在PLSQL中提供的强大特性使得数据库开发人员可以在数据库端完成功能足够复杂的任务, 本文将结合Oracle提供的相关程序包(package)以及一个非常优秀的第三方开发工具来介绍在PLSQL中开发及调试存储过程的方法,当然也适用于函数. 版权声明: 本文可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息.原文出处: http://www.aiview.com/notes/ora_using_

asp开发中常用函数

asp教程开发中常用函数 sub lastnextpage(pagecount,page,table_style,font_style) '生成上一页下一页链接  dim query, a, x, temp  action = "http://" & request.servervariables("http_host") & request.servervariables("script_name")  query = spli

c-手持器开发中,事件引发的函数中怎样使用父函数中的变量

问题描述 手持器开发中,事件引发的函数中怎样使用父函数中的变量 求高手解决一个问题.我用GNU for ARM编译器编写手持器程序,C语言.在一个函数function1()中有一个变量a:函数中触发事件OnClick=function2:事件触发函数为 int function2(HWND Obj,PMsg Msg): 怎样才能使得变量a在function2函数中也能用,我不想用全局变量,而function2又不能有其他参数. 求大神帮忙解决.

js开发中常用日期时间函数

js开发中常用日期时间函数 字符串转成日期类型,date.prototype.isleapyear 判断闰年 date.prototype.format 日期格式化 date.prototype.dateadd 日期计算 date.prototype.datediff 比较日期差 date.prototype.tostring 日期转字符串 date.prototype.toarray 日期分割为数组 date.prototype.datepart 取日期的部分信息 date.prototype

Android开发中findViewById()函数用法与简化

Android中FindViewById()是一个非常常用的函数,位于android.app.Activity包中.该函数利用我们在XML文件中定义的View的id属性来获取相应的View对象.findViewById()属于API Level 1, 对应的android版本是android1.0, 由此,可以看出,该函数是android早期版本中就有的.顺便说一下, android目前市场上已商用的版本及其对应的API Level如下: android 1.0API Level 1 andro