我在oracle中有一个表,如下所示:
name | type | nullable
------------------------------------------
person_name | varchar(20) | yes
weight_coeficient | number | yes
...
如何判断 weight_coeficient 的值有多少位数?例如:
3.0123456789
有11个数字(precision = 11)和十进制后的10位数(scale = 10)
是否有任何sql命令/函数可以执行此操作,例如GetPrecision( select.. )
返回11?
另请注意,表的定义未指定比例和精度。据我所知,所有数字都应用了最大精度。所以我不想找出定义的精度(= 48),而是表中特定值的精度。这可能只是使用oracle命令吗?
提前谢谢你,JP
答案 0 :(得分:5)
怎么样......
SELECT LENGTH(TRANSLATE(TO_CHAR(3.0123456789),'1234567890.-','1234567890'))
FROM dual
翻译只会删除非数字字符.-
答案 1 :(得分:0)
使用时略有改进:
length(to_char(:number)) - coalesce(length(translate(to_char(:number), 'x1234567890', 'x')), 0)
当to_char为指数或不同的分组字符或小数分隔符插入“E”时,它仍然有效。
答案 2 :(得分:0)
使用此脚本为您的数据生成适当的强制转换。我写这篇文章是为了帮助移动NUMBER数据,其中包含未指定的精度和数据。通过Kafka-Connect在Oracle中扩展到Postgres。 Kafka-Connect允许一个选择数据通过查询复制到另一个数据库,但由于我们没有在Oracle端设置我们的数字精度,Kafka-Connect将所有内容插入Postgres作为一个大小数。即,Oracle 1将被插入为1.000000000< 30 decimals>。
SET SERVEROUTPUT ON;
DECLARE
Q1 VARCHAR2 (4000 CHAR);
str VARCHAR2 (300 CHAR);
BEGIN
FOR rec
IN (SELECT column_name AS column_name
FROM all_tab_cols
WHERE owner = 'YOUR_SCHEMA'
AND TABLE_NAME = 'YOUR_TABLE'
AND DATA_TYPE = 'NUMBER')
LOOP
q1 :=
'SELECT REPLACE(''cast( ''
|| :1
|| '' as NUMBER(''
|| TO_CHAR (MAX (LENGTH_OF_DECIMAL) + MAX (length_of_integer))
|| '',''
|| TO_CHAR (MAX (length_of_decimal))
|| ''))'',''NUMBER(0,0)'',''NUMBER'') as result
FROM (SELECT charnum,
CASE
WHEN INSTR (charnum, ''.'') > 0
THEN
SUBSTR (charnum, INSTR (charnum, ''.'') + 1)
ELSE
NULL
END
AS decimal_part,
CASE
WHEN INSTR (charnum, ''.'') > 0
THEN
REPLACE (
REPLACE (
SUBSTR (charnum,
1,
INSTR (charnum, ''.'') - 1),
''-'',
''''),
''+'',
'''')
ELSE
REPLACE (REPLACE (charnum, ''-'', ''''), ''+'', '''')
END
AS integer_part,
CASE
WHEN INSTR (charnum, ''.'') > 0
THEN
LENGTH (
SUBSTR (charnum, INSTR (charnum, ''.'') + 1))
ELSE
0
END
AS length_of_decimal,
CASE
WHEN INSTR (charnum, ''.'') > 0
THEN
NVL (
LENGTH (
REPLACE (
REPLACE (
SUBSTR (charnum,
1,
INSTR (charnum, ''.'') - 1),
''-'',
''''),
''+'',
'''')),
0)
ELSE
NVL (
LENGTH (
REPLACE (REPLACE (charnum, ''-'', ''''),
''+'',
'''')),
0)
END
AS length_of_integer
FROM (SELECT cast(col_name2 AS VARCHAR2 (50))
AS charnum
FROM YOUR_TABLE)) T1';
q1 := REPLACE (q1, 'col_name2', rec.column_name);
EXECUTE IMMEDIATE REPLACE (q1, 'col_name2', rec.column_name)
INTO str
USING rec.column_name;
DBMS_OUTPUT.PUT_LINE (str);
END LOOP;
END;
/
测试用例:
create table precision_tester(test_val number);
- 将YOUR_TABLE更改为PRECISION_TESTER
(运行脚本,验证输出,并在每次测试后从precision_tester中删除)
insert into precision_tester(test_val) values (null);
insert into precision_tester(test_val) values (+1);
insert into precision_tester(test_val) values (-1);
insert into precision_tester(test_val) values (-1.00);
insert into precision_tester(test_val) values (+1.001);
insert into precision_tester(test_val) values (+12.001);
产生以下dbms输出:
cast( TEST_VAL as NUMBER)
cast( TEST_VAL as NUMBER(1,0))
cast( TEST_VAL as NUMBER(1,0))
cast( TEST_VAL as NUMBER(1,0))
cast( TEST_VAL as NUMBER(4,3))
cast( TEST_VAL as NUMBER(5,3))