Guest User

Untitled

a guest
Jan 23rd, 2018
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. CREATE OR REPLACE PROCEDURE myproc(table_name_in IN VARCHAR2 , per_in IN v ) IS
  2.  
  3. var1 VARCHAR2 (500 CHAR) ;
  4. var2 VARCHAR2 (500 CHAR) ;
  5. var3 VARCHAR2 (500 CHAR) ;
  6. var4 NUMBER (4);
  7. var5 VARCHAR2 (500 CHAR) := '' ;
  8. var6 VARCHAR2 (400 CHAR) := '' ; --для формирования динамического insert
  9. var7 VARCHAR2 (500 CHAR) := ''; --туда пихаю  data_scale (для NUMBER)
  10. var8 NUMBER (10);
  11. var9 VARCHAR (500 CHAR) := '';  --туда пихаю data_precision (ДЛя NUMBER)
  12. var10 NUMBER (10);
  13. var11 NUMBER (10);
  14. var12 VARCHAR2 (500);
  15. var13 VARCHAR2 (500) := '';
  16. var14 VARCHAR2 (500);
  17. var15 VARCHAR2 (500);
  18. var16 VARCHAR2 (500) := '';
  19. var17 VARCHAR2 (500) := '';
  20. var18 VARCHAR2 (500) := '';
  21.  
  22. CURSOR cur1 IS SELECT  (ROWNUM) "No." , (all_col_comments.COLUMN_NAME ) "Имя столбца",  ALL_TAB_COLUMNS.DATA_TYPE , ALL_TAB_COLUMNS.NULLABLE, all_col_comments.CoMMENTS , ALL_TAB_COLUMNS.DATA_SCALE, ALL_TAB_COLUMNS.DATA_LENGTH, ALL_TAB_COLUMNS.DATA_PRECISION, ALL_TAB_COLUMNS.CHAR_LENGTH, ALL_TAB_COLUMNS.COLUMN_NAME
  23. FROM  all_col_comments
  24. LEFT JOIN  ALL_TAB_COLUMNS ON all_col_comments.TABLE_NAME = ALL_TAB_COLUMNS.TABLE_NAME  AND all_col_comments.COLUMN_NAME = ALL_TAB_COLUMNS.COLUMN_NAME
  25. WHERE all_col_comments.TABLE_NAME LIKE UPPER(table_name_in)  AND ALL_TAB_COLUMNS.TABLE_NAME LIKE UPPER(table_name_in)
  26. ;
  27.  
  28. ERR_NUMBER EXCEPTION;
  29. PRAGMA EXCEPTION_INIT(ERR_NUMBER, -6502); --PRAGMA EXCEPTION_INIT для связи ошибки и объявяемого исключения
  30.  
  31. ERR_DATE EXCEPTION;
  32. PRAGMA EXCEPTION_INIT(ERR_DATE, -01830);
  33.  
  34. ERR_DATE_FORMAT EXCEPTION;
  35. PRAGMA EXCEPTION_INIT(ERR_DATE_FORMAT, -01840);
  36.  
  37. ERR_DATE_FORMAT1 EXCEPTION;
  38. PRAGMA EXCEPTION_INIT(ERR_DATE_FORMAT1, -01847);
  39.  
  40. ERR_DATE_FORMAT2 EXCEPTION;
  41. PRAGMA EXCEPTION_INIT(ERR_DATE_FORMAT2, -01858);
  42.  
  43. ERR_DATE_FORMAT3 EXCEPTION; -- not a valid month
  44. PRAGMA EXCEPTION_INIT(ERR_DATE_FORMAT3, -01843);
  45.  
  46. ERR_CHECK EXCEPTION; -- check constraint violated
  47. PRAGMA EXCEPTION_INIT(ERR_CHECK, -02290);
  48.  
  49.  
  50.  
  51. ERR_UNIQUE EXCEPTION;
  52. PRAGMA EXCEPTION_INIT(ERR_UNIQUE, -00001);
  53. PER_MENISHE EXCEPTION; -- когда пеерменных меньше чем стоблцов таблицы
  54.  
  55.  
  56.  
  57. i NUMBER(4) := 0 ;
  58. m NUMBER(4) := 0 ;
  59. s BOOLEAN := TRUE; --для решения вставка или нет массива в таблицу
  60.  
  61. BEGIN
  62.  
  63. --проверка количевства соответствия столбцов и элементов массива
  64. SELECT COUNT(COLUMN_NAME) INTO var4 FROM  ALL_TAB_COLUMNS WHERE TABLE_NAME LIKE UPPER(table_name_in ); --заносим в var4 количество столбцов таблицы
  65. IF  ( per_in.COUNT > var4 ) THEN
  66.   m := per_in.COUNT - var4;
  67.   dbms_output.put_line('Значений переменных в массиве больше, чем столбцов таблицы на '||m);
  68.   ELSE
  69.   IF ( per_in.COUNT < var4 ) THEN
  70.    m := var4 - per_in.COUNT;
  71.   dbms_output.put_line('===================================================================================================');
  72.   dbms_output.put_line('Значений переменных в массиве меньше, чем столбцов таблицы на '||m||' поэтому резульат вывода некорректен');
  73.   dbms_output.put_line('===================================================================================================');
  74.  
  75.   RAISE PER_MENISHE; -- переход на этот эксепшн
  76.   ELSE
  77.     dbms_output.put_line ('    ');
  78.     END IF;
  79. END IF;
  80.  
  81.  
  82.  
  83.  
  84.  
  85.  
  86.  
  87.  
  88.  DBMS_OUTPUT.ENABLE;
  89.  dbms_output.put_line('===================================================================================================');
  90.  dbms_output.put_line('  No         Column name                      Attributes    ');
  91.  dbms_output.put_line(' ------     ---------------  ----------------------------------------------------------------------');
  92.  
  93. FOR index_cicla1 IN cur1 LOOP
  94. -- проверка условия на Number (NUMBER[(precision,scale)])
  95. IF (index_cicla1.DATA_TYPE = 'NUMBER') THEN
  96.   BEGIN
  97.   var1 :='';
  98.   var1 := RPAD(index_cicla1."No.", 15, ' ');
  99.   var1 := var1||RPAD(index_cicla1."Имя столбца", 25, ' ');
  100.   IF (index_cicla1.DATA_SCALE = '0') THEN -- проверка на значения после запятой (SCALE)
  101.   var1 := var1||'Type: '|| index_cicla1.DATA_TYPE || '(' || index_cicla1.DATA_PRECISION||')';
  102.   ELSE
  103.   var1 := var1||'Type: '|| index_cicla1.DATA_TYPE || '(' || index_cicla1.DATA_PRECISION||','||index_cicla1.DATA_SCALE||')';
  104.   END IF;
  105.  
  106.   IF (index_cicla1.NULLABLE = 'N') THEN --if на NOT_NULL
  107.   var1 :=var1|| ' NOT NULL';
  108.  
  109.   ELSE
  110.   var1 :=var1;
  111.   END IF;
  112.  
  113.  
  114.   IF (index_cicla1.COMMENTS IS NOT NULL) THEN -- проверка условия на наличие comments
  115.     var1 := var1||'
  116.    '||RPAD(' ', 36, ' ') ||'Comment: '||'"'||index_cicla1.COMMENTS||'"';
  117.   ELSE
  118.     var1 := var1;
  119.    END IF;
  120.  
  121.   Dbms_output.put_line(TO_CHAR(var1)); --вывод строк Number
  122.   END;
  123.  
  124. ELSIF (index_cicla1.data_type IN ('VARCHAR2','CHAR','VARCHAR')) THEN    -- проверка условия на VARCHAR2 и CHAR
  125.        BEGIN
  126.       var2 :='';
  127.       var2 := var2|| RPAD(index_cicla1."No.", 15, ' ');
  128.       var2 := var2|| RPAD(index_cicla1."Имя столбца", 25, ' ');
  129.     IF  (index_cicla1.NULLABLE = 'N') THEN --if на NOT_NULL
  130.      var2 :=var2 ||'Type: '|| index_cicla1.DATA_TYPE||'('|| index_cicla1.CHAR_LENGTH||') NOT NULL';
  131.     ELSE
  132.       var2 :=var2 ||'Type: '|| index_cicla1.DATA_TYPE||'('|| index_cicla1.CHAR_LENGTH||')';
  133.     END IF;
  134.    
  135.       IF (index_cicla1.COMMENTS IS NOT NULL) THEN -- проверка условия на наличие comments
  136.     var2 := var2||'
  137.     '||RPAD(' ', 34, ' ') ||' Comment: '||'"'||index_cicla1.COMMENTS||'"';
  138.   ELSE
  139.     var2 := var2;
  140.    END IF;
  141.         Dbms_output.put_line(TO_CHAR(var2)); --вывод значений varchar2
  142.         END;
  143. ELSIF (index_cicla1.data_type = 'DATE') THEN --проверка условия на DATE
  144.        BEGIN
  145.         var3:='';
  146.         var3 := var3|| RPAD(index_cicla1."No.", 15, ' ');
  147.         var3 := var3|| RPAD(index_cicla1."Имя столбца", 25, ' ');
  148.              IF  (index_cicla1.NULLABLE = 'N') THEN --if на NOT_NULL
  149.              var3 :=var3 ||'Type: '|| index_cicla1.DATA_TYPE||' NOT NULL';
  150.              ELSE
  151.              var3 :=var3 ||'Type: '|| index_cicla1.DATA_TYPE;
  152.              END IF;
  153.      
  154.         IF (index_cicla1.COMMENTS IS NOT NULL) THEN -- проверка условия на наличие comments
  155.     var3 := var3||'
  156.     '||RPAD(' ', 35, ' ') ||'Comment: '||'"'||index_cicla1.COMMENTS||'"';
  157.   ELSE
  158.     var3 := var3;
  159.    END IF;
  160.  
  161.       Dbms_output.put_line(TO_CHAR(var3)); --вывод значений DATE
  162.       END;
  163.    
  164. END IF;
  165. -- контрэинт типа check!
  166. FOR constrcursor IN ( SELECT ALL_CONS_COLUMNS.CONSTRAINT_NAME, ALL_CONSTRAINTS.SEARCH_CONDITION, ALL_CONS_COLUMNS.COLUMN_NAME
  167. FROM ALL_CONSTRAINTS
  168. JOIN ALL_CONS_COLUMNS ON
  169. ALL_CONS_COLUMNS.CONSTRAINT_NAME = ALL_CONSTRAINTS.CONSTRAINT_NAME AND  index_cicla1.COLUMN_NAME = ALL_CONS_COLUMNS.COLUMN_NAME
  170. WHERE ALL_CONS_COLUMNS.TABLE_NAME LIKE UPPER(table_name_in) AND ALL_CONSTRAINTS.CONSTRAINT_TYPE LIKE 'C' )
  171.  
  172.   LOOP
  173.     IF ( TO_CHAR(constrcursor.SEARCH_CONDITION) = TO_CHAR('"'||index_cicla1.COLUMN_NAME||'" IS NOT NULL' ) ) THEN
  174.       var3 := var3;
  175.        
  176.    ELSE
  177.      var14 := '';
  178.     dbms_output.put_line(RPAD(' ', 40) || 'Constr  : "'|| constrcursor.constraint_name|| '" CHECK ('||constrcursor.SEARCH_CONDITION||')' );-- чтобы не выводило лишний check (is not null)
  179.       var14 := constrcursor.COLUMN_NAME;
  180.      
  181.        IF (var13 IS NULL) THEN
  182.       var13 := var14; --чтобы лишнних запятых не вставлял
  183.       ELSE
  184.         var13 := var13||','||var14;
  185.        END IF;
  186.        
  187.        IF ( var13 = var14||','||var14) THEN -- проверка чтобы если 2 констреинта типа check в одном поле, чтобы выводил не 2 раза подряд
  188.             var13 := var14;
  189.        ELSE
  190.          var13 := var13;
  191.          END IF;
  192.        -- в var13 будут через запятую писать констреинты типа check (но не те которые not null)
  193.          
  194.           END IF;
  195.   END LOOP;  
  196.  
  197. -- контрэинт типа UNIQUE
  198. FOR uniquecursor IN (SELECT ALL_CONS_COLUMNS.CONSTRAINT_NAME, ALL_CONSTRAINTS.CONSTRAINT_TYPE,ALL_CONS_COLUMNS.COLUMN_NAME
  199. FROM ALL_CONSTRAINTS
  200. JOIN ALL_CONS_COLUMNS ON
  201. ALL_CONS_COLUMNS.CONSTRAINT_NAME = ALL_CONSTRAINTS.CONSTRAINT_NAME AND  index_cicla1.COLUMN_NAME = ALL_CONS_COLUMNS.COLUMN_NAME AND ALL_CONS_COLUMNS.TABLE_NAME LIKE UPPER(table_name_in) AND ALL_CONSTRAINTS.CONSTRAINT_TYPE LIKE 'U')
  202. LOOP
  203.   dbms_output.put_line(RPAD(' ', 40) || 'UNIQUE ');
  204.  
  205.   var16 := uniquecursor.COLUMN_NAME;
  206.  
  207.   IF (var15 IS NULL) THEN
  208.       var15 := var16; --чтобы лишнних запятых не вставлял
  209.       ELSE
  210.         var15 := var15||','||var16;
  211.        END IF;
  212. END LOOP;
  213.  
  214. -- контрэинт типа PRIMARY KEY - первичный ключ - уникален(ИД и т.п.)
  215.  
  216. FOR uniquecursor IN (SELECT ALL_CONS_COLUMNS.CONSTRAINT_NAME, ALL_CONSTRAINTS.CONSTRAINT_TYPE,ALL_CONS_COLUMNS.COLUMN_NAME
  217. FROM ALL_CONSTRAINTS
  218. JOIN ALL_CONS_COLUMNS ON
  219. ALL_CONS_COLUMNS.CONSTRAINT_NAME = ALL_CONSTRAINTS.CONSTRAINT_NAME AND  index_cicla1.COLUMN_NAME = ALL_CONS_COLUMNS.COLUMN_NAME AND ALL_CONS_COLUMNS.TABLE_NAME LIKE UPPER(table_name_in) AND ALL_CONSTRAINTS.CONSTRAINT_TYPE LIKE 'P')
  220. LOOP
  221. dbms_output.put_line(RPAD(' ', 40) || 'PRIMARY KEY');
  222.  
  223. var17 := uniquecursor.COLUMN_NAME;
  224.  
  225.   IF (var17 IS NULL) THEN
  226.       var18 := var17; --чтобы лишнних запятых не вставлял
  227.       ELSE
  228.         var18 := var18||','||var17;
  229.        END IF;
  230. END LOOP;
  231.  
  232.  /* ЗАЩИТА:
  233.  CREATE OR REPLACE TYPE V IS VARRAY(4000) OF VARCHAR2(4000); -- тип VARRAY с именем 'V'
  234.  правильные значения у массива:
  235.  exec myproc('Н_ЛЮДИ',v('100500','ivanov','ivan','nikolaivich','pin1','inn','20.07.2003','м','olololo9','olo','SPb','20.07.2003','PIN','20.07.2003',''));
  236.  */
  237. BEGIN
  238.    i := i + 1;
  239.  
  240. IF( per_in(i) IS NULL AND index_cicla1.NULLABLE = 'N') THEN --проверка поля на NULL
  241.   DBMS_OUTPUT.put_line(RPAD(' ', 40)||per_in(i)||' НЕ ПОДХОДИТ Т.К. ЗНАчение этого поля не может быть NULL'); -- т.к. ЕСТЬ ограничения NOT NULL
  242.   s := FALSE ;
  243.  ELSE
  244.  
  245.    IF (index_cicla1.DATA_TYPE = 'NUMBER') THEN
  246.  
  247.  
  248.   var7 := LTRIM ( per_in(i) , '1||2||3||4||5||6||7||9||8||0'); -- удаляю слева все сиволы (остается что-то вроде ',11034')
  249.   var7 := LTRIM ( var7 , ','); --удаляю слева направо зяптую (остается '11034')
  250.   var8 := LENGTH(var7); --получаю длину символов для SCALE
  251.  
  252.  
  253.   IF ( var8 IS NULL) THEN
  254.    var11 :=  LENGTH (per_in(i)); --длина строки, которая без запятых
  255.   ELSE
  256.     var8:= var8;
  257.   END IF;
  258.  
  259.   IF ( var11 <= index_cicla1.Data_Precision ) THEN
  260.     DBMS_OUTPUT.put_line(RPAD(' ', 40)|| ''''|| TO_NUMBER(per_in(i))||''''|| ' ПОДХОДИТ'); --под Number
  261.     ELSE
  262.  
  263.    
  264.   var9 := RTRIM ( per_in(i) , '1||2||3||4||5||6||7||9||8||0');
  265.   var9 := RTRIM ( var9 , ',');
  266.   var10 := LENGTH(var9); --получаю длину символов для Data_Precision
  267.    
  268.         IF (index_cicla1.Data_Precision  >= var8 AND index_cicla1.DATA_SCALE >= var10 ) THEN
  269.                   DBMS_OUTPUT.put_line(RPAD(' ', 40)||''''|| TO_NUMBER(per_in(i))||''''|| ' ПОДХОДИТ'); --под Number
  270.         ELSE
  271.            DBMS_OUTPUT.put_line(RPAD(' ', 40)||per_in(i)||' НЕ ПОДХОДИТ - в этом поле ограничение в '||index_cicla1.Data_Precision||' знаков или масштаб (scale) указан неправильно');
  272.            s := FALSE ;
  273.         END IF;        
  274.    END IF;
  275.  
  276.  
  277.   ELSE
  278.                   IF ( index_cicla1.DATA_TYPE = 'DATE') THEN
  279.                   DBMS_OUTPUT.put_line(RPAD(' ', 40)||''''|| TO_DATE(per_in(i), 'DD-MM-YYYY')||'''' || ' ПОДХОДИТ' ); --под DATE
  280.                  
  281.                   ELSE
  282.                    
  283.                   -- обработка index_cicla1.CHAR_LENGTH
  284.                 var12 := LENGTH(per_in(i));
  285.                   IF (index_cicla1.CHAR_LENGTH >=  var12 ) THEN
  286.                   DBMS_OUTPUT.put_line(RPAD(' ', 40)||''''||(per_in(i))||''''||' ПОДХОДИТ');-- под CHAR
  287.                   ELSE
  288.                    
  289.                     DBMS_OUTPUT.put_line(RPAD(' ', 40)||(per_in(i))||' НЕ ПОДХОДИТ, длина строки больше на '|| (var12 -index_cicla1.CHAR_LENGTH) );
  290.                     s := FALSE ;
  291.                    END IF;
  292.                   END IF;
  293.    
  294.    
  295.    END IF;
  296.    END IF;
  297.  
  298.    
  299. EXCEPTION
  300.  
  301.    --INVALID_NUMBER:
  302.    WHEN ERR_NUMBER THEN
  303.      s := FALSE ;
  304.      DBMS_OUTPUT.put_line(RPAD(' ', 40)||per_in(i)||' НЕ ПОДХОДИТ');
  305.    
  306.   --INVALID_DATE:
  307.    WHEN ERR_DATE THEN
  308.      s := FALSE ;
  309.    DBMS_OUTPUT.put_line(RPAD(' ', 40)||per_in(i)||' НЕ ПОДХОДИТ');
  310.    WHEN ERR_DATE_FORMAT  THEN
  311.      s := FALSE ;
  312.      DBMS_OUTPUT.put_line(RPAD(' ', 40)||per_in(i)||' НЕ ПОДХОДИТ');
  313.  
  314.    WHEN ERR_DATE_FORMAT1  THEN
  315.      s := FALSE ;
  316.      DBMS_OUTPUT.put_line(RPAD(' ', 40)||per_in(i)||' НЕ ПОДХОДИТ');
  317.      
  318.    WHEN ERR_DATE_FORMAT2  THEN
  319.      s := FALSE ;
  320.      DBMS_OUTPUT.put_line(RPAD(' ', 40)||per_in(i)||' НЕ ПОДХОДИТ');
  321.    WHEN ERR_DATE_FORMAT3  THEN
  322.      s := FALSE ;
  323.      DBMS_OUTPUT.put_line(RPAD(' ', 40)||per_in(i)||' НЕ ПОДХОДИТ');
  324.      
  325.    
  326.   --  WHEN OTHERS THEN
  327.  --    RAISE_APPLICATION_ERROR(-20011,'Какая-то другая ошибка');
  328. END;
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335. EXIT WHEN cur1%NOTFOUND;
  336. END LOOP;
  337. dbms_output.put_line('===================================================================================================');
  338.   IF (s = TRUE ) THEN
  339.    DBMS_OUTPUT.put_line(RPAD(' ', 27)||'TRUE - все значения верны по типу и точности') ;
  340.    ELSE
  341.    DBMS_OUTPUT.put_line(RPAD(' ', 27)||'FALSE - есть ошибки в некоторых значениях') ;
  342.    END IF;
  343. dbms_output.put_line('===================================================================================================');
  344.  
  345.  
  346. -- нужно прописывать SET SCAN OFF чтобы экранирвание прошло успешно, а потом SET SCAN ON
  347.  
  348. var5 := ''''||per_in(1)||'''';
  349. FOR i IN 2..per_in.COUNT - m  LOOP
  350.  
  351. var5 := var5||','||''''||per_in(i)||''''; --экранирование одной кавчки ''
  352.  
  353. END LOOP;
  354.  
  355. --dbms_output.put_line(var5); -- вывод элементов массива 'a','s','gg' и и т.п.
  356.  
  357. -- правильно: INSERT INTO Н_ЛЮДИ values ('100500','ivanov','ivan','nikolaivich','pin1','inn','20.07.2003','Ж','olololo9','olo','SPb','20.07.2003','PIN','20.07.2003','')
  358. -- если уже есть: delete from Н_ЛЮДИ where ИД = 100500;
  359. -- вставка элементов массива VARRAY в таблицу
  360. IF (s = TRUE) THEN
  361.  
  362.  var6 := 'INSERT INTO '||UPPER(table_name_in)||' VALUES '||'('||TO_CHAR(var5)||')';
  363. -- dbms_output.put_line(var6);
  364.  EXECUTE IMMEDIATE var6; -- добавляю в таблицу данные
  365.  
  366.    dbms_output.put_line(RPAD(' ', 20)||'Строка добавлена в таблицу '||UPPER(table_name_in));
  367.    
  368. ELSE
  369.   dbms_output.put_line('    Строка не добавлена в таблицу '||UPPER(table_name_in)||', смотрите правильность типа данных и точность');
  370.  
  371. END IF;
  372.  
  373. dbms_output.put_line('===================================================================================================');
  374.  
  375.  
  376. EXCEPTION --общий блок исключений
  377.    WHEN ERR_UNIQUE THEN
  378.    DBMS_OUTPUT.put_line(RPAD(' ', 5)||' Строка с такими уникальными элементами (это поля '||var15||' и '||var18||') уже присутствует в таблице '||UPPER(table_name_in));
  379.    dbms_output.put_line('===================================================================================================');
  380.    
  381.    
  382.    WHEN ERR_CHECK THEN
  383.    DBMS_OUTPUT.put_line('Строка не добавлена в таблицу '||UPPER(table_name_in)||', обратите внимание на Column name: '||var13||'; там есть const CHECK');
  384.   dbms_output.put_line('===================================================================================================');
  385.    
  386.    WHEN PER_MENISHE THEN
  387.   RAISE_APPLICATION_ERROR(-20012,'Число переменных массива < чем число столбцов таблицы '||UPPER(table_name_in));
  388. END myproc;
  389. /
Add Comment
Please, Sign In to add comment