我想做这样的事情:
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)
当我尝试同时执行这两项操作时,我认为它以 double 的形式得到,就好像强制转换什么也没做一样。正确的语法是什么?为什么我的语法不能正常工作?
最佳答案
评论太长:
Oracle 设置:
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 )
的输出生成完全相同的转储值。
但是,data type 2
用于 NUMBER(p,s)
和 FLOAT(p)
列,而 DUMP()
则不使用告诉您列的比例和精度是多少(您必须从转储的值中推断出来)。
如果你想找到它,那么你需要使用 DBMS_SQL
package :
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
(即 NUMBER(p,s)
或 FLOAT(p)
类型)并且具有精度38
和 0
的小数位数 - 正是整数所期望的。
关于sql - Oracle sql 中的 NVL 与 CAST?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37853153/