逗号分隔值循环使用硬编码值但不使用参数值

comma separated value to loop working with Hardcoded value but not with parameter value

我的主要问题是:我想将逗号分隔的字符串传递给 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;

您的 table_varchar 类型不会神奇地将包含 comma-separated 值的字符串解析为单独的子字符串。你还是得这么做。

这是一个很好的小函数,可以为您进行解析。它使用 built-in 系统类型 DBMS_SQL.VARCHAR2A 而不是您的 table 类型,但结果类似:

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 子句仅包含六个值,但我相信您可以修复那。