使用CLOB将多行合并为单行

时间:2019-09-08 16:58:30

标签: sql oracle

使用CLOB将查询的多行保存为单个行时遇到麻烦。

我已经尝试过ASK TOM https://asktom.oracle.com/pls/apex/f?p=100:11:::NO::P11_QUESTION_ID:9537158500346658848建议的这种方法 但我认为我缺乏适当绑定查询变量的知识。

能帮我吗?也许还有另一种选择使用CLOB将查询压缩为单行

这是有问题的查询

Select '<?xml version="1.0" encoding="UTF-8"?>'||chr(10)||
'<OtherServices ServiceMonth="'|| to_char(framework.dim_calendar_pkg.get_startdate(FRAMEWORK.CTL_Session_Parameters_PKG.Get_BillingPeriod()),'YYYYMM')||'" Source ="CLIENT" UniqueFileID ="ID0000036">' as XML
from dual 
union all 
select CAST(XML as varchar2(2000)) as XML from (
with CTE as 
(SELECT   R.BS_TEXT          AS BillingDriver
           , F.CI_NAME          AS Signum
           , 1                  AS Quantity   -- not F.Quantity, as even non-billable should have quantity 1
           , CASE WHEN F.QUANTITY=0
                 THEN 'No'
                 ELSE 'Yes'
            END                 AS Billable            
    FROM CLIENT.FACTS F
    JOIN CLIENT.DIM_RESOURCEUNITS_VW R ON F.RU_ID = R.RU_ID
                  WHERE F.BILLINGPERIOD = FRAMEWORK.CTL_Session_Parameters_PKG.Get_BillingPeriod()
                    AND F.BILLINGPERIOD = F.SERVICEPERIOD
                    AND F.INPUT_SOURCE  IN ('CLIENT_CVS_NONPDV','CLIENT_CVS_PDV','CLIENT_CVS_PV')

)
SELECT
    XMLSERIALIZE(document
       XMLElement("Service", 
            XMLForest (C.BillingDriver AS "BillingDriver", 
                      C.Signum   AS "Signum", 
                      C.Quantity  AS "Quantity",
                      C.Billable  AS "Billable")
      )
      indent size=2) XML
      FROM CTE C)
UNION ALL
Select '</OtherServices>' AS XML from dual;



 SELECT   '201904'          AS ServiceMonth
         , 'CLIENT'        AS Source
         , 'ID0000038'      AS UniqueFileID
         , 'ViCS_MWPII_user' AS BillingDriver
          , VM.SIGNUM         AS "Signum-ID"
            , 1                 AS Quantity
            , 'Yes'             AS Billable
     FROM CLIENT.REF_CVS_VICS_MATRIX_VW VM
    WHERE  VM.ACCESS_TO_VICS_BASE = 1 
      AND (VM.ACCESS_TO_VICS_DESTKOP_EMEA = 1  OR VM.ACCESS_TO_VICS_DESTKOP_AMCS = 1 OR VM.ACCESS_TO_VICS_DESTKOP_APAC = 1)
      AND EXISTS (SELECT 1 from CLIENT.FACTS F
                  WHERE F.BILLINGPERIOD = FRAMEWORK.CTL_Session_Parameters_PKG.Get_BillingPeriod()
                    AND F.BILLINGPERIOD = F.SERVICEPERIOD
                    AND F.INPUT_SOURCE  IN ('CLIENT_MWP2_OPER','CLIENT_MWP2_COMP')
                    AND UPPER(F.CURRENT_USER) = UPPER(VM.SIGNUM))

    UNION ALL
    -- Signums with VICS_BASE and one of regional VICS_DESKTOPS, but without user in MWPII
    SELECT  '201904'          AS ServiceMonth
         , 'CLIENT'        AS Source
         , 'ID0000038'      AS UniqueFileID  
         , 'ViCS_PV'         AS BillingDriver
          , VM.SIGNUM        AS "Signum-ID"
            , 1                AS Quantity
            , 'Yes'            AS Billable
     FROM CLIENT.REF_CVS_VICS_MATRIX_VW  VM
     WHERE  VM.ACCESS_TO_VICS_BASE = 1 
       AND (VM.ACCESS_TO_VICS_DESTKOP_EMEA = 1  OR VM.ACCESS_TO_VICS_DESTKOP_AMCS = 1 OR VM.ACCESS_TO_VICS_DESTKOP_APAC = 1)
       AND NOT EXISTS (SELECT 1 from CLIENT.FACTS F
                  WHERE F.BILLINGPERIOD = FRAMEWORK.CTL_Session_Parameters_PKG.Get_BillingPeriod()
                    AND F.BILLINGPERIOD = F.SERVICEPERIOD   
                    AND F.INPUT_SOURCE  IN ('CLIENT_MWP2_OPER','CLIENT_MWP2_COMP')
                    AND UPPER(F.CURRENT_USER) = UPPER(VM.SIGNUM)) 
    UNION ALL
    -- Other signums with VICS_Base =1, but without regional VICS_Desktop
    SELECT   '201904'          AS ServiceMonth
         , 'CLIENT'        AS Source
         , 'ID0000038'      AS UniqueFileID
         , 'ViCS_Apps'       AS BillingDriver
          , VM.SIGNUM        AS "Signum-ID"
            , 1                AS Quantity
            , 'Yes'            AS Billable
     FROM CLIENT.REF_CVS_VICS_MATRIX_VW  VM
     WHERE      VM.ACCESS_TO_VICS_BASE = 1 
       AND (VM.ACCESS_TO_VICS_DESTKOP_EMEA IS NULL OR VM.ACCESS_TO_VICS_DESTKOP_EMEA != 1)
       AND (VM.ACCESS_TO_VICS_DESTKOP_AMCS IS NULL OR VM.ACCESS_TO_VICS_DESTKOP_AMCS != 1)
       AND (VM.ACCESS_TO_VICS_DESTKOP_APAC IS NULL OR VM.ACCESS_TO_VICS_DESTKOP_APAC != 1)


谢谢

1 个答案:

答案 0 :(得分:1)

这里是将多行数据转换为由换行符分隔的单个CLOB值的示例。在光标部分,您可能要替换为查询。

create table test(c clob);

declare
  lv_clob CLOB;

  cursor c
  is select rpad('*',level*2,' *')||chr(10) rec from dual connect by level <= 15;

  c_rec varchar2(100);--Holds each record from above cursor in each iteration

begin
  dbms_lob.createtemporary(lv_clob, TRUE);

  open c;
  loop
    fetch c into c_rec;
    exit when c%notfound;

    dbms_lob.append(lv_clob, c_rec);
  end loop;

  insert into test values(lv_clob);
  commit;

  dbms_lob.freetemporary(lv_clob);

end;

select * from test;

输出:

C
* 
* * 
* * * 
* * * * 
* * * * * 
* * * * * * 
* * * * * * * 
* * * * * * * * 
* * * * * * * * * 
* * * * * * * * * * 
* * * * * * * * * * * 
* * * * * * * * * * * * 
* * * * * * * * * * * * * 
* * * * * * * * * * * * * * 
* * * * * * * * * * * * * * *