我正在编写一个过程,将来自供应商表的数据转换为我们的本地表,并且有许多分配从源表上的游标映射到目标表的ROWTYPE
。所有供应商的字符串列都定义为255,但我们的字符串列定义更严格,通常只有30或50个字符。当源表的字符串太长而目标行类型的列不能接受时,这些映射中的某些映射会抛出VALUE_ERROR
个异常。
目标ROWTYPE
列的目标结果是包含尽可能多的内容,其余部分将被截断。我的第一直觉只是使用SUBSTR
并硬编码最大尺寸,但必须有一个更优雅,更强大的解决方案。
我提出的一个解决方案(虽然它没有给我温暖的模糊感觉)是下面的过程,它只处理VALUE_ERROR
异常并重试映射。
PROCEDURE p_safe_mapper(p_dest IN OUT VARCHAR2, p_out IN VARCHAR2) IS
counter INTEGER := 0;
BEGIN
--only loop for as many characters are in the source string
WHILE counter < length(p_src) LOOP
BEGIN
--attempt to map, trimming COUNTER characters from the end of the source string. If it works, we're done.
p_dest := substr(p_src,
0,
length(p_src) - counter);
EXIT;
EXCEPTION
--else if we get an error, increment the counter to try again with the source string one character shorter.
WHEN value_error THEN
counter := counter + 1;
END;
END LOOP;
END;
我还考虑过查询ALL_TAB_COLUMNS
表格列的大小,但我不知道如何通过ROWTYPE
来实现这一目标。
基本上,由于Oracle显然知道我的变量的最大大小 - 无论是ROWTYPEs
,游标还是普通的VARCHAR2s
- 我希望获得一个可以使用的通用过程/函数安全地在它们之间进行分配,截断多余的字符。
答案 0 :(得分:1)
我可以看到两种方法 -
A)更改p_safe_mapper以接受定义最大允许输出字符串大小的第三个参数
或
B)更改p_safe_mapper以接受目标表和列名称,并使用这些名称在* _TAB_COLUMNS视图之一中查找最大大小。
分享并享受。