2

我想做类似的事情:

select 
   cast(nvl(col1, col2) as Integer) col_name
from table1;

cast(col1 as Integer) col_name works (returns as Integer)
nvl(col1, col2) col_name works (returns as Double)

当我尝试两者都做时,我以双重的形式得到它,我想,好像 cast 什么也没做。什么是正确的语法,为什么我的不能正常工作?

4

2 回答 2

2

评论太长了:

甲骨文设置

CREATE TABLE table_name (
  col1 NUMBER(5,2),
  col2 NUMBER(3,0)
);

INSERT INTO table_name
SELECT 12,    12 FROM DUAL UNION ALL
SELECT 12.01, 12 FROM DUAL UNION ALL
SELECT NULL,  12 FROM DUAL;

获取 SQL 输出列的数据类型

现在您可以使用DUMP()

SELECT col1,
       col2,
       DUMP(col1) as d1,
       DUMP(col2) as d2,
       DUMP( CAST( NVL( col1, col2 ) AS Integer ) ) AS d3
FROM   table_name

这将给出输出:

COL1  COL2 D1                    D2                  D3
----- ---- --------------------- ------------------- -------------------
   12   12 Typ=2 Len=2: 193,13   Typ=2 Len=2: 193,13 Typ=2 Len=2: 193,13
12.01   12 Typ=2 Len=3: 193,13,2 Typ=2 Len=2: 193,13 Typ=2 Len=2: 193,13
        12                       Typ=2 Len=2: 193,13 Typ=2 Len=2: 193,13

如您所见,CAST( NVL( col1, col2 ) AS Integer )生成完全相同的转储值的输出。

但是,数据类型 2用于NUMBER(p,s)FLOAT(p)列,DUMP()并不会告诉您列的比例和精度是什么(您必须从转储值中推断出来)。

如果你想找到它,那么你需要使用这个DBMS_SQL

DECLARE
  c NUMBER := DBMS_SQL.OPEN_CURSOR;
  d NUMBER;
  n INTEGER;
  rec_tab DBMS_SQL.DESC_TAB;
BEGIN
  DBMS_SQL.PARSE(
    c,
    'SELECT CAST( NVL( col1, col2 ) AS Integer ) FROM table_name',
    DBMS_SQL.NATIVE
  );
  d := DBMS_SQL.EXECUTE(c);
  DBMS_SQL.DESCRIBE_COLUMNS(c,n,rec_tab);
  FOR i IN 1 .. n LOOP
    DBMS_OUTPUT.PUT_LINE(
      rec_tab(i).col_name || ': '
      || rec_tab(i).col_type || ' ('
      || rec_tab(i).col_precision || ', '
      || rec_tab(i).col_scale || ')'
    );
  END LOOP;
  DBMS_SQL.CLOSE_CURSOR(c);
END;
/

哪个输出:

CAST(NVL(COL1,COL2)ASINTEGER): 2 (38, 0)

所以输出是类型2(即 aNUMBER(p,s)FLOAT(p)类型)并且具有精度38和比例0- 正是整数所期望的。

于 2016-06-16T09:59:49.400 回答
1

这是一个测试用例,它明确表明 cast(nvl(col1,col2) as integer) 的输出与整数列的类型完全相同:

create table test1 (col1 binary_double, col2 binary_double, col3 integer);

insert into test1 values (1, 2, 3);
insert into test1 values (null, 3, 4);
insert into test1 values (null, null, 5);

commit;

select col1,
       col2,
       col3,
       nvl(col1, col2) nvl_col1_col2,
       cast(nvl(col1, col2) as integer) cast_nvl_col1_col2,
       dump(col1) dump_col1,
       dump(col2) dump_col2,
       dump(col3) dump_col3,
       dump(nvl(col1, col2)) dump_nvl_col1_col2,
       dump(cast(nvl(col1, col2) as integer)) dump_cast_nvl_col1_col2
from   test1;


      COL1       COL2       COL3 NVL_COL1_COL2 CAST_NVL_COL1_COL2 DUMP_COL1                           DUMP_COL2                           DUMP_COL3            DUMP_NVL_COL1_COL2                  DUMP_CAST_NVL_COL1_C
---------- ---------- ---------- ------------- ------------------ ----------------------------------- ----------------------------------- -------------------- ----------------------------------- --------------------
         1          2          3             1                  1 Typ=101 Len=8: 191,240,0,0,0,0,0,0  Typ=101 Len=8: 192,0,0,0,0,0,0,0    Typ=2 Len=2: 193,4   Typ=101 Len=8: 191,240,0,0,0,0,0,0  Typ=2 Len=2: 193,2  
                    3          4             3                  3 NULL                                Typ=101 Len=8: 192,8,0,0,0,0,0,0    Typ=2 Len=2: 193,5   Typ=101 Len=8: 192,8,0,0,0,0,0,0    Typ=2 Len=2: 193,4  
                               5                                  NULL                                NULL                                Typ=2 Len=2: 193,6   NULL                                NULL                
于 2016-06-16T08:40:42.130 回答