【问题标题】:How to store multiple SQLExec values in variable(s)如何在变量中存储多个 SQLExec 值
【发布时间】:2018-10-16 15:55:24
【问题描述】:

我想知道是否可以在应用程序引擎 PeopleCode 中运行 SQLExec 命令,如果返回多行,它们是如何存储在变量中的?

例如 - 我正在添加以下代码:

SQLExec("SELECT C.UNIT_OF_MEASURE FROM PS_ITM_VNDR_UOM_PR C WHERE C.INV_ITEM_ID = :1 AND C.VENDOR_ID = :2 AND C.EFFDT = (SELECT MAX(C1.EFFDT) FROM PS_ITM_VNDR_UOM_PR C1 WHERE C.SETID = C1.SETID AND C.INV_ITEM_ID = C1.INV_ITEM_ID AND C.VENDOR_SETID = C1.VENDOR_SETID AND C.VENDOR_ID = C1.VENDOR_ID AND C.VNDR_LOC = C1.VNDR_LOC AND C.UNIT_OF_MEASURE = C1.UNIT_OF_MEASURE AND C.CURRENCY_CD = C1.CURRENCY_CD AND C.QTY_MIN = C1.QTY_MIN)" , &InvItemId, &VendorID, &UOMResult

在某些情况下,不止一行(值)可能会从 SQL 查询传回 &UOMResult 变量,我不确定 PeopleCode 将如何处理这个问题,但最终我想比较 &UOMResult 中的值变量到另一个名为 &UOM 的变量,如果它们不同(没有匹配),那么做某些“东西”,否则做“其他东西”。

如果从 SQL 返回的值超过 1 个,变量是否会转换为数组?只是想知道这会是什么样子...感谢您的任何反馈。

10/17/18 编辑:

Local SQL &SQL;
    Local string &VendorId, &InvItemId, &ItmIdVndr, &UOM, &ConvRate, &PriceVndr, &Oprid, &PriceStatus, &VendorId_check, &insert_cols, &insert_select, &insert_where, &insert_sql, &Error, &MaxEffdt, &ItmField;
    Local date &Effdt;
    Local Record &ITM_VNDR_UOM_PR, &REC, &MASTER_ITEM_TBL;

    &Oprid = "'BATCH'";
    &PriceStatus = "2";
    &Error = "N";

    MessageBox(0, "", 0, 0, "**** BEGINING OF VALIDATION ERRORS ****");

    &SQL = CreateSQL("SELECT VENDOR_ID, INV_ITEM_ID, ITM_ID_VNDR, UNIT_OF_MEASURE, CONVERSION_RATE, PRICE_VNDR, %DateOut(EFFDT), ITEM_FIELD_C10_B FROM PS_GH_ITM_PR_UPDT ORDER BY VENDOR_ID, INV_ITEM_ID, ITM_ID_VNDR", &VendorId, &InvItemId, &ItmIdVndr, &UOM, &ConvRate, &PriceVndr, &Effdt, &ItmField);
    MessageBox(0, "", 0, 0, &VendorId | " " | &InvItemId | " " | &ItmIdVndr | " " | &UOM | " " | &ConvRate | " " | &PriceVndr | " " | &Effdt | " " | &ItmField | " " | &Error);
    While &SQL.Fetch(&VendorId, &InvItemId, &ItmIdVndr, &UOM, &ConvRate, &PriceVndr, &Effdt, &ItmField)

       SQLExec("SELECT A.VENDOR_ID FROM PS_ITM_VENDOR A, PS_ITM_VNDR_UOM B WHERE A.SETID = B.SETID AND A.INV_ITEM_ID = B.INV_ITEM_ID AND A.VENDOR_SETID = B.VENDOR_SETID AND A.VENDOR_ID = B.VENDOR_ID AND A.VENDOR_ID = :1 AND A.INV_ITEM_ID = :2 AND A.ITM_ID_VNDR = :3 AND A.ITM_VNDR_PRIORITY = 1 AND B.UNIT_OF_MEASURE = :4 AND B.CONVERSION_RATE = :5", &VendorId, &InvItemId, &ItmIdVndr, &UOM, &ConvRate, &VendorId_check);

       If None(&VendorId_check) Then;
          &Error = "Y";
          MessageBox(0, "", 0, 0, &VendorId | " " | &InvItemId | " " | &ItmIdVndr | " " | &UOM | " " | &ConvRate | " " | &PriceVndr | " " | &Effdt | " " | &ItmField | " " | &Error);
       Else;
          &CurrentDateTime = %Datetime;
          &Oprid = %OperatorId;
          &RECITEM = CreateRecord(Record.ITM_VNDR_UOM_PR);
          /*CHC Modification - Denise Smith - 8/8/2012 - CHC_PO_96588 - Begin */
          /*SQLExec("SELECT TO_CHAR(C.EFFDT,'DD-MON-YYYY') FROM PS_ITM_VNDR_UOM_PR C WHERE C.INV_ITEM_ID = :1 AND C.VENDOR_ID = :2 AND C.UNIT_OF_MEASURE = :3 AND C.EFFDT = (SELECT MAX(C1.EFFDT) FROM PS_ITM_VNDR_UOM_PR C1 WHERE C.SETID = C1.SETID AND C.INV_ITEM_ID = C1.INV_ITEM_ID AND C.VENDOR_SETID = C1.VENDOR_SETID AND C.VENDOR_ID = C1.VENDOR_ID AND C.VNDR_LOC = C1.VNDR_LOC AND C.UNIT_OF_MEASURE = C1.UNIT_OF_MEASURE AND C.CURRENCY_CD = C1.CURRENCY_CD AND C.QTY_MIN = C1.QTY_MIN)  ", &InvItemId, &VendorId, &UOM, &MaxEffdt);*/

          /*GETTING MAX EFFECTIVE DATED ROW TO COPY EXISTING ROW VALUES FROM INTO NEW ROW */
         SQLExec("SELECT C.EFFDT FROM PS_ITM_VNDR_UOM_PR C WHERE C.INV_ITEM_ID = :1 AND C.VENDOR_ID = :2 AND C.UNIT_OF_MEASURE = :3 AND C.EFFDT = (SELECT MAX(C1.EFFDT) FROM PS_ITM_VNDR_UOM_PR C1 WHERE C.SETID = C1.SETID AND C.INV_ITEM_ID = C1.INV_ITEM_ID AND C.VENDOR_SETID = C1.VENDOR_SETID AND C.VENDOR_ID = C1.VENDOR_ID AND C.VNDR_LOC = C1.VNDR_LOC AND C.UNIT_OF_MEASURE = C1.UNIT_OF_MEASURE AND C.CURRENCY_CD = C1.CURRENCY_CD AND C.QTY_MIN = C1.QTY_MIN)  ", &InvItemId, &VendorId, &UOM, &MaxEffdt);

         &SQL2 = CreateSQL("SELECT C.UNIT_OF_MEASURE FROM PS_ITM_VNDR_UOM_PR C WHERE C.INV_ITEM_ID = :1 AND C.VENDOR_ID = :2 AND C.EFFDT = (SELECT MAX(C1.EFFDT) FROM PS_ITM_VNDR_UOM_PR C1 WHERE C.SETID = C1.SETID AND C.INV_ITEM_ID = C1.INV_ITEM_ID AND C.VENDOR_SETID = C1.VENDOR_SETID AND C.VENDOR_ID = C1.VENDOR_ID AND C.VNDR_LOC = C1.VNDR_LOC AND C.UNIT_OF_MEASURE = C1.UNIT_OF_MEASURE AND C.CURRENCY_CD = C1.CURRENCY_CD AND C.QTY_MIN = C1.QTY_MIN) ", &InvItemId, &VendorId);
/* This is where I am afraid the While loop will create extra inserts if the SQL above contains more than 1 Row. That is why I only want to evaluate only once if possible. For example if I am wanting to add a new price with a new UOM -'TP' that does not already exist for this item I want to look at the output value(s) from above &SQL2 and compare to my &UOM variable. If I keep this logic in a While loop I'm afraid it will end up creating more insert's then necessary */
         While &SQL2.Fetch(&UOMResult)
          If &UOM = &UOMResult Then;

          SQLExec("%SelectAll(:1) WHERE INV_ITEM_ID = :2 AND VENDOR_ID = :3 AND UNIT_OF_MEASURE = :4 AND (CONVERT(CHAR(10),EFFDT,121)) = :5", &RECITEM, &InvItemId, &VendorId, &UOM, &MaxEffdt, &RECITEM);
          /*SQLExec("%SelectAll(:1) WHERE INV_ITEM_ID = :2 AND VENDOR_ID = :3 AND UNIT_OF_MEASURE = :4 AND EFFDT = :5", &RECITEM, &InvItemId, &VendorId, &UOM, &MaxEffdt, &RECITEM); */
          &new_UNIT_OF_MEASURE = &RECITEM.UNIT_OF_MEASURE.Value;
          &REC = CreateRecord(Record.ITM_VNDR_UOM_PR);
          &REC.SETID.Value = &RECITEM.SETID.Value;
          &REC.INV_ITEM_ID.Value = &RECITEM.INV_ITEM_ID.Value;
          &REC.VENDOR_SETID.Value = &RECITEM.VENDOR_SETID.Value;
          &REC.VENDOR_ID.Value = &RECITEM.VENDOR_ID.Value;
          &REC.VNDR_LOC.Value = &RECITEM.VNDR_LOC.Value;
          &REC.UNIT_OF_MEASURE.Value = &RECITEM.UNIT_OF_MEASURE.Value;
          &REC.CURRENCY_CD.Value = &RECITEM.CURRENCY_CD.Value;
          &REC.QTY_MIN.Value = &RECITEM.QTY_MIN.Value;
          &REC.EFFDT.Value = &Effdt;
          &REC.EFF_STATUS.Value = &RECITEM.EFF_STATUS.Value;
          &REC.PRICE_VNDR.Value = &PriceVndr;
          &REC.UNIT_PRC_TOL.Value = &RECITEM.UNIT_PRC_TOL.Value;
          &REC.EXT_PRC_TOL.Value = &RECITEM.EXT_PRC_TOL.Value;
          &REC.PCT_UNIT_PRC_TOL.Value = &RECITEM.PCT_UNIT_PRC_TOL.Value;
          &REC.PCT_EXT_PRC_TOL.Value = &RECITEM.PCT_EXT_PRC_TOL.Value;
          &REC.USE_STD_TOLERANCES.Value = &RECITEM.USE_STD_TOLERANCES.Value;
          &REC.QTY_RECV_TOL_PCT.Value = &RECITEM.QTY_RECV_TOL_PCT.Value;
          &REC.UNIT_PRC_TOL_L.Value = &RECITEM.UNIT_PRC_TOL_L.Value;
          &REC.PCT_UNIT_PRC_TOL_L.Value = &RECITEM.PCT_UNIT_PRC_TOL_L.Value;
          &REC.EXT_PRC_TOL_L.Value = &RECITEM.EXT_PRC_TOL_L.Value;
          &REC.PCT_EXT_PRC_TOL_L.Value = &RECITEM.PCT_EXT_PRC_TOL_L.Value;
          &REC.BU_PRICE_STATUS.Value = "2";
          &REC.STD_PRICE_STATUS.Value = "2";
          &REC.LEAD_TIME.Value = &RECITEM.LEAD_TIME.Value;
          &REC.OPRID_MODIFIED_BY.Value = &Oprid;
          &REC.LAST_DTTM_UPDATE.Value = &CurrentDateTime;
          &REC.PRICE_CHANGE.Value = &RECITEM.PRICE_CHANGE.Value;
          &REC.Insert();

         Else;

    SQLExec("%SelectAll(:1) WHERE INV_ITEM_ID = :2 AND VENDOR_ID = :3 AND UNIT_OF_MEASURE = :4 AND (CONVERT(CHAR(10),EFFDT,121)) = :5", &RECITEM, &InvItemId, &VendorId, &UOMResult, &MaxEffdt, &RECITEM);
          /*SQLExec("%SelectAll(:1) WHERE INV_ITEM_ID = :2 AND VENDOR_ID = :3 AND UNIT_OF_MEASURE = :4 AND EFFDT = :5", &RECITEM, &InvItemId, &VendorId, &UOMResult, &MaxEffdt, &RECITEM); */
          &new_UNIT_OF_MEASURE = &RECITEM.UNIT_OF_MEASURE.Value;
          &REC = CreateRecord(Record.ITM_VNDR_UOM_PR);
          &REC.SETID.Value = &RECITEM.SETID.Value;
          &REC.INV_ITEM_ID.Value = &RECITEM.INV_ITEM_ID.Value;
          &REC.VENDOR_SETID.Value = &RECITEM.VENDOR_SETID.Value;
          &REC.VENDOR_ID.Value = &RECITEM.VENDOR_ID.Value;
          &REC.VNDR_LOC.Value = &RECITEM.VNDR_LOC.Value;
          &REC.UNIT_OF_MEASURE.Value = &RECITEM.UNIT_OF_MEASURE.Value;
          &REC.CURRENCY_CD.Value = &RECITEM.CURRENCY_CD.Value;
          &REC.QTY_MIN.Value = &RECITEM.QTY_MIN.Value;
          &REC.EFFDT.Value = &Effdt;
          &REC.EFF_STATUS.Value = &RECITEM.EFF_STATUS.Value;
          &REC.PRICE_VNDR.Value = &PriceVndr;
          &REC.UNIT_PRC_TOL.Value = &RECITEM.UNIT_PRC_TOL.Value;
          &REC.EXT_PRC_TOL.Value = &RECITEM.EXT_PRC_TOL.Value;
          &REC.PCT_UNIT_PRC_TOL.Value = &RECITEM.PCT_UNIT_PRC_TOL.Value;
          &REC.PCT_EXT_PRC_TOL.Value = &RECITEM.PCT_EXT_PRC_TOL.Value;
          &REC.USE_STD_TOLERANCES.Value = &RECITEM.USE_STD_TOLERANCES.Value;
          &REC.QTY_RECV_TOL_PCT.Value = &RECITEM.QTY_RECV_TOL_PCT.Value;
          &REC.UNIT_PRC_TOL_L.Value = &RECITEM.UNIT_PRC_TOL_L.Value;
          &REC.PCT_UNIT_PRC_TOL_L.Value = &RECITEM.PCT_UNIT_PRC_TOL_L.Value;
          &REC.EXT_PRC_TOL_L.Value = &RECITEM.EXT_PRC_TOL_L.Value;
          &REC.PCT_EXT_PRC_TOL_L.Value = &RECITEM.PCT_EXT_PRC_TOL_L.Value;
          &REC.BU_PRICE_STATUS.Value = "2";
          &REC.STD_PRICE_STATUS.Value = "2";
          &REC.LEAD_TIME.Value = &RECITEM.LEAD_TIME.Value;
          &REC.OPRID_MODIFIED_BY.Value = &Oprid;
          &REC.LAST_DTTM_UPDATE.Value = &CurrentDateTime;
          &REC.PRICE_CHANGE.Value = &RECITEM.PRICE_CHANGE.Value;
          &REC.Insert();


         End-If;
         End-While;


       End-If;

       /* KDR - 10/11/2018 - Added field ITEM_FIELD_C10_B (&ItmField) to CSV file layout and insert into PS_MASTER_ITEM_TBL (&MASTER_ITEM_TBL) */
       If None(&ItmField) Then;
          &Error = "Y";
          MessageBox(0, "", 0, 0, &VendorId | " " | &InvItemId | " " | &ItmIdVndr | " " | &UOM | " " | &ConvRate | " " | &PriceVndr | " " | &Effdt | " " | &ItmField);
       Else;
          SQLExec("UPDATE PS_MASTER_ITEM_TBL SET ITEM_FIELD_C10_B = :1 WHERE INV_ITEM_ID = :2 AND SETID = 'SHARE' ", &ItmField, &InvItemId);
          /* Else;
           &REC1 = CreateRecord(Record.MASTER_ITEM_TBL);
           &REC1.ITEM_FIELD_C10_B.Value = &ItmField;
           &REC1.SETID.Value = "SHARE";
           &REC1.INV_ITEM_ID.Value = &InvItemId;
           &REC1.Update();
        End-If;  */

       End-If;

    End-While;
    MessageBox(0, "", 0, 0, "**** END OF VALIDATION ERRORS ****");
    MessageBox(0, "", 0, 0, " ");`

【问题讨论】:

    标签: peoplesoft peoplesoft-app-engine peoplecode


    【解决方案1】:

    SQLExec 只存储 1 行的结果。如果您希望能够遍历返回的多行,则需要使用 SQL 对象。更多文档可在 Enterprise PeopleTools PeopleBook 中找到:PeopleCode API 参考 > SQL 类

    Local SQL &sql;
    
    &sql = createsql("SELECT C.UNIT_OF_MEASURE FROM PS_ITM_VNDR_UOM_PR C WHERE C.INV_ITEM_ID = :1 AND C.VENDOR_ID = :2 AND C.EFFDT = (SELECT MAX(C1.EFFDT) FROM PS_ITM_VNDR_UOM_PR C1 WHERE C.SETID = C1.SETID AND C.INV_ITEM_ID = C1.INV_ITEM_ID AND C.VENDOR_SETID = C1.VENDOR_SETID AND C.VENDOR_ID = C1.VENDOR_ID AND C.VNDR_LOC = C1.VNDR_LOC AND C.UNIT_OF_MEASURE = C1.UNIT_OF_MEASURE AND C.CURRENCY_CD = C1.CURRENCY_CD AND C.QTY_MIN = C1.QTY_MIN)",&InvItemId, &VendorID);
    
    while &sql.fetch(&UOMResult)
    
    /* Do you logic here */
    end-while;
    &sql.close;
    

    【讨论】:

    • 感谢您的反馈,听起来我不需要使用任何类型的数组来保存值 - 所以我很好奇当从一个实例返回多行时会发生什么获取。所以我的 SQL 结果存储在 @UOMResult 变量中,但是如果返回了 3 行,我如何访问每一行或特定行?
    • 换句话说,我希望能够在获取过程中知道 &UOMResult 变量中返回的任何值是否与我的 &UOM 变量匹配,如果匹配或不匹配,那么我想最终做一个&REC.Insert,仅在匹配时使用变量 &UOM,如果不匹配则使用 &UOMResult。我在使用 While 循环时看到的问题是,它将继续读取每一行并创建一条新记录,直到从 While -SQL Fetch 处理所有行,我只想运行 SQL 一次,然后使用 If陈述。我更清楚地编辑了上面的帖子
    • 多想一下 - 如果返回到 &UOMResult 变量的(第 1 个)值等于 &UOM 变量,那么是否有一种方法可以将其编码为当 SQL2 Fetch 正在运行时,然后执行 Rec。插入逻辑并跳出循环,否则重新进入循环(以评估下一行)并执行相同的逻辑,直到它找到另一行 &UOMResult 等于 &UOM 或在所有行都被评估后没有匹配找到然后通过第二组 Rec.Insert 逻辑。希望这是有道理的?我很感激任何帮助!谢谢。
    • 你的逻辑是有道理的,而且 PeopleCode 有一个中断命令。所以写 if 语句,如果它是真的,做插入然后中断。有关详细信息,请参阅 PeopleBooks PeopleCode 语言参考。
    【解决方案2】:

    当我使用 App Engine 并且必须根据一组不同的标准创建 2 个或更多结果集时,我采用 2 种方法:

    1. 如果我可以在字段选择子句中使用 case 语句来实现我的目标,那么这是首选方法。
    2. 在多个相互排斥的步骤中编写 SQL(从源表的角度来看)并填充同一个目标表。

    如果可能,我将避免使用 PeopleCode 操作 SQL,因为这样您就必须处理 PeopleCode 的怪癖以及数据库本身。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-26
      • 1970-01-01
      • 1970-01-01
      • 2012-05-31
      相关资源
      最近更新 更多