【问题标题】:Porting Oracle procedure to PostgreSQL (exception codes from orafce for utl_file module)将 Oracle 过程移植到 PostgreSQL(来自 orafce 的 utl_file 模块的异常代码)
【发布时间】:2017-09-22 20:26:45
【问题描述】:

我正在进行从 Oracle 到 PostgreSQL 的数据库迁移。我们使用ora2pg 使转换成为可能,并使用orafce PostgreSQL 插件来实现功能兼容性。

我们刚刚开始,还有很多工作要做。

现在我使用存储过程(从 ora2pg 脚本输出),在解决了不同的语法错误之后,我不知道如何解决最后一个错误。

特别是有问题的代码如下:

 select utl_file.put_line(vIdLog,'******************************** COMPTE RENDU PURGE_DOUBLONS_FS **************************');
 select utl_file.put_line(vIdLog,'*      - Debut du traitement le          : '||vDateDebut);
 select utl_file.put_line(vIdLog,'*');
 select utl_file.put_line(vIdLog,'*      - Nb de lun appairées à plusieurs ZV  : ' || vNbLunMultiZV);
 select utl_file.put_line(vIdLog,'*      - Nb FS appairée à plusieurs ZV       : ' || vNbUpdateFsMultiZV);
 select utl_file.put_line(vIdLog,'*      - Nb Liens Lun/FS en suppression logique    : ' || vNbUpdateLunMultiZV);
 select utl_file.put_line(vIdLog,'*      - Nb Liens FS en suppression logique    : ' || vNbUpdateFsMultiZV);
 select utl_file.put_line(vIdLog,'*      - Nb Liens FS(ZG mono ZV)en suppression logique    : ' || vNbUpdateLunFSZVseule);
 select utl_file.put_line(vIdLog,'*      - Nb Liens FS(ZG mono ZV)en suppression logique 2  : ' || vNbUpdateLunFSZVseule2);
 select utl_file.put_line(vIdLog,'*      - Nb Liens LUN/FS ZV obsolètes             : ' || vNbOldLunZV);
 select utl_file.put_line(vIdLog,'*      - Nb Liens LUN/FS ZG obsolètes             : ' || vNbOldLunZG);
 select utl_file.put_line(vIdLog,'*      - Temps de traitement de calcul   : ' || OUTILS.time_to_char(tTotal));
 select utl_file.put_line(vIdLog,'*');
 select utl_file.put_line(vIdLog,'*      - Fin du calcul HOST_LUN le       : ' || to_char(clock_timestamp(), 'DD/MM/YYYY HH24:MI:SS'));
 select utl_file.put_line(vIdLog,'************************** FIN COMPTE RENDU PURGE_DOUBLONS_FS ****************************');
 select utl_file.fclose(vIdLog);
EXCEPTION
 when UTL_FILE.INVALID_PATH then
   select Fin_traitement_fichier('Erreur E/S');
   RAISE EXCEPTION '%', 'File location or filename was invalid.';
 when UTL_FILE.INVALID_MODE then
   select Fin_traitement_fichier('Erreur E/S');
   RAISE EXCEPTION '%', 'The open_mode parameter in FOPEN was invalid.';
 when others then
   select Fin_traitement_fichier(SQLERRM);
   RAISE NOTICE 'ERR005 : ERREUR TRAITEMENT PURGE_DOUBLONS_FS : %', SQLERRM;
   IF cFs%ISOPEN THEN
     CLOSE cFs;
   END IF;

产生的错误如下

ERROR:  syntax error at or near "UTL_FILE"
LINE 341:    RAISE EXCEPTION '%', 'File location or filename was inval...
                     ^
********** Error **********

如果我只使用异常处理的“当其他人时”部分它可以正常工作,所以问题来自常量UTL_FILE.INVALID_PATHUTL_FILE.INVALID_MODE 不能被 PostgreSQL 识别。

知道如何处理来自 orafce 的 utl_file 模块的异常代码吗?

【问题讨论】:

  • 选择 Fin_traitement_fichier('Erreur E/S');无效 - 您应该使用 PERFORM 而不是 SELECT。 pg 不支持语法 cFs%ISOPEN
  • 我在这里处理完全相同的情况。如何分配这些自定义异常?当我在 SQLERRM 中使用 case 时,我的 case 出现语法错误。你能解释一下你到底做了什么吗?

标签: postgresql plpgsql orafce


【解决方案1】:

PLpgSQL 不允许定义自己的异常 - 所以 Orafce 不能定义 UTL_FILE.* 异常。您应该查看 orafce source code file.c 以查看已使用的异常列表:

代码使用宏CUSTOM_EXCEPTION

#define CUSTOM_EXCEPTION(msg, detail) \
    ereport(ERROR, \
        (errcode(ERRCODE_RAISE_EXCEPTION), \
         errmsg("%s", msg), \
         errdetail("%s", detail)))

在这个list 中,您可以看到所有 PostgreSQL 异常。所以使用异常的名称是raise_exception,异常原因在SQLERRM变量中。所以你的代码应该是这样的:

WHEN RAISE_EXCEPTION THEN
  CASE SQLERRM
   WHEN 'UTL_FILE_INVALID_PATH' THEN
     PERFORM ...
   WHEN 'UTL_FILE_INVALID_MODE' THEN
     PERFORM ...
   ELSE 
     PERFORM ...
   END;

【讨论】:

  • 我在这里处理完全相同的情况。如何分配这些自定义异常?当我在 SQLERRM 中使用 case 时,我遇到了一个语法错误。你能解释一下你到底做了什么吗?
  • @Mariel - 我不太了解你的问题。 PLpgSQL 具有内置异常列表,可以通过长名称(字符串)指定。 SQLSTATE 应指定任何其他异常 - postgresql.org/docs/9.6/static/plpgsql-errors-and-messages.html
猜你喜欢
  • 2011-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-15
  • 1970-01-01
相关资源
最近更新 更多