将函数从oracle转换为PostgreSQL

Zac*_*rke 4 database oracle postgresql plpgsql

我正在将某些东西从Oracle转换为PostgreSQL。在Oracle文件中,有一个功能:

instr(string,substring,starting point,nth location)
Run Code Online (Sandbox Code Playgroud)

或它在我的文件中

instr(string,chr(10),instr(string,substring),1)
Run Code Online (Sandbox Code Playgroud)

在PostgreSQL中不存在,因此我查找了一个等效函数。我发现:

position(substring in string)
Run Code Online (Sandbox Code Playgroud)

但这不允许起始位置和第n个位置参数。

无论如何,要使此功能在给定的点开始?还是在PostgreSQL中可以使用更好的功能来指定起始位置和第n个位置?

这将必须在PostgreSQL 8.2.15上工作,因为那是我们在数据库上运行的版本。

kli*_*lin 6

strpos(str, sub)Postgres中的功能instr(str, sub)与Oracle中的功能相同。不幸的是,该函数没有第三个和第四个参数,因此Postgres中的表达式必须更复杂。

该函数substr(str, n)提供strn位置开始的子字符串。

instr(str, ch, instr(str, sub), 1);                               --oracle
strpos(substr(str, strpos(str, sub)), ch) + strpos(str, sub) - 1; --postgres
Run Code Online (Sandbox Code Playgroud)

作为instr()强大的功能,我根据自己的需要在plpgsql中编写了它。

create or replace function instr(str text, sub text, startpos int = 1, occurrence int = 1)
returns int language plpgsql
as $$
declare 
    tail text;
    shift int;
    pos int;
    i int;
begin
    shift:= 0;
    if startpos = 0 or occurrence <= 0 then
        return 0;
    end if;
    if startpos < 0 then
        str:= reverse(str);
        sub:= reverse(sub);
        pos:= -startpos;
    else
        pos:= startpos;
    end if;
    for i in 1..occurrence loop
        shift:= shift+ pos;
        tail:= substr(str, shift);
        pos:= strpos(tail, sub);
        if pos = 0 then
            return 0;
        end if;
    end loop;
    if startpos > 0 then
        return pos+ shift- 1;
    else
        return length(str)- pos- shift+ 1;
    end if;
end $$;
Run Code Online (Sandbox Code Playgroud)

一些检查(来自OLAP DML函数的示例):

select instr('Corporate Floor', 'or', 3, 2);  -- gives 14
select instr('Corporate Floor', 'or', -3, 2); -- gives 2
Run Code Online (Sandbox Code Playgroud)

reverse()Postgres 8.2中没有任何功能。您可以使用此:

-- only for Postgres 8.4 or earlier!
create or replace function reverse(str text)
returns text language plpgsql
as $$
declare
    i int;
    res text = '';
begin
    for i in 1..length(str) loop
        res:= substr(str, i, 1) || res;
    end loop;
    return res;
end $$;
Run Code Online (Sandbox Code Playgroud)