如何测试给定的文本列是否为有效的oid

时间:2018-12-04 23:16:07

标签: postgresql plpgsql typechecking

在PL / pgSQL中,我有一列可能包含或可能不包含oid。我需要检测是否这样做。

此刻我是这样的:

  select oidtext from t into x where name = fname;
  if found then
    begin
        select x::oid into looid;
    exception
        when SQLSTATE '22P02' then -- invalid oid    
           null;

但是感觉有点不客气。是否存在肯定的测试,即“此文本列是有效的x类型”还是“这是有效的强制类型转换”?

2 个答案:

答案 0 :(得分:2)

似乎唯一的方法是捕获异常,但是您可以在这样的便捷函数中做到这一点:

create or replace function oid_or_null(text)
returns oid language plpgsql immutable as $$
begin
    return $1::oid;
exception when invalid_text_representation then
    return null;
end $$;

select oid_or_null('123'), oid_or_null('abc');

 oid_or_null | oid_or_null 
-------------+-------------
         123 |            
(1 row) 

您可以创建一个更通用的布尔函数:

create or replace function is_valid_cast(text, text)
returns boolean language plpgsql immutable as $$
begin
    execute format('select %L::%I', $1, $2);
    return true;
exception when others then
    return false;
end $$;

select 
    is_valid_cast('123', 'oid') as oid, is_valid_cast('abc', 'oid') as not_oid,
    is_valid_cast('2018-10-10', 'date') as date, is_valid_cast('2018-20-20', 'date') as not_date;

 oid | not_oid | date | not_date 
-----+---------+------+----------
 t   | f       | t    | f
(1 row)     

答案 1 :(得分:2)

我的解决方案不需要捕获错误: CREATE FUNCTION is_oid(text)返回布尔值    语言sql不可变严格AS 修剪时的$$ SELECT情况(从$ 1开头'0')〜'^ \ d {1,10} $'               然后$ 1 :: bigint在0和4294967295之间               否则为假          END $$; oid是一个4字节的无符号整数,因此它必须包含不超过10个数字,并且介于0和4294967295之间。