Переменные связывания Application Engine Peoplecode

У меня есть приведенный ниже шаг PeopleCode в программе Application Engine, которая читает файл CSV с использованием макета файла, а затем вставляет данные в таблицу, и я просто пытаюсь лучше понять, как строка кода (&SQL1 = CreateSQL("%Insert(:1)");) в приведенный ниже скрипт генерируется. Похоже, что CreateSQL использует переменную связывания (: 1) внутри инструкции Insert, но я изо всех сил пытаюсь найти, где эта переменная определена в программе.

Function EditRecord(&REC As Record) Returns boolean;
   Local integer &E;

   &REC.ExecuteEdits(%Edit_Required + %Edit_DateRange + %Edit_YesNo + %Edit_OneZero);
   If &REC.IsEditError Then
      For &E = 1 To &REC.FieldCount
         &MYFIELD = &REC.GetField(&E);
         If &MYFIELD.EditError Then
            &MSGNUM = &MYFIELD.MessageNumber;
            &MSGSET = &MYFIELD.MessageSetNumber;
            &LOGFILE.WriteLine("****Record:" | &REC.Name | ", Field:" | &MYFIELD.Name);
            &LOGFILE.WriteLine("****" | MsgGet(&MSGSET, &MSGNUM, ""));
         End-If;
      End-For;
      Return False;
   Else
      Return True;
   End-If;
End-Function;

Function ImportSegment(&RS2 As Rowset, &RSParent As Rowset)
   Local Rowset &RS1, &RSP;
   Local string &RecordName;
   Local Record &REC2, &RECP;
   Local SQL &SQL1;
   Local integer &I, &L;
   &SQL1 = CreateSQL("%Insert(:1)");
   rem &SQL1 = CreateSQL("%Insert(:1) Order by COUNT_ORDER");
   &RecordName = "RECORD." | &RS2.DBRecordName;
   &REC2 = CreateRecord(@(&RecordName));
   &RECP = &RSParent(1).GetRecord(@(&RecordName));
   For &I = 1 To &RS2.ActiveRowCount
      &RS2(&I).GetRecord(1).CopyFieldsTo(&REC2);
      If (EditRecord(&REC2)) Then
         &SQL1.Execute(&REC2);
         &RS2(&I).GetRecord(1).CopyFieldsTo(&RECP);
         For &L = 1 To &RS2.GetRow(&I).ChildCount
            &RS1 = &RS2.GetRow(&I).GetRowset(&L);
            If (&RS1 <> Null) Then
               &RSP = &RSParent.GetRow(1).GetRowset(&L);
               ImportSegment(&RS1, &RSP);
            End-If;
         End-For;
         If &RSParent.ActiveRowCount > 0 Then
            &RSParent.DeleteRow(1);
         End-If;
      Else
         &LOGFILE.WriteRowset(&RS);
         &LOGFILE.WriteLine("****Correct error in this record and delete all error messages");
         &LOGFILE.WriteRecord(&REC2);
         For &L = 1 To &RS2.GetRow(&I).ChildCount
            &RS1 = &RS2.GetRow(&I).GetRowset(&L);
            If (&RS1 <> Null) Then
               &LOGFILE.WriteRowset(&RS1);
            End-If;
         End-For;
      End-If;
   End-For;
End-Function;

rem *****************************************************************;
rem * PeopleCode to Import Data                                     *;
rem *****************************************************************;
Local File &FILE1, &FILE3;
Local Record &REC1;
Local SQL &SQL1;
Local Rowset &RS1, &RS2;
Local integer &M;

&FILE1 = GetFile("\\nt115\apps\interface_prod\interface_in\Item_Loader\ItemPriceFile.csv", "r", "a", %FilePath_Absolute);
&LOGFILE = GetFile("\\nt115\apps\interface_prod\interface_in\Item_Loader\ItemPriceFile.txt", "r", "a", %FilePath_Absolute);

