您的字符串中没有多余的空格,如果是的话,您trim()
将再次删除它们。SQL*Plus 只是以您不期望的方式格式化结果。文档提到了列类型的默认格式,通常可以为系统函数解决这个问题(尽管字符集可以使它比你预期的要大)。
似乎SQL *Plus 和 SQL Developer 无法为您的rpad
案例确定合理的默认值,但可以为您的substr
. 好吧,SQL*Plus 实际上只是从数据库中获取结果集游标,并使用游标元数据来确定应用于显示字段的默认宽度,因此它没有从元数据中获得您期望的长度。但它应该使用什么长度?
如果填充长度是一个简单的值,数据库只知道该值有多大rpad
——它甚至不介意零(它返回 null,您依赖它)。如果填充长度由函数确定,那么除了在返回元数据和实际数据之前为结果集中的每个值计算它之外,没有办法判断结果可能有多大,这是不切实际的,并且会随着数据的变化产生不一致的输出。
即使在您的情况下看起来很简单,尝试确定理论上的最大值也是不切实际的。substr
永远不能返回比原始值更长的东西;但rpad
即使从一个短的输入值也可能产生巨大的东西,所以如果它不能轻易确定一个限制(即从一个固定值),它必须允许这种可能性。
所以它很安全,并允许它达到 a 的最大长度varchar2
,即 4000 个字符,正如这个动态 SQL 所示:
declare
l_curid integer;
l_desctab dbms_sql.desc_tab3;
l_colcnt integer;
begin
l_curid := dbms_sql.open_cursor;
dbms_sql.parse(l_curid, 'select rpad(ename, instr(ename,'' '')), '
|| 'rpad(ename, 4), '
|| 'substr(ename, 1, instr(ename,'' '')) '
|| 'from emp where ename like ''B%''' , dbms_sql.native);
dbms_sql.describe_columns3(l_curid, l_colcnt, l_desctab);
for i in 1 .. l_colcnt loop
dbms_output.put_line('column ' || i
|| ' ' || l_desctab(i).col_name
|| ' type ' || l_desctab(i).col_type
|| ' length ' || l_desctab(i).col_max_len
);
end loop;
dbms_sql.close_cursor(l_curid);
end;
/
column 1 RPAD(ENAME,INSTR(ENAME,'')) type 1 length 4000
column 2 RPAD(ENAME,4) type 1 length 16
column 3 SUBSTR(ENAME,1,INSTR(ENAME,'')) type 1 length 40
如您所见,它知道固定长度rpad
和 a的长度substr
(注意,由于多字节字符集,大小是实际字符串长度的四倍),但在rpad
使用函数时会回落到最大值。
您看到的是 SQL*Plus 显示一个 4000 字符的列。如果您在 SQL Developer 中执行此操作,您会看到该列的标题确实是 4000 个字符。SQL*Plus 通过将显示的列标题减少到行大小来提供一点帮助,并将下一列换行到单独的行上。