Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将一段SQL转换为Oracle函数_Sql_Oracle_Plsql - Fatal编程技术网

将一段SQL转换为Oracle函数

将一段SQL转换为Oracle函数,sql,oracle,plsql,Sql,Oracle,Plsql,我的表格“逗号分隔”看起来像这样 SELECT id, split_function(city) FROM COMMA_SEPERATED ID名称城市 --- ---- ----------------------------- 1拉吉钦奈,海得拉巴,贾巴尔普尔 2萨姆·博帕尔,浦那 我想将每个城市作为一个新记录分开,因此我的SQL是:(工作正常) 我想将这段SQL转换成一个函数,这样我就可以像这样简单地调用函数 SELECT id, split_function(city) FROM C

我的表格“逗号分隔”看起来像这样

SELECT id, split_function(city) FROM COMMA_SEPERATED
ID名称城市
--- ---- -----------------------------
1拉吉钦奈,海得拉巴,贾巴尔普尔
2萨姆·博帕尔,浦那
我想将每个城市作为一个新记录分开,因此我的SQL是:(工作正常)

我想将这段SQL转换成一个函数,这样我就可以像这样简单地调用函数

SELECT id, split_function(city) FROM COMMA_SEPERATED
输出:

1钦奈
1海得拉巴
1贾巴尔普
2博帕尔
2浦那

有人能帮忙吗?我对PL/SQL非常陌生。

除了@Alex显示的内容,您还可以创建一个
对象
,并通过
函数
返回
对象。见下文:

--Created an object to hold your result columns
create or replace type Obj IS OBJECT (id number, city varchar2(20));
/
--Table of object
create or replace type var_obj is table of Obj;

/
--Function with return as with Object type.
create or replace function splt_fnct
return var_obj
as
var var_obj:=var_obj();

begin
Select obj(col,col1)
bulk collect into var
from (
Select  distinct  col , regexp_substr(col1,'[^,]+',1,level) col1
from tbl
connect by regexp_substr(col1,'[^,]+',1,level) is not null
order by 1);

return var;
end;

/
--Selecting result   

 select *  from table(splt_fnct);
编辑:我尝试使用@Alex solution,但出现如下错误:

create or replace function splt_fnct(input_strng varchar2)
return var_obj
as
var var_obj:=var_obj();

begin
Select obj(col,col1)
bulk collect into var
from (
select tbl.col, t.rslt --<--This column name should the same as used in colmns clause in the below query. Its giving error "invalid column". How to handle this case.
FROM tbl, xmltable
(
    'if (contains($X,",")) then ora:tokenize($X,"\,") else $X'
    passing col1 AS X
    columns input_strng varchar2(4000) path '.'
) t
);
return var;
end;

/

除了@Alex显示的内容外,您还可以创建一个
对象
,并通过
函数
返回
对象
。见下文:

--Created an object to hold your result columns
create or replace type Obj IS OBJECT (id number, city varchar2(20));
/
--Table of object
create or replace type var_obj is table of Obj;

/
--Function with return as with Object type.
create or replace function splt_fnct
return var_obj
as
var var_obj:=var_obj();

begin
Select obj(col,col1)
bulk collect into var
from (
Select  distinct  col , regexp_substr(col1,'[^,]+',1,level) col1
from tbl
connect by regexp_substr(col1,'[^,]+',1,level) is not null
order by 1);

return var;
end;

/
--Selecting result   

 select *  from table(splt_fnct);
编辑:我尝试使用@Alex solution,但出现如下错误:

create or replace function splt_fnct(input_strng varchar2)
return var_obj
as
var var_obj:=var_obj();

begin
Select obj(col,col1)
bulk collect into var
from (
select tbl.col, t.rslt --<--This column name should the same as used in colmns clause in the below query. Its giving error "invalid column". How to handle this case.
FROM tbl, xmltable
(
    'if (contains($X,",")) then ora:tokenize($X,"\,") else $X'
    passing col1 AS X
    columns input_strng varchar2(4000) path '.'
) t
);
return var;
end;

/

您试图访问的查询:

SELECT id, split_function(city) FROM COMMA_SEPERATED
不起作用,因为您试图为每个源行返回多行。不幸的是,你必须把事情弄得更复杂一点

如果目标是隐藏拆分机制,那么我能想到的最接近的方法就是创建一个返回字符串集合的函数,它可以是:

然后,您提议的呼叫将为每个ID提供一行集合:

select id, split_function(city) from comma_seperated;

        ID SPLIT_FUNCTION(CITY)
