2014-07-17 59 views
1

我是oracle中的新成员。我有一个关于TSQL的函数,我需要将它翻译成pl/sql。 函数用一些规则分隔传入的字符串。所以我试试这个:函数返回表。 pl/sql

create or replace 
FUNCTION FN_PROPSTOTABLE(stValues in varchar2) RETURN POPSTBL AS 
tbl PROPSTBL; 
s varchar2(8000); 
ind varchar2(100); 
val varchar2(100); 
p int; 
tmp varchar2(8000); 
BEGIN 
    tmp:=stValues; 
    while LENGTH(tmp)>0 
    loop 
    p:=instr(tmp, ':'); 
    IF p=0 THEN 
     p:=LENGTH(tmp); 
    END IF; 
    s:=SUBSTR(tmp, 0, p); 
    tmp:=SUBSTR(tmp, LENGTH(s)+1); 
    s:=REPLACE(s, ':', ''); 
    ind:=substr(s,0, instr(s, '|')-1); 
    val:=substr(s,instr(s, '|')+1); 

    select b bulk collect into tbl 
    from (select props(ind, val) b from dual); 

    end loop; 

    RETURN tbl; 
END FN_PROPSTOTABLE; 

这很好,但它只返回最后一个子字符串。请帮帮我。

+0

'POPSTBL'的定义是什么? (发布'create type ...'声明) –

+1

@a_horse_with_no_name:我要做出有根据的猜测并说:'CREATE TYPE PROPSTBL AS PROPS' :) –

回答

4

如何制作一个PIPELINED函数(我认为最常用的功能之一)?

CREATE OR REPLACE 
FUNCTION FN_PROPSTOTABLE(stValues in varchar2) RETURN PROPSTBL 

-- Add the "PIPELINED" modifier here 
PIPELINED AS 
    tbl PROPSTBL; 
    s varchar2(8000); 
    ind varchar2(100); 
    val varchar2(100); 
    p int; 
    tmp varchar2(8000); 
BEGIN 
    tmp := stValues; 
    WHILE LENGTH(tmp) > 0 
    LOOP 
    p := INSTR(tmp, ':'); 

    IF p=0 THEN 
     p := LENGTH(tmp); 
    END IF; 

    s := SUBSTR(tmp, 0, p); 
    tmp := SUBSTR(tmp, LENGTH(s)+1); 
    s := REPLACE(s, ':', ''); 
    ind := SUBSTR(s,0, instr(s, '|')-1); 
    val := SUBSTR(s,instr(s, '|')+1); 

    -- Emit resulting rows using "PIPE" 
    PIPE ROW(props(ind, val)); 
    END LOOP; 

    RETURN; 
END FN_PROPSTOTABLE; 

然后调用它像这样:

SELECT * FROM TABLE(fn_propstotable('1|a:2|b')) 

之所以你的解决方案没有工作是因为你不断改写你的表型(而不是追加到它)每次迭代的时间你的循环。

+0

谢谢。这很好。 – Gleb