你能帮我把以下T-SQL功能转换成Oracle吗?该函数转换类似
的字符串service|nvretail;language|de;yyyy|2011;
到桌子。
我遇到的主要问题是使用临时表。我在Oracle中找不到任何相同的东西。
CREATE FUNCTION [dbo].[TF_ConvertPara]
(
@parastringNVARCHAR(max)
)
RETURNS @para TABLE
(
[Key] varchar(max),
[Value] varchar(max)
)
begin
DECLARE @NextString NVARCHAR(40)
DECLARE @Pos1 INT
DECLARE @Pos2 INT
DECLARE @NextPos INT
DECLARE @Delimiter1 NCHAR=';'
DECLARE @Delimiter2 NCHAR='|'
if substring(@paraString, len(@paraString) - 1, 1) <> @Delimiter1
SET @paraString = @paraString + @Delimiter1
SET @Pos1 = charindex(@Delimiter1, @paraString)
WHILE (@pos1 <> 0)
BEGIN
SET @NextString = substring(@paraString, 1, @Pos1 - 1)
SET @paraString = substring(@paraString, @pos1 + 1, len(@paraString))
SET @pos1 = charindex(@Delimiter1, @paraString)
SET @Pos2 = charindex(@Delimiter2, @NextString)
if (@Pos2 > 0)
begin
insert into @para
values
(substring(@NextString, 1, @Pos2 - 1),
substring(@NextString, @Pos2 + 1, len(@NextString)))
end
END
return;
end
提前谢谢。
答案 0 :(得分:3)
如果您希望将字符串的标记作为行返回,那么您可以在单个SQL查询中完成所有操作:
WITH t AS (SELECT 'service|nvretail;language|de;yyyy|2011;' as val FROM dual)
SELECT row_output
FROM t,
XMLTABLE( '/root/e/text()'
PASSING xmltype( '<root><e>' ||
REGEXP_REPLACE (t.val, '(;|\|)', '</e><e>' ) ||
'</e></root>' )
COLUMNS row_output VARCHAR2( 4000 ) PATH '/');
返回:
service nvretail language de yyyy 2011
如果你想在表中包含这些行,那么将SQL包装在一个简单的函数中,以返回内存中的表或将记录插入到数据库表中,无论你需要什么。
以下是返回VARCHAR2记录的表(集合)的函数示例:
CREATE OR REPLACE
FUNCTION str_to_table (
p_input_str IN VARCHAR2
)
RETURN DBMS_SQL.VARCHAR2_TABLE
IS
CURSOR str_to_rows (
cp_str IN VARCHAR2
)
IS
SELECT row_output
FROM (SELECT cp_str as val FROM dual) t,
XMLTABLE( '/root/e/text()'
PASSING xmltype( '<root><e>' ||
REGEXP_REPLACE(t.val, '(;|\|)', '</e><e>') ||
'</e></root>' )
COLUMNS row_output VARCHAR2( 4000 ) PATH '/');
varchar_tab DBMS_SQL.VARCHAR2_TABLE;
BEGIN
OPEN str_to_rows(p_input_str);
FETCH str_to_rows BULK COLLECT INTO varchar_tab;
CLOSE str_to_rows;
--
RETURN varchar_tab;
EXCEPTION
WHEN others
THEN
IF str_to_rows%ISOPEN
THEN
CLOSE str_to_rows;
END IF;
RAISE;
END str_to_table;
它未经测试,因此可能存在一些语法错误,但它应该是prety close。
返回引用光标:
CREATE OR REPLACE
FUNCTION str_to_table (
p_input_str IN VARCHAR2
)
RETURN sys_refcursor
IS
cur SYS_REFCURSOR;
BEGIN
OPEN cur
FOR SELECT row_output
FROM (SELECT p_input_str as val FROM dual) t,
XMLTABLE( '/root/e/text()'
PASSING xmltype( '<root><e>' ||
REGEXP_REPLACE (t.val, '(;|\|)', '</e><e>' ) ||
'</e></root>' )
COLUMNS row_output VARCHAR2( 4000 ) PATH '/');
--
RETURN cur;
END str_to_table;
希望它有所帮助...
答案 1 :(得分:2)
要返回键值对,如何(对于Oracle 10g及更高版本):
CREATE OR REPLACE FUNCTION csv_to_rows(mycsv IN VARCHAR2)
RETURN sys_refcursor
AS
c SYS_REFCURSOR;
BEGIN
OPEN c FOR
SELECT SUBSTR(element,1,INSTR(element,'|')-1) as key ,
SUBSTR(element,INSTR(element,'|')+1,99999) as val
FROM (
SELECT REGEXP_SUBSTR(mycsv,'[^;]+',1,LEVEL) element
FROM dual
CONNECT BY LEVEL < LENGTH(REGEXP_REPLACE(mycsv,'[^;]+')) + 1
);
RETURN c;
END;
并查看结果:
DECLARE
c SYS_REFCURSOR;
akey VARCHAR2(100);
aval VARCHAR2(100);
BEGIN
c := csv_to_rows('service|nvretail;language|de;yyyy|2011');
LOOP
FETCH c into akey,aval;
EXIT WHEN c%NOTFOUND;
dbms_output.put_line('Key : '||akey || ' Value : '||aval);
END LOOP;
END;
这应该给你
Key : service Value : nvretail
Key : language Value : de
Key : yyyy Value : 2011