2016-01-16 2 views
0

Я новичок в Oracle SQL и PL sql.i имеют записи пл функцию SQL, которая принимает данные из PHP в XML format.Here это код PL SQL ниже, и она отлично работает:почему столбец таблицы оракула принимает данные больше, чем начальный размер?

FUNCTION save_overtime(overtime_data NVARCHAR2) RETURN clob IS ret clob; 
    xmlData XMLType; 

    v_code NUMBER; 
    v_errm VARCHAR2(100); 

    BEGIN 
    xmlData:=XMLType(overtime_data); 
    INSERT INTO TBL_OVERTIME SELECT x.* FROM XMLTABLE('/overtime' 
               PASSING xmlData 
               COLUMNS OT_EMPID NVARCHAR2(10)  PATH 'employee_id', 
                 OT_DATE DATE  PATH 'date',               
                 OT_HOUR NUMBER(4,0) PATH 'overtime_hour'               
                 ) x; 


    ret:=to_char(sql%rowcount); 
COMMIT; 

RETURN '<result><status affectedRow='||ret||'>success</status></result>'; 
EXCEPTION 
WHEN OTHERS THEN 
v_code := SQLCODE; 
v_errm := SUBSTR(SQLERRM, 1, 100); 
DBMS_OUTPUT.PUT_LINE (v_code || ' ' || v_errm); 
-- '<result><status>Error</status> <error_message>'|| 'Error Code:' || v_code || ' ' || 'Error Message:' || v_errm ||'</error_message> </result>'; 
RETURN '<result><status>Error</status> <error_message>'|| 'Error Message:' || v_errm ||'</error_message> </result>'; 

END save_overtime; 

При вставке данных, Я заметил, что таблица оракула также принимает данные, которые больше, чем их первоначальный размер! Например, следующие колонки приема данных, которые больше, чем размер 10.

EMPID NVARCHAR2(10) 

если данные 12 в длину, то он занимает 1-ые 10 chars.But мне, я думаю, это должно быть инвалидом/error.Because, в противном случае определение размера столбца бессмысленно. Я знаю о добавлении ограничений. Но добавление многих ограничений для таких мелочей очень скучно и утомительно. Если я сделал какие-либо ошибки/ошибки, то, пожалуйста, помогите мне понять это. Спасибо

ответ

3

Вставка не разрешает и молча усекает значения дольше, чем размер столбца. Предложение XMLTable columns выполняет усечение; тип данных для этого говорит о том, что будет возвращено проекцией XMLTable и не означает, что значение по указанному пути будет проверено против ограничения размера типа данных. Добавление ограничения к таблице не имеет значения.

Вы можете увидеть усечение, если вы просто запрос из XMLTable выражения, а не вставлять:

var overtime_data nvarchar2(4000); 
exec :overtime_data := '<overtime><employee_id>invalidvalue</employee_id><date>2016-01-15</date><overtime_hour>1234.5</overtime_hour></overtime>'; 

select x.ot_empid, x.ot_date, x.ot_hour 
from xmltable('/overtime' 
    passing xmltype(:overtime_data) 
    columns ot_empid nvarchar2(10) path 'employee_id', 
    ot_date date path 'date', 
    ot_hour number(4,0) path 'overtime_hour' 
) x; 

OT_EMPID OT_DATE  OT_HOUR 
---------- --------- ---------- 
invalidval 15-JAN-16  1235 

Значение 12 символов из элемента XML усекается оговоркой columns. Также обратите внимание, что количество часов округлено, чтобы вписаться в тип ограниченного числа - 1234,5 округляется до 1235. (Пока значение может быть преобразовано в указанную точность, оно не будет жаловаться. По сути, это означает, что до тех пор, пока не имеют более четырех цифр до десятичной точки, округленные, если у вас есть пять или более цифр до десятичной точки, он получит ORA-01438.)

Если вы попытаетесь вставить эти значения, это не будет «т жаловаться, так как они действительны для определения таблицы:

insert into tbl_overtime (ot_empid, ot_date, ot_hour) 
select x.ot_empid, x.ot_date, x.ot_hour 
from xmltable('/overtime' 
    passing xmltype(:overtime_data) 
    columns ot_empid nvarchar2(10) path 'employee_id', 
    ot_date date path 'date', 
    ot_hour number(4,0) path 'overtime_hour' 
) x; 

1 row inserted. 

Если вы не собираетесь проверять или манипулировать значением, прежде чем она установлена, и вы хотите, чтобы это ошибка, если значения XML узел больше чем 10 символов, тогда что приведет к тому, что тип данных столбца XMLTable будет содержать даже один символ. (Если вы собираетесь проверить ценность, то вы можете сделать ее намного больше, но здесь будет больше 10).

INSERT INTO TBL_OVERTIME SELECT x.* FROM XMLTABLE('/overtime' 
               PASSING xmlData 
               COLUMNS OT_EMPID NVARCHAR2(11)  PATH 'employee_id', 
                 OT_DATE DATE  PATH 'date',   
                 OT_HOUR NUMBER(4,0) PATH 'overtime_hour'               
                 ) x; 

, если значение от пути больше, чем 10 символов, значение x.ot_empid будет обрезано до 11 символов, и вставка будет затем терпит неудачу, потому что слишком велико для реального столбца таблицы.

Для демонстрации с теми же данными, что и раньше;

select x.ot_empid, x.ot_date, x.ot_hour 
from xmltable('/overtime' 
    passing xmltype(:overtime_data) 
    columns ot_empid nvarchar2(11) path 'employee_id', 
    ot_date date path 'date', 
    ot_hour number(4,0) path 'overtime_hour' 
) x; 

OT_EMPID OT_DATE  OT_HOUR 
----------- --------- ---------- 
invalidvalu 15-JAN-16  1235 

Отметьте, что столбец ot_empid имеет 11 символов. И вставка в настоящее время не удается:

insert into tbl_overtime (ot_empid, ot_date, ot_hour) 
select x.ot_empid, x.ot_date, x.ot_hour 
from xmltable('/overtime' 
    passing xmltype(:overtime_data) 
    columns ot_empid nvarchar2(11) path 'employee_id', 
    ot_date date path 'date', 
    ot_hour number(4,0) path 'overtime_hour'               
) x; 

Error report - 
SQL Error: ORA-12899: value too large for column "SCHEMA"."TBL_OVERTIME"."OT_EMPID" (actual: 11, maximum: 10) 
+0

Благодаря @Alex Poole ваше объяснение очищает мне понятие о it.Your трюк очень хорошо, и это worked.However я замечаю, что XML правильно следующее ограничение на размер типа NUMBER (4,0). Проблема заключается в типе NVARCHAR2.Что вы скажете, почему таблица xml корректно соответствует лимиту размера типа NUMBER (4,0). Спасибо. – user5005768

+1

@ user5005768 - ошибка с ORA-01438, если вы превысите указанную точность номера, например. если элементы XML содержат 10000, даже если у вас есть выбор без вставки. Это не будет ошибкой, если у вас есть значение как 9999.999 по мере совпадения точности, и значимые цифры за пределами указанного масштаба будут округлены. [Подробнее о масштабе и точности] (http://docs.oracle.com/cd/E11882_01/server.112/e41084/sql_elements001.htm#sthref118). –

+0

Большое спасибо @Alex Poole.Можно также посетить мой другой пост в oracle xml http://stackoverflow.com/questions/34855163/how-to-deal-with-sequence-in-oracle-xmltable – user5005768

Смежные вопросы