理解DB2中的复杂SP

时间:2017-05-27 12:34:58

标签: db2 ibm-midrange

我需要对SP进行更改,该SP具有一堆复杂的XML函数,而不是

Declare ResultCsr2 Cursor For
       WITH
       MDI_BOM_COMP(PROD_ID,SITE_ID, xml ) AS (
       SELECT TC401F.T41PID,TC401F.T41SID,
        XMLSERIALIZE(
         XMLAGG(
          XMLELEMENT( NAME "MDI_BOM_COMP",
           XMLFOREST(
                     trim(TC401F.T41CTY) AS COMPONENT_TYPE,
                     TC401F.T41LNO AS COMP_NUM,
                     trim(TC401F.T41CTO) AS CTRY_OF_ORIGIN,
                     trim(TC401F.T41DSC) AS DESCRIPTION,
                     TC401F.T41EFR AS EFFECTIVE_FROM,
                     TC401F.T41EFT AS EFFECTIVE_TO,
                     trim(TC401F.T41MID) AS MANUFACTURER_ID,
                     trim(TC401F.T41MOC) AS MANUFACTURER_ORG_CODE,
                     trim(TC401F.T41CNO) AS PROD_ID,
                     trim(TC401F.T41POC) AS PROD_ORG_CODE,
                     TC401F.T41QPR AS QTY_PER,
                     trim(TC401F.T41SBI) AS SUB_BOM_ID,
                     trim(TC401F.T41SBO) AS SUB_BOM_ORG_CODE,       --ADB01
                     trim(TC401F.T41VID) AS SUPPLIER_ID,
                     trim(TC401F.T41SOC) AS SUPPLIER_ORG_CODE,
                     TC401F.T41UCT AS UNIT_COST
               )
              )
             ) AS CLOB(1M)
            )
             FROM TC401F TC401F
             GROUP BY T41PID,T41SID
            )

       SELECT
       RowNum, '<BOM_INBOUND>' ||
        XMLSERIALIZE (
         XMLELEMENT(NAME "INTEGRATION_MESSAGE_CONTROL",
          XMLFOREST(
                    'FULL_UPDATE' as ACTION,
                    'POLARIS' as COMPANY_CODE,
                    TRIM(TC400F.T40OCD) as ORG_CODE,
                    '5' as PRIORITY,
                    'INBOUND_ENTITY_INTEGRATION' as MESSAGE_TYPE,
                    'POLARIS_INTEGRATION' as USERID,
                    'TA' as RECEIVER,
                    HEX(Generate_Unique()) as SOURCE_SYSTEM_TOKEN
                    ),
                      XMLELEMENT(NAME "BUS_KEY",
                       XMLFOREST(
                        TRIM(TC400F.T40BID) as BOM_ID,
                        TRIM(TC400F.T40OCD) as ORG_CODE
                       )
                      )
                     ) AS VARCHAR(1000)
                    )
            || '<MDI_BOM>' ||
              XMLSERIALIZE (
               XMLFOREST(

                 TRIM(TC400F.T40ATP) AS ASSEMBLY_TYPE,
                 TRIM(TC400F.T40BID) AS BOM_ID,
                 TRIM(TC400F.T40CCD) AS CURRENCY_CODE,
                 TC400F.T40DPC AS DIRECT_PROCESSING_COST,
                 TC400F.T40EFD AS EFFECTIVE_FROM,
                 TC400F.T40EFT AS EFFECTIVE_TO,
                 TRIM(TC400F.T40MID) AS MANUFACTURER_ID,
                 TRIM(TC400F.T40MOC) AS MANUFACTURER_ORG_CODE,
                 TRIM(TC400F.T40OCD) AS ORG_CODE,
                 TRIM(TC400F.T40PRF) AS PROD_FAMILY,
                 TRIM(TC400F.T40PID) AS PROD_ID,
                 TRIM(TC400F.T40POC) AS PROD_ORG_CODE,
                 TRIM(TC400F.T40ISA) AS IS_ACTIVE,
                 TRIM(TC400F.T40VID) AS SUPPLIER_ID,
                 TRIM(TC400F.T40SOC) AS SUPPLIER_ORG_CODE,
                 TRIM(TC400F.T40PSF) AS PROD_SUB_FAMILY,
                 CASE TRIM(TC400F.T40PML)
                    WHEN '' THEN TRIM(TC400F.T40PML)
                    ELSE TRIM(TC400F.T40PML) || '~' || TRIM(TC403F.T43MDD)
                   END    AS PROD_MODEL

                  ) AS VARCHAR(3000)
                 )
            || IFNULL(MBC.xml, '') ||
               XMLSERIALIZE (
                 XMLFOREST(
                   XMLFOREST(
                     TRIM(TC400F.T40CCD) AS CURRENCY_CODE,
                     TC400F.T40PRI AS PRICE,
                     TRIM(TC400F.T40PTY) AS PRICE_TYPE
                       ) AS MDI_BOM_PRICE,
                    XMLFOREST(
                      TRIM(TC400F.T40CCD) AS CURRENCY_CODE,
                      TRIM(TC400F.T40PRI) AS PRICE,
                      'TRANSACTION_VALUE' AS PRICE_TYPE
                      ) AS MDI_BOM_PRICE,
                    XMLFOREST(
                      TRIM(TC400F.T40INA) AS INCLUDE_IN_AVERAGING

                       ) AS MDI_BOM_IMPL_BOM_PROD_FAMILY_AUTOMOBILES

                      ) AS VARCHAR(3000)
                    )
                  || '</MDI_BOM>' ||
                  '</BOM_INBOUND>' XML
                     FROM (
                            SELECT
                            ROW_NUMBER() OVER (
                                   ORDER BY T40STS
                                   ,T40SID
                                   ,T40BID
                            ) AS RowNum
                            ,t.*
                            FROM TC400F t
                     ) TC400F

                     LEFT OUTER JOIN MDI_BOM_COMP MBC
                     ON TC400F.T40SID = MBC.SITE_ID
                     AND TC400F.T40PID = MBC.PROD_ID
                     LEFT OUTER JOIN TC403F TC403F
                      ON TC400F.T40PML <> ''
                      AND TC400F.T40PML = TC403F.T43MDL
                     WHERE TC400F.T40STS = '10'
                       AND TC400F.RowNUM BETWEEN
                         (P_STARTROW + (P_PAGENOS - 1) * P_NBROFRCDS)
                         AND (P_STARTROW  + (P_PAGENOS - 1) * P_NBROFRCDS  +
                              P_NBROFRCDS - 1);