&FILE1.SetFileLayout(FileLayout.GH_ITM_PR_UPDT);
&LOGFILE.SetFileLayout(FileLayout.GH_ITM_PR_UPDT); 
&RS1 = &FILE1.CreateRowset();
&RS = CreateRowset(Record.GH_ITM_PR_UPDT);
REM &SQL1 = CreateSQL("%Insert(:1)");
&SQL1 = CreateSQL("%Insert(:1)");
/*Skip Header Row:  The following line of code reads the first line in the file layout (the header) 
and does nothing.  Then the pointer goes to the next line in the file and starts using the 
file.readrowset*/
&some_boolean = &FILE1.ReadLine(&string);
&RS1 = &FILE1.ReadRowset();

While &RS1 <> Null
   ImportSegment(&RS1, &RS);
   &RS1 = &FILE1.ReadRowset();
End-While;

&FILE1.Close();
&LOGFILE.Close();

person JBinson88    schedule 09.10.2018    source источник


Ответы (2)


:1 исходит из линии ниже &SQL1.Execute(&REC2);

&REC2 назначается объект записи, поэтому строка &SQL1.Execute(&REC2); оценивается как %Insert(your_record_object)

Вот простой пример, который делает то же самое вещь

Вот описание %Insert< /а>

person Ben Rubin    schedule 10.10.2018
comment
Бен, спасибо за объяснение - я все еще немного борюсь, так как не могу найти, где определяется фактическое имя таблицы (в которую вставляются строки). Я ищу имя таблицы на протяжении всего этого шага в программе AE и нигде не нахожу имя своей таблицы. Так что мне любопытно, откуда он на самом деле берет это? Все работает, это просто для моего собственного любопытства. Спасибо! - person JBinson88; 10.10.2018
comment
@ JBinson88 Я ответил на этот вопрос как ответ. Начал ломать клавиатуру, и вскоре комментарий стал слишком длинным. - person Based; 10.10.2018
comment
@ JBinson88 Ответ Питера очень хорошо объясняет ответ на ваш комментарий. - person Ben Rubin; 10.10.2018

Ответьте, потому что слишком долго комментировать:

Имя таблицы, скорее всего, (PS_)GH_ITM_PR_UPDT. Общее мнение состоит в том, чтобы называть FileLayout так же, как и запись, на которой он основан.

Если нет, то он определяется в FileLayout.GH_ITM_PR_UPDT. Откройте FileLayout, щелкните правой кнопкой мыши сегмент и в разделе «Свойства выбранного узла» вы найдете «Имя записи файла».

В вашем коде эта запись переносится в &RS1.

&FILE1.SetFileLayout(FileLayout.GH_ITM_PR_UPDT);
&RS1 = &FILE1.CreateRowset();

Набор строк представляет собой набор строк. Строка состоит из записей, а запись — это строка данных из таблицы базы данных. (Типы данных Peoplesoft Object Data Types забавны...) Этот набор строк заполняется данными в следующем выражении:

&RS1 = &FILE1.ReadRowset();

Это использует ваш файл в качестве входных данных и выводит коллекцию наборов строк, сопоставляя данные с записями на основе того, как вы определили свой FileLayout. Результат передается в функцию ImportSegment:

ImportSegment(&RS1, &RS); 
Function ImportSegment(&RS2 As Rowset, &RSParent As Rowset)

&RS2 в функции является ссылкой на &RS1 в остальной части вашего кода. Здесь также скрыто имя таблицы:

&RecordName = "RECORD." | &RS2.DBRecordName;

Поэтому, если вы не можете/не хотите проверять FileLayout, вы можете вывести &RS2.DBRecordName с окном сообщений, и ваш ответ будет Журнал сообщений вашего Process Monitor.

Наконец, для этой таблицы базы данных создается объект записи, который заполняется строкой из набора строк. Эта запись вставляется в таблицу базы данных:

&REC2 = CreateRecord(@(&RecordName));
&RS2(&I).GetRecord(1).CopyFieldsTo(&REC2);
&SQL1 = CreateSQL("%Insert(:1)");
&SQL1.Execute(&REC2); 

TLDR:

Имя таблицы можно найти в FileLayout или вывести в функции ImportSegment как &RS2.DBRecordName.

person Based    schedule 10.10.2018
comment
Спасибо, Питер! Это полезно! - person JBinson88; 10.10.2018