将水平CSV模板转换为表格格式

时间:2017-04-06 12:27:14

标签: sql oracle plsql

免责声明:请详细询问详细问题。我希望尽可能明确要求。

以下种子表(SAMPLE_EXTRA_INFO)存储员工的额外信息:

EIT_ID  EMPLOYEE_NUMBER     EXTRA_INFORMATION       INFORMATION_CATEGORY    INFORMATION1    INFORMATION2    INFORMATION3 .... INFORMATION10
------  ------------------- ---------------------   ----------------------  --------------  -------------   ------------      --------------
1       11111               Academic Rank           Next Academic Rank      Professor       Y               10.5              (NULL)      
2       11111               Academic Rank           Academic Rank           Ass.Professor   N               (NULL)            (NULL)  
3       11111               Academic Rank           Effective Start Date    01-JAN-2017     (NULL)          (NULL)            (NULL)
4       11111               Academic Rank           Effective End Date      31-DEC-4712     (NULL)          (NULL)            (NULL)
5       11111               Alien Income Forecast   Income_code             P               (NULL)          (NULL)            (NULL)    
6       11111               Alien Income Forecast   Date                    2017            01              DEC               (NULL)      
7       11111               Alien Income Forecast   Amount                  10000           Tax             (NULL)            (NULL)          
8       11111               Alien Income Forecast   Effective Start Date    01-JAN-2017     (NULL)          (NULL)            (NULL)      
9       11111               Alien Income Forecast   Effective End Date      31-DEC-4712     (NULL)          (NULL)            (NULL)      
10      22222               Academic Rank           Next Academic Rank      Master          N               11.5              (NULL)            
11      22222               Academic Rank           Academic Rank           Professor       Y               (NULL)            (NULL)  
12      22222               Academic Rank           Effective Start Date    01-JAN-2017     (NULL)          (NULL)            (NULL)
13      22222               Academic Rank           Effective End Date      31-DEC-4712     (NULL)          (NULL)            (NULL)
14      22222               Alien Income Forecast   Income_code             X1              (NULL)          (NULL)            (NULL)    
15      22222               Alien Income Forecast   Date                    2017            01              APR               (NULL)    
16      22222               Alien Income Forecast   Amount                  100000000       Tax-Free        (NULL)            (NULL)          
17      22222               Alien Income Forecast   Effective Start Date    01-JAN-2017     (NULL)          (NULL)            (NULL)      
18      22222               Alien Income Forecast   Effective End Date      31-DEC-4712     (NULL)          (NULL)            (NULL)      

所有信息列都具有数据类型VARCHAR2,但有一些商店日期(如上例所示)。

此表由一个种子API包(SAMPLE_PKG.CREATE_EXTRA_INFO)填充。

样本程序规范

SAMPLE_PKG.CREATE_EXTRA_INFO
(
    P_EMPLOYEE_NUMBER       VARCHAR2
,   P_EXTRA_INFORMATION     VARCHAR2
,   P_INFORMATION_CATEGORY  VARCHAR2
,   P_INFORMATION1          VARCHAR2
,   P_INFORMATION2          VARCHAR2
,   P_INFORMATION3          VARCHAR2
,   P_INFORMATION4          VARCHAR2
,   P_INFORMATION5          VARCHAR2
,   P_INFORMATION6          VARCHAR2
,   P_INFORMATION7          VARCHAR2
,   P_INFORMATION8          VARCHAR2
,   P_INFORMATION9          VARCHAR2
,   P_INFORMATION10         VARCHAR2
);

我的任务是创建一个上传流程,该流程将使用CSV模板和API的界面信息。 以下是CSV模板的示例:

EMPLOYEE_NUMBER Next Academic Rank  Max Academic Rank   Max Score   Academic Rank   Promotion Rank  ACADEMIC_RANK_START_DATE ACADEMIC_RANK_END_DATE  Income_code Date(YYYY) Date(MON)   Date(DD)    Amount  Tax?    INCOME_START_DATE   INCOME_END_DATE
--------------- ------------------  ------------------  ----------  -------------   --------------  ------------------------ ------------------      ----------- ---------  ---------   ---------   ------  -----   -----------------   -------------------
33333           Professor           Y                   10.1        Ass.Professor   Y               01-JAN-2017              31-DEC-4712             P           2017       JAN         01          10000   Tax     01-JAN-2017         31-DEC-4712
44444           Ass.Professor       N                   9.7         Student         N               01-JAN-2017              31-DEC-4712             R           2017       JAN         17          50000   Non-Tax 01-JAN-2017         31-DEC-4712

我打算使用外部表(SAMPLE_EXTRA_INFO_EXT)来阅读CSV模板并将信息传递给API。

