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中做的每一个疯狂的事情。希望永远不要再写这样的东西的主要内容,如果未能解决你的问题,请参考以下文章