---------- -----------------------------------------------------------------
         1 ODCIVARCHAR2LIST('CHENNAI', 'HYDERABAD', 'JABALPUR')
         2 ODCIVARCHAR2LIST('BHOPAL', 'PUNE')
这不是你想要的;但您可以使用表集合表达式和交叉联接转换为多行:

select cs.id, t.column_value as city
from comma_seperated cs
cross join table(split_function(cs.city)) t;

        ID CITY                          
---------- ------------------------------
         1 CHENNAI                       
         1 HYDERABAD                     
         1 JABALPUR                      
         2 BHOPAL                        
         2 PUNE                          


这并不像您希望的那么简单,但可以说仍然比交叉连接到
xmltable()
要好,特别是如果您希望在多个位置重用该拆分逻辑/函数,以及隐藏如何完成拆分的详细信息,这将使您可以轻松地更改机制,例如,使用更常见的正则表达式进行拆分。

您试图获取的查询:

SELECT id, split_function(city) FROM COMMA_SEPERATED
不起作用,因为您试图为每个源行返回多行。不幸的是,你必须把事情弄得更复杂一点

如果目标是隐藏拆分机制,那么我能想到的最接近的方法就是创建一个返回字符串集合的函数,它可以是:

然后,您提议的呼叫将为每个ID提供一行集合:

select id, split_function(city) from comma_seperated;

        ID SPLIT_FUNCTION(CITY)
---------- -----------------------------------------------------------------
         1 ODCIVARCHAR2LIST('CHENNAI', 'HYDERABAD', 'JABALPUR')
         2 ODCIVARCHAR2LIST('BHOPAL', 'PUNE')
这不是你想要的;但您可以使用表集合表达式和交叉联接转换为多行:

select cs.id, t.column_value as city
from comma_seperated cs
cross join table(split_function(cs.city)) t;

        ID CITY                          
---------- ------------------------------
         1 CHENNAI                       
         1 HYDERABAD                     
         1 JABALPUR                      
         2 BHOPAL                        
         2 PUNE                          



这并不像您希望的那么简单,但可以说仍然比交叉连接到
xmltable()
要好,特别是如果您希望在多个位置重用该拆分逻辑/函数,以及隐藏如何完成拆分的详细信息,这将使您可以轻松地更改机制,例如,使用更常见的正则表达式进行拆分。

该表达式的可能副本似乎不是合适的副本;问题不在于如何拆分字符串(OP已经在使用其中一种解决方案的变体),而在于如何将其封装到函数中?当你说
split_函数(city)
这是否意味着应该返回传递给函数的city或所有行?我建议不要编写此函数,而是规范化您的表。该函数的可能副本似乎不是一个合适的副本;问题不在于如何拆分字符串(OP已经在使用其中一种解决方案的变体),而在于如何将其封装到函数中?当你说
split_函数(city)
这是否意味着应该返回传递给函数的city或所有行?我建议不要编写此函数,而是规范化您的表。Alex不确定在这种情况下传递p_string
是否有效。如果我们必须使用它,那么语句应该是动态的。我尝试过,但在我的案例中失败了。@XING-不太清楚为什么它需要动态;它在测试时(在11gR2中)可以工作,我添加了一个相同代码的dbfiddle演示。好奇你的什么地方出了问题?而
p_string
只是函数参数名,它作为调用的一部分从基表传递逗号分隔的字符串-因此它很灵活,不绑定到特定的表。可能是我做错了什么。我将分享我的代码以了解故障。。谢谢你的回复。你能看看我上面贴的问题吗?Alex不确定在这种情况下传递p_字符串是否有效。如果我们必须使用它,那么语句应该是动态的。我尝试过,但在我的案例中失败了。@XING-不太清楚为什么它需要动态;它在测试时(在11gR2中)可以工作,我添加了一个相同代码的dbfiddle演示。好奇你的什么地方出了问题?而
p_string
只是函数参数名,它作为调用的一部分从基表传递逗号分隔的字符串-因此它很灵活,不绑定到特定的表。可能是我做错了什么。我将分享我的代码以了解故障。。谢谢你的回答。你能看看我上面贴的问题吗?你应该有
传递输入
列rslt
?我想其他一些名字的参考资料也有点混乱。但这仍然不完全正确,如果您使用的是一个对象,那么您也需要传递ID,否则当您在函数中重新查询基表时,您实际上是在执行一个意外的交叉连接:。@AlexPoole。完美的谢谢你的回答。。。!!您应该有
传递输入\u strng
列rslt
?我想其他一些名字的参考资料也有点混乱。但这仍然不完全正确,如果您正在使用一个对象,那么您需要传递ID,否则