Create Table SAMPLE_EXTRA_INFO_EXT
(
    EMPLOYEE_NUMBER            VARCHAR2(250)
,   NEXT_ACADEMIC_RANK         VARCHAR2(250) 
,   MAX_ACADEMIC_RANK          VARCHAR2(250)
,   MAX_SCORE                  VARCHAR2(250)
,   ACADEMIC_RANK              VARCHAR2(250)
,   PROMOTION_RANK             VARCHAR2(250)
,   ACADEMIC_RANK_START_DATE   VARCHAR2(250)
,   ACADEMIC_RANK_END_DATE     VARCHAR2(250)
,   INCOME_CODE                VARCHAR2(250)
,   DATE_YYYY                  VARCHAR2(250)
,   DATE_MON                   VARCHAR2(250)
,   DATE_DD                    VARCHAR2(250)
,   AMOUNT                     VARCHAR2(250)
,   TAX                        VARCHAR2(250)
,   INCOME_START_DATE          VARCHAR2(250)
,   INCOME_END_DATE            VARCHAR2(250)
)
organization external ( type oracle_loader
                        default directory EXT_TAB_DATA
                        access parameters
                        (
                            records delimited by newline
                            skip 1
                            fields terminated by ','
                            optionally enclosed by '"' LRTRIM
                            missing field values are null                            
                        )
                        location(EXT_TAB_DATA: 'Demographic_file_10APR2017.csv')
                       ) reject limit unlimited
                       ;

使用类似下面的代码块(请注意注释):

DECLARE

    CURSOR EXT_CUR IS
    SELECT  EMPLOYEE_NUMBER    
        ,   NEXT_ACADEMIC_RANK        -- Academic Rank (Next Academic Rank) INFORMATION1    
        ,   MAX_ACADEMIC_RANK         -- Academic Rank (Next Academic Rank) INFORMATION2    
        ,   MAX_SCORE                 -- Academic Rank (Next Academic Rank) INFORMATION3  
        ,   ACADEMIC_RANK             -- Academic Rank (Academic Rank) INFORMATION1    
        ,   PROMOTION_RANK            -- Academic Rank (Academic Rank) INFORMATION2     
        ,   ACADEMIC_RANK_START_DATE  -- Academic Rank (Effective Start Date) INFORMATION1
        ,   ACADEMIC_RANK_END_DATE    -- Academic Rank (Effective End Date) INFORMATION1
        ,   INCOME_CODE               -- Alien Income Forecast (Income_code) INFORMATION1
        ,   DATE_YYYY                 -- Alien Income Forecast (Date) INFORMATION1
        ,   DATE_MON                  -- Alien Income Forecast (Date) INFORMATION2 
        ,   DATE_DD                   -- Alien Income Forecast (Date) INFORMATION3 
        ,   AMOUNT                    -- Alien Income Forecast (Amount) INFORMATION1
        ,   TAX                       -- Alien Income Forecast (Amount) INFORMATION2 
        ,   INCOME_START_DATE         -- Alien Income Forecast (Effective Start Date) INFORMATION1 
        ,   INCOME_END_DATE           -- Alien Income Forecast (Effective End Date) INFORMATION1                          
    FROM    SAMPLE_EXTRA_INFO_EXT;    -- this is the external table

BEGIN

    FOR EXT_REC IN EXT_CUR LOOP 

        SAMPLE_PKG.CREATE_EXTRA_INFO
        (
            P_EMPLOYEE_NUMBER       => EXT_REC.EMPLOYEE_NUMBER      
        ,   P_EXTRA_INFORMATION     => EXT_REC.EXTRA_INFORMATION    -- This is my problem, how do i make it vertical?
        ,   P_INFORMATION_CATEGORY  => EXT_REC.INFORMATION_CATEGORY 
        ,   P_INFORMATION1          => EXT_REC.INFORMATION1         
        ,   P_INFORMATION2          => EXT_REC.INFORMATION2         
        ,   P_INFORMATION3          => EXT_REC.INFORMATION3         
        ,   P_INFORMATION4          => EXT_REC.INFORMATION4         
        ,   P_INFORMATION5          => EXT_REC.INFORMATION5         
        ,   P_INFORMATION6          => EXT_REC.INFORMATION6         
        ,   P_INFORMATION7          => EXT_REC.INFORMATION7         
        ,   P_INFORMATION8          => EXT_REC.INFORMATION8         
        ,   P_INFORMATION9          => EXT_REC.INFORMATION9         
        ,   P_INFORMATION10         => EXT_REC.INFORMATION10        
        );

    END LOOP;

END;

以下是我的问题:

  1. 模板是“水平的”,但API是“垂直的”。
  2. 并非所有额外信息都使用相同的信息列(一些使用列INFORMATION1-3,一些使用列INFORMATION1)。
  3. 话虽如此,我怎样才能将上面的模板转换为API可以使用的有效格式?

    我正在考虑在外部表中使用Pivot或UnPivot,但我不太确定如何处理该要求。 首选Pure SQL方法,但使用PL / SQL就可以了。

    Oracle版本

    Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
    PL/SQL Release 11.2.0.4.0 - Production
    "CORE   11.2.0.4.0  Production"
    TNS for Solaris: Version 11.2.0.4.0 - Production
    NLSRTL Version 11.2.0.4.0 - Production
    

