oracle utl_lms用变量替换整数

时间:2016-05-15 18:42:42

标签: oracle plsql oracle11g str-replace substitution

我使用oracle的UTL_LMS.MESSAGE_FORMAT遇到了一个奇怪的问题。当使用变量替换来定位%d替换时,UTL_LMS正在悄悄地无法替换和中断我的调用堆栈中的异常消息。

UTL_LMS.FORMAT_MESSAGE调用VARCHAR参数,但doc(11gR2)示例中的类型转换似乎与整数变量兼容。但是,我的%d永远不会被替换。

我希望得到一些想法/建议。下面是失败的一个例子。

运行以下内容:

DECLARE
  C_INTRANSITIVE_VERB CONSTANT VARCHAR2(50) := 'breakdance';
  C_SUBJECT_NOUN CONSTANT VARCHAR2(50) := 'hobbit';
  C_PREPOSITION_OBJECT CONSTANT VARCHAR2(50) := 'wookie';
  C_MULTIPLIER CONSTANT INTEGER := 19;
  C_TEMPLATE CONSTANT VARCHAR2(400) := 'The %s likes to %s with the %s %d times a day.';
BEGIN
  DBMS_OUTPUT.PUT_LINE('My integer is: '|| C_MULTIPLIER);
  DBMS_OUTPUT.PUT_LINE(
      UTL_LMS.FORMAT_MESSAGE(C_TEMPLATE,C_SUBJECT_NOUN,C_INTRANSITIVE_VERB,C_PREPOSITION_OBJECT,C_MULTIPLIER)
  );
END;
/

收率:

  

我的整数是:19

     

霍比特人喜欢每天与wookie霹雳舞。

但是,下面转换raw int fine:

DECLARE
  C_INTRANSITIVE_VERB CONSTANT VARCHAR2(50) := 'breakdance';
  C_SUBJECT_NOUN CONSTANT VARCHAR2(50) := 'hobbit';
  C_PREPOSITION_OBJECT CONSTANT VARCHAR2(50) := 'wookie';
  C_MULTIPLIER CONSTANT INTEGER := 19;
  C_TEMPLATE CONSTANT VARCHAR2(400) := 'The %s likes to %s with the %s %d times a day.';
BEGIN
  DBMS_OUTPUT.PUT_LINE('My integer is: '|| C_MULTIPLIER);
  DBMS_OUTPUT.PUT_LINE(
      UTL_LMS.FORMAT_MESSAGE(C_TEMPLATE,C_SUBJECT_NOUN,C_INTRANSITIVE_VERB,C_PREPOSITION_OBJECT,19)
  );
END;
/
  

我的整数是:19

     

霍比特人喜欢每天19次与wookie霹雳舞。

以下解决方法是不可取的。

DECLARE
  C_INTRANSITIVE_VERB CONSTANT VARCHAR2(50) := 'breakdance';
  C_SUBJECT_NOUN CONSTANT VARCHAR2(50) := 'hobbit';
  C_PREPOSITION_OBJECT CONSTANT VARCHAR2(50) := 'wookie';
  C_MULTIPLIER CONSTANT INTEGER := 19;
  C_TEMPLATE CONSTANT VARCHAR2(400) := 'The %s likes to %s with the %s %d times a day.';
BEGIN
  DBMS_OUTPUT.PUT_LINE('My integer is: '|| C_MULTIPLIER);
  DBMS_OUTPUT.PUT_LINE(
      UTL_LMS.FORMAT_MESSAGE(C_TEMPLATE,C_SUBJECT_NOUN,C_INTRANSITIVE_VERB,C_PREPOSITION_OBJECT,TO_CHAR(C_MULTIPLIER))
  );
END;
/
  

我的整数是:19

     

霍比特人喜欢每天19次与wookie霹雳舞。

  1. 为什么FORMAT_MESSAGE接受原始整数,但在INTEGER类型(或常规NUMBER类型)变量上失败?
  2. 是否有更好的预包装(11g)dbms消息格式化器已经可用?
  3. oracle 11g中有关清除消息格式的任何其他建议吗?我会考虑包装java的MessageFormat / String#format(),或者创建一个处理char类型转换的FORMAT_MESSAGE委托,但是我更愿意为所有需要它的数据库避免这种情况,而且我会这样做。我不太热衷于"只记得" to_char()随处可见故障相当安静。
  4. 谢谢!

1 个答案:

答案 0 :(得分:3)

查看位于

的文档

https://docs.oracle.com/database/121/ARPLS/u_lms.htm#ARPLS71196

该示例指定PLS_INTEGER而不是Integer或Number。我已经对此进行了测试,并且在没有Integer的地方使用PLS_INTEGER可以工作。

我知道这不是理想的解决方案,并且不确定将变量定义为pls_integer是否适合您。但是可能会有帮助。

DECLARE
  C_INTRANSITIVE_VERB CONSTANT VARCHAR2(50) := 'breakdance';
  C_SUBJECT_NOUN CONSTANT VARCHAR2(50) := 'hobbit';
  C_PREPOSITION_OBJECT CONSTANT VARCHAR2(50) := 'wookie';
  C_MULTIPLIER CONSTANT PLS_INTEGER := 19;
  C_TEMPLATE CONSTANT VARCHAR2(400) := 'The %s likes to %s with the %s %d times a day.';
BEGIN
  DBMS_OUTPUT.PUT_LINE('My integer is: '|| C_MULTIPLIER);
  DBMS_OUTPUT.PUT_LINE(
      UTL_LMS.FORMAT_MESSAGE(C_TEMPLATE,C_SUBJECT_NOUN,C_INTRANSITIVE_VERB,C_PREPOSITION_OBJECT,C_MULTIPLIER)
  );
END;

提供输出

My integer is: 19
The hobbit likes to breakdance with the wookie 19 times a day.