【问题标题】:PL/SQL converts name-value pairs to single row tablePL/SQL 将名称-值对转换为单行表
【发布时间】:2016-10-28 12:13:22
【问题描述】:

使用 PL/SQL,如何转换这样的名称-值对表...

Name      Value
--------- -------
Firstname   Bob
Surname     Smith
Address1    101 High Street
City        London
Country     UK

...到这样的单行表:

Firstname Surname Address1        City   Country
--------- ------- --------------- ------ -------
Bob       Smith   101 High Street London UK

实际上我需要将名称-值对转换为 SYS_REFCURSOR 作为上面的单行表

完整的故事是: 我将数据作为单个字符串接收,像这样 (Firstname;Bob;Surname;SmithAddress1;101 High Street;City;London;Country;UK) 我所需要的只是将其转换为 SYS_REFCURSOR

我从创建类型开始

TYPE order_type IS TABLE OF VARCHAR2(255) INDEX BY VARCHAR2(255);
neworder order_type;

到目前为止,我设法通过名称-值对来做到这一点

这是一个好方法吗?

【问题讨论】:

  • 你需要旋转;如何取决于您使用的 Oracle 版本。但是为什么要为此使用 PL/SQL?
  • 我刚刚更新了我的问题@Alex 希望它能让事情更清楚
  • 你的 oracle 版本是多少?
  • 它是 Oracle 11g

标签: database oracle plsql plsqldeveloper


【解决方案1】:
create table t1 (name varchar2(20), value varchar2(20));
insert into t1 values('Firstname','Bob');
insert into t1 values('Surname','Smith');
insert into t1 values('Address1','101 High Street');
insert into t1 values('City','London');
insert into t1 values('Country','UK');

select * from t1 pivot (max(value) for (name) in ('Firstname' as firstname, 'Surname' as surname, 'Address1' as address, 'City' as city, 'Country' as country));

此类 SQL 将列数据转换为一行。

如果您将数据作为具有固定顺序的分隔字符串获取,我将使用 instr('Firstname;Bob;Surname;Smith;Address1;101 High Street;City;London;Country;UK',';',1)substring 函数的组合对其进行解析。

类似:

declare
text varchar2(200) := 'Firstname;Bob;Surname;Smith;Address1;101 High Street;City;London;Country;UK';
firstname varchar2(40);
surname varchar2(40);
address varchar2(40);
city varchar2(40);
country varchar2(40);
begin
firstname := substr(text,instr(text,';',1) + 1,instr(text,';',2) - instr(text,';',1));
surname := substr(text,instr(text,';',3) + 1, instr(text,';',4) - instr(text,';',3));
....
end;

【讨论】:

  • 我收到的字符串的值是可变的,所以我不能只定义名字、姓氏、...等
  • @Data-Base 好的。如果您知道参数集,您可以尝试识别并解析它。如果参数是动态设置的,则需要解析对,然后进行一些动态枢轴
  • @Data-Base 很高兴知道。不确定我是否对您有所帮助,但您能解决问题是件好事。
【解决方案2】:

遇到了一个我不知道的有趣实用程序。 dbms_utility.comma_to_table。 http://mohsoracle.blogspot.com/2010/04/oracle-breaking-comma-separated-string.html

所以如果你想用它从一个分隔的字符串中返回一个 sys ref 游标可能是这样的。

/* Formatted on 10/28/2016 9:42:52 AM (QP5 v5.256.13226.35510) */
CREATE OR REPLACE PROCEDURE myproc (v_cur OUT SYS_REFCURSOR)
IS
   lv_Str_List   VARCHAR2 (1000)
      := 'Firstname, Bob, Surname, Smith, Address, 101 High Street, City, London, Country, UK';
   lb_cnt        BINARY_INTEGER;
   la_Tab_Str    DBMS_UTILITY.UNCL_ARRAY;
BEGIN
   lv_Str_List := '"' || REPLACE (lv_Str_List, ',', '","') || '"';
   -- parse the string into comma separated table
   DBMS_UTILITY.COMMA_TO_TABLE (lv_Str_List, lb_cnt, la_Tab_Str);

   FOR i IN 1 .. la_Tab_Str.COUNT
   LOOP
      -- display substring
      DBMS_OUTPUT.PUT_LINE (TRIM (la_Tab_Str (i)));
   END LOOP;

   OPEN v_cur FOR
      SELECT *
        FROM (SELECT REPLACE (TRIM (la_Tab_Str (2)), '"', '') AS Firstname,
                     REPLACE (TRIM (la_Tab_Str (4)), '"', '') AS Surname,
                     REPLACE (TRIM (la_Tab_Str (6)), '"', '') AS Address,
                     REPLACE (TRIM (la_Tab_Str (8)), '"', '') AS City,
                     REPLACE (TRIM (la_Tab_Str (10)), '"', '') AS Country
                FROM DUAL) t;
END;

我在字符串中进行了硬编码,但它可以作为变量输入,然后用逗号替换分号。

当我在 toad 中运行以下命令进行测试时。

DECLARE 
  V_CUR SYS_REFCURSOR;

BEGIN 
  V_CUR := NULL;

  MYPROC ( V_CUR );
  :to_grid := V_CUR;
  COMMIT; 
END; 

我明白了

FIRSTNAME SURNAME  ADDRESS           CITY     COUNTRY
Bob       Smith    101 High Street   London   UK

【讨论】:

    猜你喜欢
    • 2013-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-08
    相关资源
    最近更新 更多