sql 关于在一个程序中你可以在PL / SQL中做的每一个疯狂的事情。希望永远不要再写这样的东西

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sql 关于在一个程序中你可以在PL / SQL中做的每一个疯狂的事情。希望永远不要再写这样的东西相关的知识,希望对你有一定的参考价值。

PROCEDURE build_configurations(
    p_model_instance_id   IN model_instance. id %type,
    p_resale_value_factor IN NUMBER DEFAULT .7,
    p_user_id             IN users . id %type)
AS
  dbms_cursor    INTEGER;
  ignore         INTEGER;
  v_var_holder         NUMBER;
  v_config_query VARCHAR2(32767) ;
  v_gc_name_array varchar_array;
  v_config_set_array num_array;
  v_loop_counter      NUMBER := 0;
  v_configuration_template_id NUMBER;
  v_cg_model_instance_config_id cg_model_instance_config.id%TYPE;
  v_configured_price cg_model_instance_config.configured_price%type;
  v_configured_price_date cg_model_instance_config.config_price_date%type;
  v_configured_weight cg_model_instance_config.configured_weight%type;
  v_resale_value cg_model_instance_config.resale_value%type;
  v_resale_source cg_model_instance_config.resale_source%type;
  v_date_discontinued cg_model_instance_config.date_discontinued%type;
  -- TODO: Change this to zero, getting past current constraint
  v_sort_order         NUMBER := 1;
