---
# System prepended metadata

title: СУБД

---

# СУБД

### Лабораторная работа №1


sqplus>

Ширина вывода
> set linesize 600; 

Отключает игнорирование пробелов спереди
> SET SERVEROUTPUT ON FORMAT WRAPPED; 

> set

Первая версия запроса (завернуть в функцию)
```
select COLUMN_ID as "No.", COLUMN_NAME as "Имя столбца", ('Type: ' || DATA_TYPE || CHR(10) || 'COMMEN: ' || CHR(10) || '' || 'Constraint: ' || '') as "Атрибуты" from USER_TAB_COLUMNS;
```
Вторая версия 
```
select COLUMN_ID as "No.", COLUMN_NAME as "Имя столбца", ('Type: ' || DATA_TYPE || CHR(10) || 'COMMEN: ' || CHR(10) || '' || 'Constraint: ' || '') as "Атрибуты" from ALL_TAB_COLUMNS WHERE TABLE_NAME = 'Н_УЧЕНИКИ';
```
Вариант с коментариями 
```
select atc.COLUMN_ID as "No.", atc.COLUMN_NAME as "Имя столбца", ('Type: ' || atc.DATA_TYPE || CHR(10) || 'COMMEN: ' || dcc.COMMENTS || CHR(10) || '' || 'Constraint: ' || '') as "Атрибуты"
from ALL_TAB_COLUMNS atc join DBA_COL_COMMENTS dcc on atc.TABLE_NAME = dcc.TABLE_NAME and atc.COLUMN_NAME = dcc.COLUMN_NAME
WHERE atc.TABLE_NAME = 'Н_УЧЕНИКИ';
```

Процедура
```
CREATE OR REPLACE PACKAGE s223860.lab1 IS
  TYPE rowRec IS RECORD
  (
    "No." NUMBER,
    "Имя столбца" VARCHAR2(30),
    "Атрибуты" VARCHAR2(134)
  );

  TYPE tableRec IS TABLE OF rowRec;

  FUNCTION getInfo RETURN tableRec PIPELINED ;
  END lab1;

  CREATE OR REPLACE PACKAGE BODY s223860.lab1 AS
    FUNCTION getInfo
      RETURN  tableRec PIPELINED IS
      BEGIN
        for rec IN (
          select COLUMN_ID as "No.", COLUMN_NAME as "Имя столбца", ('Type: ' || DATA_TYPE || CHR(10) || 'COMMEN: ' || CHR(10) || '' || 'Constraint: ' || '') as "Атрибуты" 
          from ALL_TAB_COLUMNS WHERE TABLE_NAME = 'Н_УЧЕНИКИ'

        )
          LOOP
          PIPE ROW (rec);
        END LOOP;
        END getInfo;
      END lab1;

SELECT * FROM TABLE(lab1.getInfo);
```


Процедура 2 (не дописана)
```
create or replace procedure table_info(TAB_NAME VARCHAR2) as
    cursor table_inforamtion is
        select
               COLUMN_ID,
               tc.COLUMN_NAME,
               DATA_TYPE,
               NULLABLE,
               DATA_PRECISION,
               CHAR_LENGTH,
               COMMENTS  from USER_TAB_COLUMNS tc
        join USER_COL_COMMENTS cc on tc.TABLE_NAME = cc.TABLE_NAME and tc.COLUMN_NAME = cc.COLUMN_NAME
        where tc.TABLE_NAME = 'CUSTOMERS';

    dataType VARCHAR2(128);
begin
    DBMS_OUTPUT.ENABLE();
    DBMS_OUTPUT.PUT_LINE('Таблица: ' || TAB_NAME);

    dbms_output.put_line('No.      Имя столбца      Атрибуты');
    dbms_output.put_line('_______  ________________ _______________________');


    for row in table_inforamtion loop

        if row.DATA_PRECISION is not null then
            dataType := row.DATA_TYPE || '(' || row.DATA_PRECISION || ')';
        end if;

        dbms_output.PUT_LINE(RPAD(TO_CHAR(row.COLUMN_ID), 8) || ' ' || RPAD(row.COLUMN_NAME, 12) || ' ' || 'Type: ' || dataType);
    end loop;

end table_info;
```
что то дописал (добавил комент и попровил 'верстку') 
```
CREATE OR REPLACE PROCEDURE table_info(TAB_NAME VARCHAR2) AS
    CURSOR table_inforamtion IS
        SELECT
               COLUMN_ID,
               tc.COLUMN_NAME,
               DATA_TYPE,
               NULLABLE,
               DATA_PRECISION,
               CHAR_LENGTH,
               COMMENTS
        FROM ALL_TAB_COLUMNS tc JOIN ALL_COL_COMMENTS cc ON tc.TABLE_NAME = cc.TABLE_NAME AND tc.COLUMN_NAME = cc.COLUMN_NAME
        WHERE tc.TABLE_NAME = TAB_NAME;

    dataType VARCHAR2(128);
BEGIN
    DBMS_OUTPUT.ENABLE();
    DBMS_OUTPUT.PUT_LINE('Таблица: ' || TAB_NAME);
    DBMS_OUTPUT.PUT_LINE('');
    DBMS_OUTPUT.PUT_LINE('No.      Имя столбца      Атрибуты');
    DBMS_OUTPUT.PUT_LINE('--- ----------------- ------------------------------------------------------');

    FOR row IN table_inforamtion LOOP
        IF row.DATA_PRECISION IS NOT NULL THEN
            dataType := row.DATA_TYPE || '(' || row.DATA_PRECISION || ')';
        ELSE
            IF row.CHAR_LENGTH > 0 THEN
              dataType := row.DATA_TYPE || '(' || row.CHAR_LENGTH || ')';
            ELSE
              dataType := row.DATA_TYPE;
            END IF;
        END IF;

        DBMS_OUTPUT.PUT_LINE(RPAD(TO_CHAR(row.COLUMN_ID), 3) || ' ' || RPAD(row.COLUMN_NAME, 17) || ' ' || 'Type: ' || dataType);

        IF row.COMMENTS IS NOT NULL  THEN
          DBMS_OUTPUT.PUT_LINE(RPAD(TO_CHAR(' '), 3) || ' ' || RPAD(' ', 17) || ' ' || 'Comment: ' || row.COMMENTS);
        END IF ;
    END LOOP;

END table_info;
```

