2014-12-15 5 views
2

Как получить длину Max и Min, разрешенную в столбце varchar2. Мне нужно проверить входящие данные из таблицы temp, которая поступает с какого-то удаленного db. И каждое значение строки должно быть проверено для определенных столбцов, которое имеет максимальное или минимальное значение, которое может быть установлено в столбце.Получить максимальную длину в столбце | Oracle

Так что я должен был получить спецификации столбцов, используя детали схемы. Я сделал сделать proc для этого:

PROCEDURE CHK_COL_LEN(VAL IN VARCHAR2,    
         MAX_LEN IN NUMBER :=4000, 
         MIN_LEN IN NUMBER :=0, 
         LEN_OUT OUT VARCHAR2) 
     IS 
      BEGIN 
       IF LENGTH(VAL)<MIN_LEN THEN 
        LEN_OUT := 'ERROR'; 
        RETURN; 
       ELSIF LENGTH(VAL)>MAX_LEN THEN 
        LEN_OUT := 'ERROR'; 
        RETURN; 
       ELSE 
        LEN_OUT := 'SUCCESS'; 
        RETURN; 
       END IF; 
      END; 
END CHK_COL_LEN; 

Но проблема в том, что нельзя использовать повторно и немного жёстко. Я должен явно отправлять значения MAX и MIN для каждого значения вместе с проверяемыми данными.

Так на proc вызова, это что-то вроде:

CHK_COL_LEN(EMP_CURSOR.EMP_ID, 5, 1, LEN_ERROR_MSG); 

вместо этого я хочу что-то вроде: (! Если что-то вроде этого существуют)

CHK_COL_LEN(EMP_CURSOR.EMP_ID, 
       EMP.COLUMN_NAME%MAX_LENGTH, 
       EMP.COLUMN_NAME%MIN_LENGTH, 
       LEN_ERROR_MSG) 

Спасибо заранее.

EDIT

select max(length(col)) from table; 

Это решение, но опять-таки мне придется выполнить этот запрос каждый раз, чтобы задать две переменные для MAX и MIN значения. И выполнение дополнительных двух запросов для каждого значения, а затем установка 2 переменных будет стоить значительного снижения производительности при наличии около 32 таблиц, каждая из которых имеет 5-8 столбцов varchar2 и средние строки около 40k-50k в каждой таблице.

+1

Но max (length (col)) даст вам максимальную существующую длину, это не обязательно MAX_LENGTH вашей колонки. Я думаю, что @ road242 прав, единственный способ получить размер столбца - использовать словарь. – Aramillo

+1

Почему вы пытаетесь написать валидацию с использованием словаря данных вместо того, чтобы позволить определению таблицы сделать валидацию для вас? – Allan

+0

Потому что я хочу поймать это перед рукой. Как только исключение будет выброшено (даже если оно будет обработано вручную), он затем пропустит операции, запланированные позже (возьмите сценарий, когда произойдут только несколько циклов цикла, а затем выброшенные исключения), тогда цикл заканчивается при первом возникновении исключения. – Sachin

ответ

3

Вы может запросить таблицу «user_tab_columns таблица» для получения информации о метаданных конкретной таблицы:

SELECT 
    COLUMN_NAME, DATA_LENGTH, DATA_PRECISION 
FROM 
    user_tab_columns 
WHERE 
    t.table_name IN ('<YOURTABLE>'); 

с этой информацией вы можете запросить метаданные непосредственно в хранимой процедуре:

... 
SELECT 
    CHAR_LENGTH INTO max_length 
FROM 
    user_tab_columns 
WHERE 
    table_name = '<YOURTABLE>' AND COLUMN_NAME = '<YOURCOLUMN>'; 

... 

Exmple процедура получения максимальная длина таблицы/колонки:

create or replace PROCEDURE GET_MAX_LENGTH_OF_COLUMN( 
         tableName IN VARCHAR2, 
         columnName IN VARCHAR2, 
         MAX_LENGTH OUT VARCHAR2) 
     IS 
      BEGIN 

      SELECT CHAR_LENGTH INTO MAX_LENGTH 
      FROM user_tab_columns 
      WHERE table_name = tableName AND COLUMN_NAME = columnName;    

END GET_MAX_LENGTH_OF_COLUMN; 
+0

Да, с этим я могу получить, конечно. Но это не так много, как и для каждого столбца, мне придется написать такой большой код и получить значение для установки в переменную, а затем передать переменную в proc. Также я не могу написать TABLE NAME в proc, coz proc reuable и использовал мои около 32 таблиц. Таким образом, была создана общая процедура для всех таблиц. – Sachin

+0

Почему? вы можете использовать имя таблицы + имя столбца в качестве входного параметра, поэтому вам придется писать эту процедуру только один раз. – road242

+0

Вы правы, но, к сожалению, в Oracle имя таблицы не может быть динамическим. Ни одно имя схемы не может быть динамическим в Oracle и должно быть жестко запрограммировано. Ограничение оракула. – Sachin

0

Если список таблиц не так много вы можете указать минимальное значение не используя CHECK Constraint на столе.

Любой DML в таблице автоматически завершится ошибкой, если он превышает длину, назначенную этому столбцу.

CREATE TABLE suppliers 
(
supplier_id numeric(4), 
supplier_name varchar2(50), 
CONSTRAINT check_supplier_id 
CHECK (length(supplier_name) > 5) 
); 
+0

Да, но проверка должна быть выполнена до DML. Вот почему изначально данные хранятся в таблице Temp, а затем после проверки выполнения DML. Результат должен быть пойман за любым исключением! Потому что для клиента исключение должно быть инициировано по очень серьезным вопросам, а не по типу. – Sachin

+0

Как создается курсор EMP_CURSOR.EMP_ID – psaraj12

1

Попробуйте создать свой порядок, как это:

create or replace procedure Checking_size(column_name varchar2,columnvalue varchar2,state out varchar2) is 

begin 
execute immediate 'declare 
z '||column_name||'%type; 
begin 
z:=:param2; 
end;' using columnvalue; 

state:='OK'; 
exception when value_error then 
state:='NOT OK'; 

end; 

Как вы можете видеть, я имитировать назначение ошибки. Если длина columnvalue больше, чем столбец i, который проходит как column_name, он выдает исключение value_error и возвращает NOT OK, else возвращает OK. Например, если your_table.your_column обратитесь к столбцу с длиной (3), то верните NOT OK.

declare 
state varchar2(10); 
begin 

Checking_size('your_table.your_column','12345',state); 
dbms_output.put_line(state); 
end;