BEGIN
  v_gc_name_array    := varchar_array() ;
  v_config_set_array := num_array() ;
  SELECT mi.config_price                                                                                                           ,
    mi.config_price_date                                                                                                           ,
    mi.config_weight                                                                                                               ,
    NVL(NVL(NVL(mivs_by_year.resale_value, mivs_by_age1.resale_value), mi.config_price * p_resale_value_factor), 0) AS resale_value,
    CASE
      WHEN NVL(mivs_by_year.resale_value, mivs_by_age1.resale_value) IS NOT NULL
      THEN 'Green Guide'
      ELSE 'Computed'
    END AS resale_source,
    mi.date_discontinued
  INTO v_configured_price  ,
    v_configured_price_date,
    v_configured_weight    ,
    v_resale_value         ,
    v_resale_source        ,
    v_date_discontinued
  FROM model_instance mi
  LEFT JOIN model_inst_value_stream mivs_by_year
  ON mivs_by_year.model_instance_id                    = mi. id
  AND to_number(TO_CHAR(mi.date_discontinued, 'yyyy')) = mivs_by_year. YEAR
  LEFT JOIN model_inst_value_stream mivs_by_age1
  ON mivs_by_age1.model_instance_id = mi. id
  AND mivs_by_age1.age              = 1
  WHERE mi. id                      = p_model_instance_id;
  IF(v_configured_price            IS NOT NULL) THEN
    -- if a matched configuration was previously included.  it will be included.
    -- if a matched configuration was previously excluded.  it will be excluded.
    -- if an unmatched configuration (e.g. new) is found.  it will be included.
    SELECT gcid.global_components ,
      mc.approved_flag            ,
      en.product_volume_id        ,
      en.manufacturer_id          ,
      en.equipment_subtype_id     ,
      en.equipment_subtype_size_id,
      en.notes BULK COLLECT
    INTO vtab_previous_config_template
    FROM
      (SELECT uf_table_to_string(CAST(collect(TO_CHAR(global_component.id)
      ORDER BY global_component.id) AS varchar_array)) AS global_components,
        cg_model_instance_config.configuration_template_id
      FROM global_component
      INNER JOIN configuration_template_detail
      ON global_component.id = configuration_template_detail.global_component_id
      INNER JOIN configuration_template
      ON configuration_template.id = configuration_template_detail.configuration_template_id
      INNER JOIN cg_model_instance_config
      ON configuration_template.id = cg_model_instance_config.configuration_template_id
      GROUP BY cg_model_instance_config.configuration_template_id
      ) gcid
    INNER JOIN cg_model_instance_config mc
    ON mc.configuration_template_id = gcid.configuration_template_id
    LEFT JOIN external_notes en
    ON en.cg_model_instance_config_id = mc.id
    AND(mc.approved_flag              = 'N'
    OR en.id                         IS NOT NULL) ;
    -- delete all existing configs notes.
    /*DELETE
    FROM external_notes
    WHERE EXISTS
    (SELECT 1
    FROM cg_model_instance_config
    WHERE id              = external_notes.cg_model_instance_config_id
    AND model_instance_id = p_model_instance_id
    ) ;
    -- delete old config template details
    DELETE
    FROM configuration_template_detail
    WHERE configuration_template_id IN
    (SELECT configuration_template.id
    FROM configuration_template
    INNER JOIN cg_model_instance_config
    ON cg_model_instance_config.configuration_template_id = configuration_template.id
    WHERE cg_model_instance_config.model_instance_id      = p_model_instance_id
    ) ;
    -- delete old cg_model_instance_config records
    DELETE
    FROM cg_model_instance_config
    WHERE cg_model_instance_config.model_instance_id = p_model_instance_id;
    -- delete old config templates
    DELETE
    FROM configuration_template
    WHERE id IN
    (SELECT configuration_template_id
    FROM cg_model_instance_config
    WHERE cg_model_instance_config.model_instance_id = p_model_instance_id
    ) ;*/
    --Loop component names
    FOR x IN
    (SELECT DISTINCT GLOBAL_COMPONENT. NAME
    FROM GLOBAL_COMPONENT
    INNER JOIN COMPONENT_TEMPLATE
    ON COMPONENT_TEMPLATE.GLOBAL_COMPONENT_ID = GLOBAL_COMPONENT. ID
    INNER JOIN COMPONENT_SPECIFICATION
    ON COMPONENT_SPECIFICATION.GLOBAL_COMPONENT_ID = GLOBAL_COMPONENT. ID
    INNER JOIN GLOBAL_SPECIFICATION
    ON COMPONENT_SPECIFICATION.GLOBAL_SPECIFICATION_ID = GLOBAL_SPECIFICATION. ID
    INNER JOIN model_instance
    ON component_template.model_instance_id = model_instance. ID
    INNER JOIN equipment_subtype_size
    ON model_instance.equipment_subtype_size_id = equipment_subtype_size. ID
    INNER JOIN equipment_subtype
    ON equipment_subtype_size.equipment_subtype_id = equipment_subtype. ID
    INNER JOIN equipment_type
    ON equipment_subtype.equipment_type_id = equipment_type. ID
    WHERE MODEL_INSTANCE. ID               = p_model_instance_id
    )
    LOOP
      v_loop_counter := v_loop_counter + 1;
      v_gc_name_array.EXTEND() ;
      v_gc_name_array(v_loop_counter) := x.name;
    END LOOP;
    --Create query for unique sets of components
    FOR i IN v_gc_name_array.first .. v_gc_name_array.last
    LOOP
      IF i              = v_gc_name_array.FIRST THEN
        v_config_query := 'SELECT DISTINCT * FROM (SELECT DISTINCT GLOBAL_COMPONENT.ID FROM GLOBAL_COMPONENT INNER JOIN COMPONENT_TEMPLATE          
          ON COMPONENT_TEMPLATE.GLOBAL_COMPONENT_ID = GLOBAL_COMPONENT.ID WHERE          
          component_template.model_instance_id = ' || p_model_instance_id || ' AND GLOBAL_COMPONENT.name = ''' || v_gc_name_array(i) || ''') CROSS JOIN ';
      END IF;
      IF i             != v_gc_name_array.FIRST AND i != v_gc_name_array.LAST THEN
        v_config_query := v_config_query || '(SELECT DISTINCT GLOBAL_COMPONENT.ID FROM GLOBAL_COMPONENT INNER JOIN COMPONENT_TEMPLATE          
          ON COMPONENT_TEMPLATE.GLOBAL_COMPONENT_ID = GLOBAL_COMPONENT.ID WHERE          
          component_template.model_instance_id = ' || p_model_instance_id || ' AND GLOBAL_COMPONENT.name = ''' || v_gc_name_array(i) || ''') CROSS JOIN ';
      END IF;
      IF i              = v_gc_name_array.LAST THEN
        v_config_query := v_config_query || '(SELECT DISTINCT GLOBAL_COMPONENT.ID FROM GLOBAL_COMPONENT INNER JOIN COMPONENT_TEMPLATE          
        ON COMPONENT_TEMPLATE.GLOBAL_COMPONENT_ID = GLOBAL_COMPONENT.ID WHERE         
        component_template.model_instance_id = ' || p_model_instance_id || ' AND GLOBAL_COMPONENT.name = ''' || v_gc_name_array(i) || ''')';
      END IF;
      v_config_set_array.extend() ;
    END LOOP;
    --Set up dbms_cursor
    dbms_cursor := dbms_sql.open_cursor;
    DBMS_SQL.PARSE(dbms_cursor, v_config_query, DBMS_SQL.NATIVE) ;
    FOR i IN v_gc_name_array.first .. v_gc_name_array.last
    LOOP
      DBMS_SQL.DEFINE_COLUMN(dbms_cursor, i, v_var_holder);
    END LOOP;
    ignore := DBMS_SQL.EXECUTE(dbms_cursor) ;
    -- Create records
    /*FOR x IN
    (SELECT DISTINCT
        GLOBAL_COMPONENT. NAME,
        GLOBAL_COMPONENT. ID
      FROM
        GLOBAL_COMPONENT
      INNER JOIN COMPONENT_TEMPLATE ON COMPONENT_TEMPLATE.GLOBAL_COMPONENT_ID = GLOBAL_COMPONENT. ID
      INNER JOIN COMPONENT_SPECIFICATION ON COMPONENT_SPECIFICATION.GLOBAL_COMPONENT_ID = GLOBAL_COMPONENT. ID
      INNER JOIN GLOBAL_SPECIFICATION ON COMPONENT_SPECIFICATION.GLOBAL_SPECIFICATION_ID = GLOBAL_SPECIFICATION. ID
      INNER JOIN model_instance ON component_template.model_instance_id = model_instance. ID
      INNER JOIN equipment_subtype_size ON model_instance.equipment_subtype_size_id = equipment_subtype_size. ID
      INNER JOIN equipment_subtype ON equipment_subtype_size.equipment_subtype_id = equipment_subtype. ID
      INNER JOIN equipment_type ON equipment_subtype.equipment_type_id = equipment_type. ID
      WHERE
        MODEL_INSTANCE. ID = p_model_instance_id
      ORDER BY
        GLOBAL_COMPONENT. NAME
    )
    LOOP*/
    LOOP
      IF DBMS_SQL.FETCH_ROWS(dbms_cursor) > 0 THEN
      -- Create configuration_template record and save id for configuration_template_detail records
      INSERT
      INTO configuration_template
        (
          updated_user_id,
          updated_date
        )
        VALUES
        (
          p_user_id,
          sysdate
        )
      RETURNING id
      INTO v_configuration_template_id ;
      FOR i IN v_gc_name_array.first .. v_gc_name_array.last
      LOOP
        -- create configuration_template_detail record
        DBMS_SQL.COLUMN_VALUE(dbms_cursor, i, v_var_holder) ;
        INSERT
        INTO configuration_template_detail
          (
            configuration_template_id,
            global_component_id      ,
            updated_user_id          ,
            updated_date
          )
          VALUES
          (
            v_configuration_template_id,
            v_var_holder      ,
            p_user_id                  ,
            sysdate
          ) ;
        v_sort_order := v_sort_order + 1;
      END LOOP;
      -- create cg_model_instance_config record
      -- TODO: remove fake uid to get past constraint while testing
      INSERT
      INTO cg_model_instance_config
        (
          configuration_uid,
          model_instance_id,
          configured_price ,
          config_price_date,
          configured_weight,
          resale_value     ,
          resale_source    ,
          date_discontinued,
          approved_flag    ,
          build_date       ,
          sort_order       ,
          updated_user_id  ,
          updated_date     ,
          configuration_template_id
        )
        VALUES
        (
          'ThisCanBeDeleted'     ,
          p_model_instance_id    ,
          v_configured_price     ,
          v_configured_price_date,
          v_configured_weight    ,
          v_resale_value         ,
          v_resale_source        ,
          v_date_discontinued    ,
          'Y'                    ,
          sysdate                ,
          v_sort_order           ,
          p_user_id              ,
          sysdate                ,
          v_configuration_template_id
        ) ;
      -- Update config price
      BEGIN
        UPDATE cg_model_instance_config
        SET
          (
            configured_price
          )
          =
          (SELECT v_configured_price + NVL(config_price, 0)
          FROM
            (SELECT cg_model_instance_config.id,
              SUM(NVL(global_component.component_cost, 0)) config_price
            FROM cg_model_instance_config
            INNER JOIN configuration_template
            ON configuration_template.id = cg_model_instance_config.configuration_template_id
            INNER JOIN configuration_template_detail
            ON configuration_template_detail.configuration_template_id = configuration_template.id
            INNER JOIN global_component
            ON global_component.id                           = configuration_template_detail.global_component_id
            WHERE cg_model_instance_config.model_instance_id = p_model_instance_id
            GROUP BY cg_model_instance_config.id
            ) v
          WHERE cg_model_instance_config.id = v.id
          )
        WHERE model_instance_id = p_model_instance_id;
      EXCEPTION WHEN update_null_to_notnull THEN
        -- If no columns are returned NVL does not stop nulls
        NULL;
      END;
      -- Update config weight
      UPDATE cg_model_instance_config
      SET
        (
          configured_weight
        )
        =
        (SELECT v_configured_weight + NVL(config_weight, 300)
        FROM
          (SELECT cg_model_instance_config.id,
            SUM(NVL(component_specification.low_value, 0)) config_weight
          FROM component_specification
          INNER JOIN global_specification
          ON global_specification.id = component_specification.global_specification_id
          INNER JOIN global_component
          ON global_component.id = component_specification.global_component_id
          INNER JOIN component_template
          ON component_template.global_component_id = global_component.id
          INNER JOIN configuration_template_detail
          ON configuration_template_detail.global_component_id = global_component.id
          INNER JOIN configuration_template
          ON configuration_template.id = configuration_template_detail.configuration_template_id
          INNER JOIN cg_model_instance_config
          ON cg_model_instance_config.configuration_template_id = configuration_template.id
          WHERE global_specification.name                       = 'Weight'
          AND cg_model_instance_config.model_instance_id        = p_model_instance_id
          GROUP BY cg_model_instance_config.id
          ) v
        WHERE cg_model_instance_config.id = v.id
        )
      WHERE model_instance_id = p_model_instance_id;
      -- TODO: take out commit
      COMMIT;
      ELSE
      EXIT;
      END IF;
    END LOOP;
    -- check to see if any of the config's that previously existed, which is
    -- either deselected or has notes, is also exists in the new build.
    -- if so, retain deselected flag and notes.
    FOR i IN 1..vtab_previous_config_template.count
    LOOP
      BEGIN
        SELECT id
        INTO v_cg_model_instance_config_id
        FROM
          (SELECT uf_table_to_string(CAST(collect(TO_CHAR(global_component.id)
          ORDER BY global_component.id) AS varchar_array)) AS global_components,
            cg_model_instance_config.configuration_template_id
          FROM global_component
          INNER JOIN configuration_template_detail
          ON global_component.id = configuration_template_detail.global_component_id
          INNER JOIN configuration_template
          ON configuration_template.id = configuration_template_detail.configuration_template_id
          INNER JOIN cg_model_instance_config
          ON configuration_template.id = cg_model_instance_config.configuration_template_id
          GROUP BY cg_model_instance_config.configuration_template_id
          ) gcid
        INNER JOIN cg_model_instance_config mc
        ON mc.configuration_template_id                    = gcid.configuration_template_id
        WHERE model_instance_id                            = p_model_instance_id
        AND global_components                              = vtab_previous_config_template(i) .global_components;

        IF vtab_previous_config_template(i) .approved_flag = 'N' THEN
          UPDATE cg_model_instance_config
          SET approved_flag       = 'N'
          WHERE model_instance_id = p_model_instance_id
          AND id                  = v_cg_model_instance_config_id;
        END IF;

        IF vtab_previous_config_template(i) .notes IS NOT NULL THEN
          INSERT
          INTO external_notes
            (
              product_volume_id          ,
              model_instance_id          ,
              cg_model_instance_config_id,
              manufacturer_id            ,
              equipment_subtype_id       ,
              equipment_subtype_size_id  ,
              notes                      ,
              updated_user_id
            )
            VALUES
            (
              vtab_previous_config_template(i) .product_volume_id        ,
              p_model_instance_id                                        ,
              v_cg_model_instance_config_id                              ,
              vtab_previous_config_template(i) .manufacturer_id          ,
              vtab_previous_config_template(i) .equipment_subtype_id     ,
              vtab_previous_config_template(i) .equipment_subtype_size_id,
              vtab_previous_config_template(i) .notes                    ,
              p_user_id
            ) ;
        END IF;
      EXCEPTION
      WHEN no_data_found THEN
        -- well this config no longer exists in new build. if any notes
        -- were attached to it, will be gone.
        -- application should alert user about the possibility of losing
        -- notes.
        NULL;
      END;
    END LOOP;
  ELSE
    raise_build_error(p_model_instance_id => p_model_instance_id, p_message => 'has no configured price.  Once the price have been defined the model can be rebuilt.') ;
  END IF;
  pkg_cost_guide_dao.calculate_oocs(p_model_instance_id => p_model_instance_id, p_user_id => p_user_id) ;
END build_configurations;

以上是关于sql 关于在一个程序中你可以在PL / SQL中做的每一个疯狂的事情。希望永远不要再写这样的东西的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL编程_概述

在 PL/SQL 中创建动态对象

PL/SQL编程_子程序设计

在 PL/SQL 中重置关联数组?

(十三)PL/SQL包

关于 Oracle PL/SQL 引号运算符中的换行符:可以更改默认行为吗?