Используйте этот скрипт, чтобы сгенерировать соответствующие приведения для ваших данных.Я написал это, чтобы помочь перемещать данные NUMBER с неопределенной точностью и масштабированием в Oracle в Postgres через Kafka-Connect.Kafka-Connect позволяет выбирать данные для копирования в другую базу данных с помощью запроса, но, поскольку у нас не была установлена точность чисел на стороне Oracle, Kafka-Connect вставлял все в Postgres как большое десятичное число.То есть Oracle 1 будет вставлен как 1.000000000 <30 десятичных знаков>.
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);
Выводит следующие выходные данные в дБмс:
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))