Postgres:在特定数据库中创建函数

4

代码:

CREATE FUNCTION square_num(num integer)
 RETURNS INTEGER AS $$

BEGIN

 IF (num<0) THEN
 RETURN 0;
 END IF;

 RETURN num*num;

END; $$
LANGUAGE PLPGSQL;

上述代码在数据库postgres和模式public中创建了一个函数。我该如何在特定的数据库及其模式中创建函数?谢谢。


你的意思是将我的函数所有者更改为特定数据库的模式吗??在创建函数时我不能指定数据库名称吗?? - wonder
您可以通过执行 ALTER FUNCTION square_num(num) SET SCHEMA your_schema_name 来更改模式。 - Cátia Matos
要更改函数所有者,请执行以下操作:ALTER FUNCTION your_schema_name.square_num() OWNER TO your_user; - Cátia Matos
“ALTER FUNCTION square_num(num integer) SET SCHEMA your_schema_name;” 如果模式在同一数据库中,则似乎可以正常工作。但是我将模式放在另一个数据库中。 - wonder
连接到你想要在其中创建fn()的数据库,然后只需创建它(可选择在Postgres数据库中删除fn())。这将是“移动”它跨数据库的过程。 - Vao Tsun
显示剩余5条评论
1个回答

9

以上代码在数据库postgres和public架构中创建了一个函数。

不是的。它会在你连接的数据库中,从search_path中第一个已存在的架构中创建函数。

例如:

-bash-4.2$ psql t
psql (10.1)
Type "help" for help.

t=# create table tt();
CREATE TABLE
t=# select table_catalog,table_schema from information_schema.tables where table_name = 'tt';
 table_catalog | table_schema
---------------+--------------
 t             | public
(1 row)

我在连接中定义了数据库名称t,因此关系在数据库t中创建。 我没有模式postgres,因此跳过$user,下一个“默认”模式是public

t=# show search_path;
   search_path
-----------------
 "$user", public
(1 row)

所以现在:

t=# create schema postgres;
CREATE SCHEMA
t=# create table tt();
CREATE TABLE

看到“关系已存在”没有错误,因为:

t=# select table_catalog,table_schema from information_schema.tables where table_name = 'tt';
 table_catalog | table_schema
---------------+--------------
 t             | public
 t             | postgres
(2 rows)

函数创建遵循相同的规则,我使用表格作为更短的语法...

阅读:https://www.postgresql.org/docs/current/static/ddl-schemas.html#DDL-SCHEMAS-PATH

搜索路径中存在的第一个模式是创建新对象的默认位置。

最终回答:

如何在特定的数据库及其模式中创建函数?

连接到需要的数据库,然后明确指定模式名称:

CREATE FUNCTION my_schema.square_num(...and so on

或者在满足您需求的情况下调整search_path

为了清晰起见,我使用架构名称 postgres 来符合原始帖子。对于新用户而言,使用postgres数据库和创建postgres模式都可能会令人困惑。默认的 postgres 数据库并没有什么特别之处(可以随时从模板重新创建),而且名称 postgres 也不会给架构带来任何特殊属性。我只是为了让OP更容易重现示例(因为从他连接到postgres数据库的事实来看,用户可能没有指定数据库名称,以OS用户 postgres 的身份连接)。因此,为了演示如何选择 search_path 的第一个值 $ user ,我使用了与用户名相同的名称...


我对这个答案感到无语。非常清晰明了的解释。非常感谢。你的回答解决了我的一些问题。只需要编辑一下答案——第二次创建表格时应该是tt()而不是ii() - wonder
个人而言,我会为新创建的模式选择一个不同的名称。postgres 可能会让初学者感到困惑(因为他们可能会认为它是特殊的、保留的或关键字,但在这种情况下并非如此)。 - wildplasser
我选择它是因为 OP 连接时使用 postgres 用户,所以 $user 显然是 postgres 用户模式。 - Vao Tsun
我认为连接用户为postgres是一个不好的习惯(对于新用户)。此外,系统<-->postgres用户名的解耦应该被规定。 - wildplasser
1
我完全支持这种观点。但是我不会覆盖整篇文章,因为这样会失去它简洁的外观。我将使用“注”来更新它。感谢您的注意。 - Vao Tsun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接