1. SQL / Говнокод #4140

    −854

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    procedure dynamic_open(p_sql VARCHAR2, p_params t_string_table, p_cur OUT SYS_REFCURSOR) is
      begin
        case p_params.count
          when 0 then open p_cur for p_sql;
          when 1 then open p_cur for p_sql using p_params(1);
          when 2 then open p_cur for p_sql using p_params(1),
                                                 p_params(2);
          when 3 then open p_cur for p_sql using p_params(1),
                                                 p_params(2),
                                                 p_params(3);
          when 4 then open p_cur for p_sql using p_params(1),
                                                 p_params(2),
                                                 p_params(3),
                                                 p_params(4);
    /* ... */
          when 100 then open p_cur for p_sql using p_params(1),
                                                 p_params(2),
                                                 p_params(3),
                                                 p_params(4),
    /* ... */
                                                 p_params(100);
        end case;
      end dynamic_open;

    Динамический SQL - такой динамический. Уложились всего-то в 5050 строк.

    Запостил: wecanstoptrain, 31 Августа 2010

    Комментарии (12) RSS

    • Откуда это?
      Ответить
      • попытка обойти ограничение оракла на то, что количество забинденных переменных в динамическом запросе должно быть известно в compile-time
        Ответить
        • надо юзать dbms_sql в таких случаях.
          Ответить
          • на выходе нужно иметь sys_refcursos, а в 10-ке нет dbms_sql.to_refcursor, так что пока не перейдем на 11g, будет торчать такое убожество.
            Ответить
        • Это решается очень просто, еще в процессе генерирования текста dynamic SQL - для неиспользуемых параметров генеришь "always-true-заглушки" (см.ниже пример кода).

          Это позволяет при любых входящих условиях выполнять execute immediate ... using ... или open for ... using ... с неизменным числом параметров.
          v_sql := 'SELECT tbl1.* FROM my_table tbl1 WHERE 1=1';
              IF param01 IS NOT NULL
              THEN
                  v_sql := v_sql || ' AND tbl1.some_field = :p01';
              ELSE
                  v_sql := v_sql || ' AND (1=1 OR :p01 IS NULL)';
              END IF;
              .........
              IF param08 IS NOT NULL
              THEN
                  v_sql := v_sql || ' AND tbl1.another_field = :p08';
              ELSE
                  v_sql := v_sql || ' AND (1=1 OR :p08 IS NULL)';
              END IF;
              .........
              OPEN p_cur FOR v_sql USING param01, ..., param08, ..., param100;
          Ответить
      • это PL/SQL - язык программирования в Оракле.
        Ответить
    • варарг на коленке?
      Ответить
    • Автор, используй пакет dbms_sql и будет тебе счастье.
      Ответить
    • на sql-ex.ru было ограничение в 8 Кб текста запроса... и что?
      Ответить

    Добавить комментарий