Ответы пользователя по тегу PL/SQL
  • Как вывести всю строку в FOR..IN не перечисляя вручную столбцы?

    erge
    @erge
    Примус починяю
    DECLARE
        l_sql        VARCHAR2(32767):='
          SELECT 1 field_11, ''river'' field_22 FROM DUAL
          UNION ALL
          SELECT 1 field_11, ''sharf'' field_22 FROM DUAL
        ';
        l_cur        PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;
        l_ind        PLS_INTEGER;
        l_col_count  PLS_INTEGER;
        l_col_names  DBMS_SQL.DESC_TAB;
        l_out        VARCHAR2(32767);
        col_val_chr  VARCHAR2(32767);
        LNBR         VARCHAR2(2)  := CHR(13)||CHR(10);
        col_delim    VARCHAR2(20) := '</td><td>';
        row_delim    VARCHAR2(20) := '</td></tr>'|| LNBR ||'<tr><td>';
    BEGIN
        -- Разбор запроса
        DBMS_SQL.PARSE (
          l_cur,
          l_sql,
          DBMS_SQL.NATIVE
        );
        -- Получение информации о столбцах
        DBMS_SQL.DESCRIBE_COLUMNS (l_cur, l_col_count, l_col_names);
        -- Вывод каждого из имен столбцов
        FOR col_ind IN 1 .. l_col_count
        LOOP
            -- Определим тип столбца
            DBMS_SQL.DEFINE_COLUMN(l_cur, col_ind, col_val_chr, 32767);
            -- Выводим наимнование столбца
            l_out := l_out || l_col_names(col_ind).col_name;
            -- Если не последний эл. вставляем разделитель
            IF col_ind != l_col_count
            THEN
                l_out := l_out || col_delim;
            END IF;
        END LOOP;
    
        -- Выполняем и фетчим курсор
        l_ind := DBMS_SQL.EXECUTE (l_cur);
        LOOP
            l_ind := DBMS_SQL.FETCH_ROWS( l_cur );
            EXIT WHEN l_ind = 0;
    
            l_out := l_out || row_delim;
    
            FOR col_ind IN 1 .. l_col_count
            LOOP
                -- Читаем и выводим значение
                DBMS_SQL.COLUMN_VALUE (l_cur, col_ind, col_val_chr);
                l_out := l_out || col_val_chr;
                -- Если не последний эл. вставляем разделитель
                IF col_ind != l_col_count
                THEN
                    l_out := l_out || col_delim;
                END IF;
            END LOOP;
        END LOOP;
        DBMS_SQL.CLOSE_CURSOR (l_cur);
        DBMS_OUTPUT.PUT_LINE('<table>'||LNBR||'<tr><td>'|| l_out ||'</td></tr>'||LNBR||'</table>');
    END;
    /
    
    /*
        -- Если задать разделители полей ; и LNBR то на выходе получим CSV данные
        col_delim    VARCHAR2(20) := ';';
        row_delim    VARCHAR2(20) := LNBR;
    */


    см. пример на dbfiddle

    PS: Вы видимо что-то недочитали :)
    Спасибо, сам разобрался, даже и не знал что так можно, теперь наверно буду использовать :)

    UPDATE:
    Можно обернуть в функцию и помимо прочего передавать в нее тип разделителя (для HTML можно передавать стили или classname для таблицы) и на выходе иметь разный формат данных.
    Ответ написан
    Комментировать
  • Возможно ли в одной выборке вывести несколько COUNT`ов с условием?

    erge
    @erge
    Примус починяю
    а взять и просто написать, вместо того чтобы спрашивать?
    COUNT не считает NULL
    SELECT
        key,
        count(DECODE(value, 'tino',1, NULL)) AS tino,
        count(DECODE(value, 'tipo',1, NULL)) AS tipo,
        count(DECODE(value, 'tiko',1, NULL)) AS tiko
      FROM table1
      GROUP BY key


    см. на sqlfiddle
    Ответ написан
    Комментировать