上面给出的是SP代码中的游标声明,我很难理解。第一个WITH本身似乎很神秘。我已将它与临时表名一起使用,但这是第一次,我看到这类似乎是SP或UDF的东西?有人可以指导我如何理解并理解这一切吗?

进一步补充问题,这里的实际要求是将数据排列在XML中,使得填充了TC401F.T41SBI字段的那些记录应该出现在XML输出的开头。

在以下代码中选择此字段:

trim(TC401F.T41SBI) AS SUB_BOM_ID。如果此字段为非空白,则该字段应首先出现在XML中,并且具有此字段值Blank的所有记录应仅在此后出现。这样做的最佳方法是什么?以任何方式使用ORDER BY似乎并没有帮助,因为XML实际上是通过某些函数创建的,并且排序不影响项在XML中的排列方式。我能想到的一种方法是使用where子句,其中TC401F.T41SBI <> ''首先将那些记录追加到TC401F.T41SBI = ''

2 个答案:

答案 0 :(得分:0)

我能做的最好的就是帮助CTE。

WHERE

这只会生成一个名为MDI_BOM_COMP的表,其中包含三列名为PROD_ID,SITE_ID和XML的列。该表将为每个PROD_ID,SITE_ID创建一条记录,XML的内容将是一个XML代码段,其中包含该产品和站点的所有组件。

现在XML部分可能有点令人困惑,但如果我们将其分解为标量和聚合组件,我们可以使它更容易理解。

首先忽略分组。所以CTE检索 WITH MDI_BOM_COMP(PROD_ID,SITE_ID, xml ) AS ( SELECT TC401F.T41PID,TC401F.T41SID, 中的每一行。 TC401FXMLELEMENT是标量函数。 XMLFORREST创建单个XML元素标记是第一个参数,元素的内容是上例中的第二个参数。 XMLELEMENT就像一堆XMLFORREST连在一起。

XMLELEMENT

因此,在示例中,对于表格中的每一行, XMLSERIALIZE( XMLAGG( XMLELEMENT( NAME "MDI_BOM_COMP", XMLFOREST( trim(TC401F.T41CTY) AS COMPONENT_TYPE, TC401F.T41LNO AS COMP_NUM, trim(TC401F.T41CTO) AS CTRY_OF_ORIGIN, trim(TC401F.T41DSC) AS DESCRIPTION, TC401F.T41EFR AS EFFECTIVE_FROM, TC401F.T41EFT AS EFFECTIVE_TO, trim(TC401F.T41MID) AS MANUFACTURER_ID, trim(TC401F.T41MOC) AS MANUFACTURER_ORG_CODE, trim(TC401F.T41CNO) AS PROD_ID, trim(TC401F.T41POC) AS PROD_ORG_CODE, TC401F.T41QPR AS QTY_PER, trim(TC401F.T41SBI) AS SUB_BOM_ID, trim(TC401F.T41SBO) AS SUB_BOM_ORG_CODE, --ADB01 trim(TC401F.T41VID) AS SUPPLIER_ID, trim(TC401F.T41SOC) AS SUPPLIER_ORG_CODE, TC401F.T41UCT AS UNIT_COST ) ) ) AS CLOB(1M) 都会创建一个XML元素列表,每个元素对应XMLFORRESTCOMPONENT_TYPECOMP_NUM等等。这些元素构成了由CTRY_OF_ORIGIN创建的另一个XML元素MDI_BOM_COMP的内容。

现在,对于表格中的每一行,我们选择了XMLELEMENTPROD_ID,并创建了一些XML。接下来,我们按SITE_IDPROD_ID进行分组。聚合函数SITE_ID将收集每个XMLAGGPROD_ID的所有XML,并将它连接在一起。

最后SITE_ID会将内部XML表示转换为我们都知道和喜爱的字符串格式;)

答案 1 :(得分:0)

我想我找到了符合我要求的答案。我必须在XMLELEMENT函数

之后按字段名添加订单