1 个答案:

答案 0 :(得分:1)

在我看来,您需要从同一个表中多次选择,使用不同的列,具体取决于您收集的信息。如果您的模板是静态的,则以下是 EXT_CUR光标代码的代码:

CURSOR EXT_CUR IS
          select employee_number, 'Academic Rank' EXTRA_INFORMATION,   'Next Academic Rank'   INFORMATION_CATEGORY, [... fetching various columns]  from SAMPLE_EXTRA_INFO_EXT
union all select employee_number, 'Academic Rank' EXTRA_INFORMATION,   'Academic Rank'        INFORMATION_CATEGORY, [... fetching various columns]  from SAMPLE_EXTRA_INFO_EXT
union all select employee_number, 'Academic Rank' EXTRA_INFORMATION,   'Effective Start Date' INFORMATION_CATEGORY, [... fetching various columns]  from SAMPLE_EXTRA_INFO_EXT
union all select employee_number, 'Academic Rank' EXTRA_INFORMATION,   'Effective End Date '  INFORMATION_CATEGORY, [... fetching various columns]  from SAMPLE_EXTRA_INFO_EXT
union all select employee_number, 'AlienIF'       EXTRA_INFORMATION,   'Income_code '         INFORMATION_CATEGORY, [... fetching various columns]  from SAMPLE_EXTRA_INFO_EXT
union all select employee_number, 'AlienIF'       EXTRA_INFORMATION,   'Date        '         INFORMATION_CATEGORY, [... fetching various columns]  from SAMPLE_EXTRA_INFO_EXT
union all select employee_number, [and it goes on for whatever line your API needs]

以下是说明

的工作示例
with t as (  
select '33333  ' EMPLOYEE_NUMBER
, 'Professor   ' "Next Academic Rank "
, 'Y           ' "Max Academic Rank  "
, '10.1  '       "Max Score  "
,'Ass.Professor' "Academic Rank "
,'Y           '  "Promotion Rank"
,'01-JAN-2017 '  "ACADEMIC_RANK_START_DATE"
,'31-DEC-4712 '  "ACADEMIC_RANK_END_DATE"
,'P         '    "Income_code "
,'2017      '    "Date(YYYY)"
,' JAN      '    "Date(MON)"
,'   01     '    "Date(DD)"
,'  10000  '     "  Amount "
,' Tax     '     "Tax?"
,'01-JAN-2017  ' "INCOME_START_DATE  "
,' 31-DEC-4712 ' " INCOME_END_DATE"
from dual
union select '44444          ', 'Ass.Professor      ', 'N                  ', '9.7        ','Student       ','N             ','01-JAN-2017             ','31-DEC-4712            ','R           ','2017      ',' JAN      ','   17        ','  50000  ',' Non-Tax ','01-JAN-2017        ',' 31-DEC-4712    ' from dual
)         select employee_number, 'Academic Rank' EXTRA_INFORMATION,   'Next Academic Rank'   INFORMATION_CATEGORY,  "Next Academic Rank "         INFORMATION1 , null         INFORMATION2 , null       INFORMATION3 from t 
union all select employee_number, 'Academic Rank' EXTRA_INFORMATION,   'Academic Rank'        INFORMATION_CATEGORY,  "Academic Rank "              INFORMATION1 , null         INFORMATION2 , null       INFORMATION3 from t 
union all select employee_number, 'Academic Rank' EXTRA_INFORMATION,   'Effective Start Date' INFORMATION_CATEGORY,  "ACADEMIC_RANK_START_DATE"    INFORMATION1 , null         INFORMATION2 , null       INFORMATION3 from t 
union all select employee_number, 'Academic Rank' EXTRA_INFORMATION,   'Effective End Date '  INFORMATION_CATEGORY,  "ACADEMIC_RANK_END_DATE"      INFORMATION1 , null         INFORMATION2 , null       INFORMATION3 from t 
union all select employee_number, 'AlienIF'       EXTRA_INFORMATION,   'Income_code '         INFORMATION_CATEGORY,  "Income_code "                INFORMATION1 , null         INFORMATION2 , null       INFORMATION3 from t 
union all select employee_number, 'AlienIF'       EXTRA_INFORMATION,   'Date        '         INFORMATION_CATEGORY,  "Date(YYYY)"                  INFORMATION1 , "Date(MON)"  INFORMATION2 , "Date(DD)" INFORMATION3 from t 
order by 1, 2, 3

导致

enter image description here

如果您的模板随时间变化,则会出现另一个问题。您必须学习如何使用动态PL / SQL构建游标。 SO上有足够的资源。这是相当大的工作,但使用与上面相同的想法。