reg:子字符串和列长度

5vf7fwbs  于 2021-07-24  发布在  Java
关注(0)|答案(3)|浏览(370)

我有个小问题。我有一张table,上面有下面的描述。

SQL> desc ERROR
  Name                                      Null?    Type
  ----------------------------------------- -------- ----------------------------
  DPDATE_TIME                               NOT NULL DATE
  ERR_MSG                                   NOT NULL VARCHAR2(132)
  CODE1                                              VARCHAR2(50)

现在,当我选择下面给出的代码1时,上面的表

SELECT substr(code1, 1,length(code1)) as name From ERROR where code1='xxxxAXP'

NAME
--------------------------------------------------
xxxxAXP
xxxxAXP

它选择该列的长度,然后显示它。我的意思是,它不是只显示7个字符,而是显示50个带有空格的字符。
但如果我这么做了

SELECT substr(code1, 1,7) as name From ERROR where code1='xxxxAXP'

NAME
-------
xxxxAXP
xxxxAXP

那就完美了。我不能使用下面的查询,因为每个代码的长度可能不同,硬编码为7是不好的。有没有通用的方法来实现这一点?谢谢您。

zphenhs4

zphenhs41#

在sql*plus中显示的列长度为50个字符。
但是,列的长度真的是这样吗?这将导致您声称的错误:

SELECT substr(code1, 1,length(code1)) as name From ERROR where code1='xxxxAXP'

结果是什么

SELECT LENGTH(substr(code1, 1,length(code1))) as name From ERROR where code1='xxxxAXP'
       ------                               -

因为,如果sql*plus困扰您,请使用

col name format a5

斯科特模式演示:

SQL> desc emp
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 EMPNO                                     NOT NULL NUMBER(4)
 ENAME                                              VARCHAR2(10)
 JOB                                                VARCHAR2(9)
 MGR                                                NUMBER(4)
 HIREDATE                                           DATE
 SAL                                                NUMBER(7,2)
 COMM                                               NUMBER(7,2)
 DEPTNO                                             NUMBER(2)

SQL> select substr(ename, 1, length(ename)) as name from emp where rownum = 1;

NAME
----------
SMITH

SQL> select substr(ename, 1, 5) as name from emp where rownum = 1;

NAME
-----
SMITH

SQL> col name format a5
SQL> select substr(ename, 1, length(ename)) as name from emp where rownum = 1;

NAME
-----
SMITH

SQL>
mgdq6dx1

mgdq6dx12#

简单的逻辑为什么sqlplus在 length() 和7的大小,如果是常数7英寸 substr :
sql
plus不知道在 length() 所以它显示了50个字符,空格等于列的实际大小。
如果是7英寸 substr ,它知道每个结果的长度为7个字符或更小,因此它只显示7个字符的大小。

u0sqgete

u0sqgete3#

sqlplus分析游标的列定义,游标是在解析时生成的,而不是在运行时生成的。所以它不知道你真的只有7个字符。sqlcl还分析输出,因此请改用sqlcl。
oracle返回列定义,而不是sql*plus:

create table ERROR(
  DPDATE_TIME DATE,
  ERR_MSG     VARCHAR2(132),
  CODE1       VARCHAR2(50 byte)
);
insert into error(code1) values('xxxxAXP');
commit
/
Declare
     SQL_stmt  varchar2(2000) := 'select substr(code1, 1,length(code1)) as name from error';
     ColCount  number:=0;
     DestTab   dbms_sql.desc_tab;
     CursorId  integer;
begin
   CursorId:= dbms_sql.open_cursor;
   dbms_sql.parse(CursorId,SQL_stmt,dbms_sql.native);
   dbms_sql.describe_columns(CursorId,ColCount,DestTab);

   for i in 1 .. ColCount loop
    dbms_output.put_line('ColumnType:    ' || DestTab(i).col_type);
    dbms_output.put_line('Maximum Length: ' || DestTab(i).col_max_len);
    dbms_output.put_line('ColumnName:    ' || DestTab(i).col_name);
    dbms_output.put_line('Name Length:   ' || DestTab(i).col_name_len);
    dbms_output.put_line('Scale:         ' || DestTab(i).col_scale);
    dbms_output.put_line('Precision:     ' || DestTab(i).col_precision);
    dbms_output.put_line('Charsetid:     ' || DestTab(i).col_Charsetid);
    dbms_output.put_line('Charset Form:  ' || DestTab(i).col_charsetform);
    if (DestTab(i).col_null_ok) then
       dbms_output.put_line('IsNull:Y');
    else
       dbms_output.put_line('IsNull:N');
    end if;
    dbms_output.new_line;
   end loop;
   dbms_sql.close_cursor(CursorId);
   exception
   when others then dbms_sql.close_cursor(CursorId);
     raise;
end;
/

相关问题