значение, разделенное запятыми, для цикла, работающего с жестко закодированным значением, но не со значением параметра - PullRequest
0 голосов
/ 17 июня 2019

Моя основная проблема: я хочу передать строку, разделенную запятыми, в хранимый процесс Oracle 9i и внутри него, я хочу перебрать его и использовать каждое значение в операторах вставки.Вышеуказанная версия Oracle 9i предоставляет некоторую внутреннюю функцию, например regex_susbstr, которую можно использовать для реализации этого, но с помощью Oracle 9i я могу найти один код, который я вставил ниже.Это прекрасно работает, когда я использовал жестко закодированное значение строк, разделенных запятыми, в хранимой процедуре, но когда он передается через входной параметр хранимой процедуры, он рассматривает эту строку как единственное значение и просто проходит через нее один раз и вставляет полную строку в столбец

CREATE OR REPLACE PROCEDURE SP_INSERTDOCUMENTDETAILS_BD
(
    BatchId  IN NUMBER,
    strDocumentIds IN varchar2
)
IS
  type table_varchar  is table of varchar2(32767);
  var_table_varchar  table_varchar;
begin
  var_table_varchar  := table_varchar(strDocumentIds);
  var_table_varchar  := table_varchar('004416979','004416987','004416988','004416989');

  for elem in 1 .. var_table_varchar.count loop
      Insert into documentdetails(DocumentID,BatchID,DocumentSRCGUID,Name,documentType,ExtractionStatus,InjectionStatus) 
      values(DocumentID_SEQ.NEXTVAL,BatchId,var_table_varchar(elem),'','',1,1);
  end loop;
end;
/
show errors;

1 Ответ

0 голосов
/ 17 июня 2019

Ваш тип table_varchar не выполняет магический анализ строки, содержащей значения, разделенные запятыми, в отдельные подстроки.Вы все еще должны это сделать.

Вот хорошая маленькая функция, которая выполняет анализ для вас.Он использует встроенный тип системы DBMS_SQL.VARCHAR2A вместо типа таблицы, но результат аналогичен:

FUNCTION EXTRACT_TOKENS(p_string     IN VARCHAR2,
                        p_separators IN VARCHAR2)
  RETURN DBMS_SQL.VARCHAR2A
IS
  arrTokens DBMS_SQL.VARCHAR2A;
BEGIN
  WITH sel_string AS 
      (SELECT p_string AS fullstring FROM DUAL)
  SELECT SUBSTR(fullstring, beg + 1, end_p - beg - 1) AS token
    BULK COLLECT INTO arrTokens
    FROM (SELECT beg, LEAD(beg) OVER (ORDER BY beg) AS end_p, fullstring
            FROM (SELECT beg, fullstring
                    FROM (SELECT LEVEL beg, fullstring
                            FROM sel_string
                            CONNECT BY LEVEL <= LENGTH(fullstring))
                    WHERE INSTR(p_separators, SUBSTR(fullstring, beg, 1)) > 0
                  UNION ALL
                    SELECT 0, fullstring FROM sel_string
                  UNION ALL
                    SELECT LENGTH(fullstring) + 1, fullstring FROM sel_string))
    WHERE end_p IS NOT NULL AND
          end_p > beg + 1;

  RETURN arrTokens;
END EXTRACT_TOKENS;

Вы можете использовать это, изменив свою процедуру на:

CREATE OR REPLACE PROCEDURE SP_INSERTDOCUMENTDETAILS_BD
(
    BatchId  IN NUMBER,
    strDocumentIds IN varchar2
)
IS
  var_table_varchar  DBMS_SQL.VARCHAR2A ;
begin
  var_table_varchar := EXTRACT_TOKENS(strDocumentIds, ',');

  for elem in 1 .. var_table_varchar.count loop
      Insert into documentdetails
        (DocumentID, BatchID, DocumentSRCGUID, Name, documentType, ExtractionStatus, InjectionStatus) 
      values
        (DocumentID_SEQ.NEXTVAL, BatchId, var_table_varchar(elem), ',' , 1, 1);
  end loop;
end SP_INSERTDOCUMENTDETAILS_BD;

Обратите внимание, что это все равно не будет работать, потому что список полей в вашем операторе INSERT имеет семь названных полей, в то время как предложение VALUES содержит только шесть значений, но я уверен, что вы можете это исправить.

Удачи.

...