как я понял осталось добавить линки (constraint)
![](https://i.imgur.com/MlKs4W1.png) 
???возможно это???

а и еще не совсем понятное not null у типа DATE возиожно это поле ALL_TAB_COLUMNS.nullable


v3
```sql
create or replace procedure table_info(TAB_NAME VARCHAR2) as
    cursor table_inforamtion is
        select
               COLUMN_ID,
               tab.COLUMN_NAME,
               DATA_TYPE,
               NULLABLE,
               DATA_PRECISION,
               CHAR_LENGTH,
               COMMENTS
        from ALL_TAB_COLUMNS tab
        left join ALL_COL_COMMENTS col on tab.TABLE_NAME = col.TABLE_NAME and tab.COLUMN_NAME = col.COLUMN_NAME and tab.OWNER = col.OWNER
        where tab.TABLE_NAME = UPPER(TAB_NAME)
        order by tab.COLUMN_ID;

    cursor cnstrs is
        select
               c.CONSTRAINT_NAME,
               COLUMN_NAME,
               CONSTRAINT_TYPE
        from ALL_CONS_COLUMNS cons
        join ALL_CONSTRAINTS c on c.TABLE_NAME = cons.TABLE_NAME and c.OWNER = cons.OWNER and cons.CONSTRAINT_NAME = c.CONSTRAINT_NAME
        where cons.TABLE_NAME = UPPER(TAB_NAME);


    dataType VARCHAR2(128);
    colConstr VARCHAR2(128);

begin
    DBMS_OUTPUT.ENABLE();
    DBMS_OUTPUT.PUT_LINE('Таблица: ' || TAB_NAME);
    DBMS_OUTPUT.PUT_LINE('');
    DBMS_OUTPUT.PUT_LINE('No. Имя столбца       Атрибуты');
    DBMS_OUTPUT.PUT_LINE('--- ----------------- ------------------------------------------------------');

    FOR row IN table_inforamtion LOOP
        IF row.DATA_PRECISION IS NOT NULL THEN
            dataType := row.DATA_TYPE || '(' || row.DATA_PRECISION || ')';
        ELSE
            IF row.CHAR_LENGTH > 0 THEN
              dataType := row.DATA_TYPE || '(' || row.CHAR_LENGTH || ')';
            ELSE
              dataType := row.DATA_TYPE;
            END IF;
        END IF;

        DBMS_OUTPUT.PUT_LINE(RPAD(TO_CHAR(row.COLUMN_ID), 3) || ' ' || RPAD(row.COLUMN_NAME, 17) || ' ' || 'Type: ' || dataType);

        IF row.COMMENTS IS NOT NULL THEN
          DBMS_OUTPUT.PUT_LINE(RPAD(TO_CHAR(' '), 3) || ' ' || RPAD(' ', 17) || ' ' || 'Comment: ' || row.COMMENTS);
        END IF ;

        colConstr := NULL;
        for cnstr in cnstrs loop
--             P (primary key) - PK = not null + unique
            if cnstr.COLUMN_NAME = row.COLUMN_NAME and cnstr.CONSTRAINT_TYPE = 'P' then
                colConstr := cnstr.CONSTRAINT_NAME ||' Primary key';
            end if;
        end loop;

        IF colConstr is NULL and row.NULLABLE = 'N' THEN
--             Check NULLABLE
            colConstr := 'NOT NULL';
        END IF ;

        IF colConstr is not NULL then
--             if found constraint
            DBMS_OUTPUT.PUT_LINE(RPAD(TO_CHAR(' '), 3) || ' ' || RPAD(' ', 17) || ' ' || 'Constraint: ' || colConstr);
        end if;

    END LOOP;

end table_info;
```