随机获取 "ORA-22814: attribute or element value is larger than specified in type" 批量收集到
Randomly getting "ORA-22814: attribute or element value is larger than specified in type" with a bulk collect into
我有代码随机获取 "ORA-22814: attribute or element value is larger than specified in type"
并批量收集到。
我怀疑这是一个数据问题,因为它是随机的,但 PL/SQL 不是我的强项,但我维护的应用程序在处理逻辑中有很多。
这是 Oracle 12c 数据库。
如有任何帮助,我们将不胜感激!
这是代码块:
SELECT mxpv_activityupdate_O (
projectid,
task_id,
task_code,
pvtask_code,
task_name,
CASE
WHEN wbs_t0_id IS NOT NULL AND scgemergent_flag = 'Y'
THEN
wbs_t0_id
ELSE
wbs_pv_id
END,
act_start_date,
CASE
WHEN act_end_date IS NOT NULL AND (invalidactfinish_flag = 'Y')
THEN
NULL
ELSE
act_end_date
END,
NULL,
CASE WHEN invalidactuals_flag = 'Y' THEN NULL ELSE act_work_qty END,
MAX (oid),
scgemergent_flag,
invalidactuals_flag,
invalidactfinish_flag)
BULK COLLECT INTO u_all_tab
FROM (SELECT projectorganization,
projecttype,
projectid,
task_id,
task_code,
pvtask_code,
pvact_start_date,
task_name,
act_start_date,
act_end_date,
CASE
WHEN pvact_start_date IS NULL
AND act_start_date IS NULL
AND NVL (act_work_qty, 0) <> 0
THEN
'Y'
ELSE
'N'
END
invalidactuals_flag,
act_work_qty,
oid,
wbs_t0_id,
wbs_pv_id,
CASE
WHEN pvact_start_date IS NULL
AND (act_start_date IS NOT NULL --or nvl(act_work_qty,0)<>0
)
AND projectorganization = 'SCG'
AND projecttype = 'Daily'
AND pvtarget_start_date > v_t0_start_midnight + 7
THEN
'Y'
ELSE
'N'
END
scgemergent_flag,
CASE
WHEN act_end_date IS NOT NULL
AND NVL (act_start_date, pvact_start_date) IS NOT NULL
AND act_end_date <
NVL (act_start_date, pvact_start_date)
THEN
'Y'
ELSE
'N'
END
invalidactfinish_flag
FROM (SELECT oid,
projecttype,
wbs_t0.wbs_id wbs_t0_id,
--emergentwork,
projectorganization,
projectid,
task_id,
pvwbs_id wbs_pv_id,
activityid task_code,
task_code pvtask_code,
pvact_start_date,
pvtarget_start_date,
CASE
WHEN pvact_end_date IS NULL THEN activityname
ELSE NULL
END
task_name,
CASE
WHEN actualstart IS NOT NULL
AND ( pvact_start_date IS NULL
OR actualfinish IS NOT NULL)
THEN
actualstart
ELSE
NULL
END
act_start_date,
--actualstart act_start_date,
CASE
WHEN pvact_end_date IS NULL
AND ( pvact_start_date IS NOT NULL
OR actualstart IS NOT NULL)
THEN
actualfinish
ELSE
NULL
END
act_end_date,
NULL target_start_date,
CASE WHEN mxactualunits.proj_catg_short_name = 'Y' --and nvl(pvact_work_qty, 0) <> nvl(actuallaborhours,0)
THEN NVL (actuallaborhours, 0) ELSE NULL END
act_work_qty
FROM --1) activityid and proj id matches
(SELECT oid,
pv.task_id,
mx.proj_id,
mx.projectid,
pv.task_code,
pv.task_name,
pv.wbs_id pvwbs_id,
pv.act_start_date pvact_start_date,
pv.act_end_date pvact_end_date,
pv.target_start_date pvtarget_start_date,
mx.activityid,
mx.activityname,
mx.actualstart,
mx.actualfinish,
pv.act_work_qty pvact_work_qty,
mx.actuallaborhours,
mx.projectorganization,
mx.projecttype,
mx.process_start_ts --,
FROM mxpv_activity_tmp mx, mxpv_task_tmp pv
WHERE mx.task_id = pv.task_id
UNION
--3) PM Number/Job Plan number matches
SELECT oid,
jp.task_id,
jp.proj_id,
jp.proj_short_name,
jp.task_code,
jp.task_name,
jp.wbs_id,
jp.act_start_date pvtarget_start_date,
jp.act_end_date pvtarget_end_date,
jp.target_start_date pvtarget_start_date,
jp.activityid,
jp.activityname,
jp.actualstart,
jp.actualfinish,
jp.act_work_qty pvact_work_qty,
actuallaborhours,
projectorganization,
projecttype,
p_process_start_ts --,
FROM --3a) PM Number matches
(SELECT * FROM TABLE (pm_tab)
UNION
--3a) Job Plan Number matches
SELECT * FROM TABLE (jp_tab)) jp)
update_activity,
(SELECT projpcat.PROJ_ID, pcval.PROJ_CATG_SHORT_NAME
FROM privuser_PROJPCAT projpcat,
privuser_PCATTYPE pctype,
privuser_PCATVAL pcval
WHERE projpcat.PROJ_CATG_ID = pcval.PROJ_CATG_ID
AND pcval.PROJ_CATG_TYPE_ID =
pctype.PROJ_CATG_TYPE_ID
AND pctype.PROJ_CATG_TYPE = 'MX Actual Units')
mxactualunits,
(SELECT w.wbs_id, w.proj_id
FROM privuser_projwbs w, privuser_phase ph
WHERE w.phase_id = ph.phase_id
AND ph.phase_name = '0') wbs_t0
WHERE --update_activity.proj_id = actstrtoffset.proj_id (+)
update_activity.proj_id = wbs_t0.proj_id(+)
AND update_activity.proj_id = mxactualunits.proj_id(+)
AND update_activity.process_start_ts =
p_process_start_ts--and delete_ts is null
))
GROUP BY projectid,
task_id,
task_code,
pvtask_code,
task_name,
wbs_t0_id,
wbs_pv_id,
act_start_date,
act_end_date,
act_work_qty,
invalidactuals_flag,
invalidactfinish_flag,
scgemergent_flag,
pvact_start_date;
类型定义如下:
TYPE PV_APP_DATA.MXPV_ACTIVITYUPDATE_O AS OBJECT(
proj_short_name VARCHAR2 (100),
task_id NUMBER,
task_code VARCHAR2 (120 CHAR),
pvtask_code VARCHAR2 (120 CHAR),
task_name VARCHAR2 (120 CHAR),
wbs_id NUMBER,
act_start_date DATE,
act_end_date DATE,
target_start_date DATE,
act_work_qty NUMBER,
oid NUMBER,
scgemergent_flag VARCHAR2 (10),
invalidactuals_flag VARCHAR2 (100),
invalidactfinish_flag VARCHAR2 (100)
)
如果您需要更多信息,请post 我不确定哪些信息有用。
更新 1 7/18/17
我用 substr 修改了查询,但没有成功解决问题:
select mxpv_activityupdate_O(
substr(projectid,0,99),
task_id,
substr(task_code,0,119),
substr(pvtask_code,0,119),
substr(task_name,0,119),
case when wbs_t0_id is not null and scgemergent_flag='Y' then wbs_t0_id
else wbs_pv_id end,
act_start_date,
case when act_end_date is not null and
(invalidactfinish_flag='Y'
)
then null else act_end_date end,
null,
case when invalidactuals_flag = 'Y' then null else act_work_qty end,
max(oid),
substr(scgemergent_flag,0,9),
substr(invalidactuals_flag,0,99),
substr(invalidactfinish_flag,0,99)
)
bulk collect into u_all_tab
from
(SELECT
projectorganization,
projecttype,
substr(projectid,0,99) as projectid,
task_id,
substr(task_code,0,119) as task_code,
substr(pvtask_code,0,119) as pvtask_code,
pvact_start_date,
substr(task_name,0,119) as task_name,
act_start_date,
act_end_date,
case when pvact_start_date is null and act_start_date is null
and nvl(act_work_qty, 0) <> 0 then 'Y' else 'N' end invalidactuals_flag,
act_work_qty,
oid,
wbs_t0_id,
wbs_pv_id,
case when pvact_start_date is null and
(act_start_date is not null --or nvl(act_work_qty,0)<>0
)
and projectorganization='SCG' and projecttype='Daily'
and pvtarget_start_date>v_t0_start_midnight+7
then 'Y' else 'N' end scgemergent_flag,
case when act_end_date is not null and nvl(act_start_date, pvact_start_date) is not null
and act_end_date<nvl(act_start_date, pvact_start_date) then 'Y' else 'N' end
invalidactfinish_flag
FROM
"if I want to force to correct length what's the best approach?"
您需要将 Table 列的长度与 Type 的目标属性的长度进行比较,并查看哪些属性比您试图放入其中的列短。使用数据字典。
对于类型属性,使用 USER_TYPE_ATTRS(如果是不同的架构,则使用 ALL_TYPE_ATTRS):
select attribute_name, attr_type_name, length, scale, precision
from user_type_attrs
where type_name = 'MXPV_ACTIVITY_UPDATE_O'
/
对于 Table 列,它将是基于 USER_TAB_COLS 的类似查询。
建立错误列后,您需要更改类型以扩大属性。或者将 SUBSTR()
函数应用于查询投影中的列,以将它们缩小到一定大小。哪个更好取决于您的应用程序的情况,尽管通常我们更喜欢不会丢失数据的方法。
我有代码随机获取 "ORA-22814: attribute or element value is larger than specified in type"
并批量收集到。
我怀疑这是一个数据问题,因为它是随机的,但 PL/SQL 不是我的强项,但我维护的应用程序在处理逻辑中有很多。
这是 Oracle 12c 数据库。
如有任何帮助,我们将不胜感激!
这是代码块:
SELECT mxpv_activityupdate_O (
projectid,
task_id,
task_code,
pvtask_code,
task_name,
CASE
WHEN wbs_t0_id IS NOT NULL AND scgemergent_flag = 'Y'
THEN
wbs_t0_id
ELSE
wbs_pv_id
END,
act_start_date,
CASE
WHEN act_end_date IS NOT NULL AND (invalidactfinish_flag = 'Y')
THEN
NULL
ELSE
act_end_date
END,
NULL,
CASE WHEN invalidactuals_flag = 'Y' THEN NULL ELSE act_work_qty END,
MAX (oid),
scgemergent_flag,
invalidactuals_flag,
invalidactfinish_flag)
BULK COLLECT INTO u_all_tab
FROM (SELECT projectorganization,
projecttype,
projectid,
task_id,
task_code,
pvtask_code,
pvact_start_date,
task_name,
act_start_date,
act_end_date,
CASE
WHEN pvact_start_date IS NULL
AND act_start_date IS NULL
AND NVL (act_work_qty, 0) <> 0
THEN
'Y'
ELSE
'N'
END
invalidactuals_flag,
act_work_qty,
oid,
wbs_t0_id,
wbs_pv_id,
CASE
WHEN pvact_start_date IS NULL
AND (act_start_date IS NOT NULL --or nvl(act_work_qty,0)<>0
)
AND projectorganization = 'SCG'
AND projecttype = 'Daily'
AND pvtarget_start_date > v_t0_start_midnight + 7
THEN
'Y'
ELSE
'N'
END
scgemergent_flag,
CASE
WHEN act_end_date IS NOT NULL
AND NVL (act_start_date, pvact_start_date) IS NOT NULL
AND act_end_date <
NVL (act_start_date, pvact_start_date)
THEN
'Y'
ELSE
'N'
END
invalidactfinish_flag
FROM (SELECT oid,
projecttype,
wbs_t0.wbs_id wbs_t0_id,
--emergentwork,
projectorganization,
projectid,
task_id,
pvwbs_id wbs_pv_id,
activityid task_code,
task_code pvtask_code,
pvact_start_date,
pvtarget_start_date,
CASE
WHEN pvact_end_date IS NULL THEN activityname
ELSE NULL
END
task_name,
CASE
WHEN actualstart IS NOT NULL
AND ( pvact_start_date IS NULL
OR actualfinish IS NOT NULL)
THEN
actualstart
ELSE
NULL
END
act_start_date,
--actualstart act_start_date,
CASE
WHEN pvact_end_date IS NULL
AND ( pvact_start_date IS NOT NULL
OR actualstart IS NOT NULL)
THEN
actualfinish
ELSE
NULL
END
act_end_date,
NULL target_start_date,
CASE WHEN mxactualunits.proj_catg_short_name = 'Y' --and nvl(pvact_work_qty, 0) <> nvl(actuallaborhours,0)
THEN NVL (actuallaborhours, 0) ELSE NULL END
act_work_qty
FROM --1) activityid and proj id matches
(SELECT oid,
pv.task_id,
mx.proj_id,
mx.projectid,
pv.task_code,
pv.task_name,
pv.wbs_id pvwbs_id,
pv.act_start_date pvact_start_date,
pv.act_end_date pvact_end_date,
pv.target_start_date pvtarget_start_date,
mx.activityid,
mx.activityname,
mx.actualstart,
mx.actualfinish,
pv.act_work_qty pvact_work_qty,
mx.actuallaborhours,
mx.projectorganization,
mx.projecttype,
mx.process_start_ts --,
FROM mxpv_activity_tmp mx, mxpv_task_tmp pv
WHERE mx.task_id = pv.task_id
UNION
--3) PM Number/Job Plan number matches
SELECT oid,
jp.task_id,
jp.proj_id,
jp.proj_short_name,
jp.task_code,
jp.task_name,
jp.wbs_id,
jp.act_start_date pvtarget_start_date,
jp.act_end_date pvtarget_end_date,
jp.target_start_date pvtarget_start_date,
jp.activityid,
jp.activityname,
jp.actualstart,
jp.actualfinish,
jp.act_work_qty pvact_work_qty,
actuallaborhours,
projectorganization,
projecttype,
p_process_start_ts --,
FROM --3a) PM Number matches
(SELECT * FROM TABLE (pm_tab)
UNION
--3a) Job Plan Number matches
SELECT * FROM TABLE (jp_tab)) jp)
update_activity,
(SELECT projpcat.PROJ_ID, pcval.PROJ_CATG_SHORT_NAME
FROM privuser_PROJPCAT projpcat,
privuser_PCATTYPE pctype,
privuser_PCATVAL pcval
WHERE projpcat.PROJ_CATG_ID = pcval.PROJ_CATG_ID
AND pcval.PROJ_CATG_TYPE_ID =
pctype.PROJ_CATG_TYPE_ID
AND pctype.PROJ_CATG_TYPE = 'MX Actual Units')
mxactualunits,
(SELECT w.wbs_id, w.proj_id
FROM privuser_projwbs w, privuser_phase ph
WHERE w.phase_id = ph.phase_id
AND ph.phase_name = '0') wbs_t0
WHERE --update_activity.proj_id = actstrtoffset.proj_id (+)
update_activity.proj_id = wbs_t0.proj_id(+)
AND update_activity.proj_id = mxactualunits.proj_id(+)
AND update_activity.process_start_ts =
p_process_start_ts--and delete_ts is null
))
GROUP BY projectid,
task_id,
task_code,
pvtask_code,
task_name,
wbs_t0_id,
wbs_pv_id,
act_start_date,
act_end_date,
act_work_qty,
invalidactuals_flag,
invalidactfinish_flag,
scgemergent_flag,
pvact_start_date;
类型定义如下:
TYPE PV_APP_DATA.MXPV_ACTIVITYUPDATE_O AS OBJECT(
proj_short_name VARCHAR2 (100),
task_id NUMBER,
task_code VARCHAR2 (120 CHAR),
pvtask_code VARCHAR2 (120 CHAR),
task_name VARCHAR2 (120 CHAR),
wbs_id NUMBER,
act_start_date DATE,
act_end_date DATE,
target_start_date DATE,
act_work_qty NUMBER,
oid NUMBER,
scgemergent_flag VARCHAR2 (10),
invalidactuals_flag VARCHAR2 (100),
invalidactfinish_flag VARCHAR2 (100)
)
如果您需要更多信息,请post 我不确定哪些信息有用。
更新 1 7/18/17 我用 substr 修改了查询,但没有成功解决问题:
select mxpv_activityupdate_O(
substr(projectid,0,99),
task_id,
substr(task_code,0,119),
substr(pvtask_code,0,119),
substr(task_name,0,119),
case when wbs_t0_id is not null and scgemergent_flag='Y' then wbs_t0_id
else wbs_pv_id end,
act_start_date,
case when act_end_date is not null and
(invalidactfinish_flag='Y'
)
then null else act_end_date end,
null,
case when invalidactuals_flag = 'Y' then null else act_work_qty end,
max(oid),
substr(scgemergent_flag,0,9),
substr(invalidactuals_flag,0,99),
substr(invalidactfinish_flag,0,99)
)
bulk collect into u_all_tab
from
(SELECT
projectorganization,
projecttype,
substr(projectid,0,99) as projectid,
task_id,
substr(task_code,0,119) as task_code,
substr(pvtask_code,0,119) as pvtask_code,
pvact_start_date,
substr(task_name,0,119) as task_name,
act_start_date,
act_end_date,
case when pvact_start_date is null and act_start_date is null
and nvl(act_work_qty, 0) <> 0 then 'Y' else 'N' end invalidactuals_flag,
act_work_qty,
oid,
wbs_t0_id,
wbs_pv_id,
case when pvact_start_date is null and
(act_start_date is not null --or nvl(act_work_qty,0)<>0
)
and projectorganization='SCG' and projecttype='Daily'
and pvtarget_start_date>v_t0_start_midnight+7
then 'Y' else 'N' end scgemergent_flag,
case when act_end_date is not null and nvl(act_start_date, pvact_start_date) is not null
and act_end_date<nvl(act_start_date, pvact_start_date) then 'Y' else 'N' end
invalidactfinish_flag
FROM
"if I want to force to correct length what's the best approach?"
您需要将 Table 列的长度与 Type 的目标属性的长度进行比较,并查看哪些属性比您试图放入其中的列短。使用数据字典。
对于类型属性,使用 USER_TYPE_ATTRS(如果是不同的架构,则使用 ALL_TYPE_ATTRS):
select attribute_name, attr_type_name, length, scale, precision
from user_type_attrs
where type_name = 'MXPV_ACTIVITY_UPDATE_O'
/
对于 Table 列,它将是基于 USER_TAB_COLS 的类似查询。
建立错误列后,您需要更改类型以扩大属性。或者将 SUBSTR()
函数应用于查询投影中的列,以将它们缩小到一定大小。哪个更好取决于您的应用程序的情况,尽管通常我们更喜欢不会丢失数据的方法。