postgresql - 以 VARCHAR 作为参数的 PL/pgSQL 函数

标签 postgresql plpgsql

我正在尝试编写一个带有 VARCHAR 参数的 PL/pgSQL 函数,这应该是有限的。考虑以下函数,其中 VARCHAR 参数的大小限制为 5 个字符:

CREATE OR REPLACE FUNCTION do_nothin(v_value VARCHAR(5)) 
RETURNS TEXT AS
$$
DECLARE
BEGIN
    RETURN v_value;
END;
$$
LANGUAGE plpgsql;

当我用大于 5 的文本调用此函数时,它确实有效:

DO $$
DECLARE
BEGIN
    PERFORM do_nothin('123456');
END;
$$

它给了我结果“123456”,但为什么呢?这应该给我一个错误吧?

如果我这样定义一个varchar:

DO $$
DECLARE
    v_mytext VARCHAR(5);
BEGIN
    v_mytext := '123456';
END;
$$

它给我一个预期的错误:

 ERROR: value too long for type character varying(5) CONTEXT: PL/pgSQL      function inline_code_block line 5 at assignment SQL state: 22001

我想在函数的参数太大时抛出这个错误,但是怎么做呢?

最佳答案

出于历史原因,PostgreSQL 忽略函数参数类型 (typmod) 中的大小修饰符。存在一些与实现相关的问题,简单且足够好的解决方案是忽略此类型功能 - varchar 的预期行为很简单,但可能很难为数字类型设计正确且用户友好的行为。

create or replace function fx(a varchar(10)) 
returns varchar as $$ begin return a; end $$ language plpgsql;

postgres=# \sf fx
CREATE OR REPLACE FUNCTION public.fx(a character varying)
RETURNS character varying
LANGUAGE plpgsql
AS $function$ begin return a; end $function$

您可以看到 - typmod 值不是持久的 - 然后没有效果。

如果你真的需要一些限制,那么你应该使用域类型:

postgres=# create domain varchar_10 as varchar(10);
CREATE DOMAIN
postgres=# create or replace function fx2(a varchar_10)
returns varchar as $$ begin return a; end $$ language plpgsql
CREATE FUNCTION
postgres=# select fx2('12345678901');
ERROR:  value too long for type character varying(10)

域是所有(类型修改、检查)的持久类型同义词。

关于postgresql - 以 VARCHAR 作为参数的 PL/pgSQL 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47480161/

相关文章:

postgresql - 使用 Postgresql 主分区表与子表一起插入行是否正常?

postgresql - PostgreSQL 配置文件的备用位置

postgresql - 如何在不同的模式上运行相同的功能

sql - 一个 SQL 函数调用中的多个 ALTER TABLE ADD COLUMN

java - 如何使用 JPA Criteria API 过滤 PostgreSQL 数组列?

ruby-on-rails - 无法在 Nitrous.io 上创建数据库

django - 如何根据 ManyToManyField 中的多个值来订购模型?

postgresql - 创建创建新序列的过程/函数

postgresql - 如何在另一个过程中调用存储过程并在Postgresql的同一个过程中使用它的结果?

sql - 如何将命名参数传递给postgres中存储过程中的where子句