nvl2(count(*),count(*),0)提示ORA-01722無效數字


最近在公司接觸項目部署和客戶化工作,最讓我郁悶的不是客戶長期的更改,而是不同環境和結果數據產生的異常。因為這樣的異常在我本地是沒法測試的,只能通過正式庫的數據和場景不斷的推斷,在本地進行環境模擬測試,首先場景模擬就很讓我頭疼,因為場景模擬就代表這你對該異常有一個初步的判斷,但是對於sql語句提示你執行錯誤,你怎能知道哪里錯誤,為什么錯誤,而且在自己本地明明就沒有錯誤,這時候只想說,天,你把我送走吧。

言歸正傳,直接上sql:

sql.append("select pmi.authority_id, pmi.pe_id, p.pe_visit_id, pmi.name, pmi.sex, pmi.date_of_birth, pmi.id_no, pmi.mobile, pmi.phone_number, p.pe_source, p.pe_pre_date , p.set_name_cust , p.audit_doctor_name as 醫生姓名, p.result_status , fp.followup_fact_time, fp.OPERATOR_NAME as username, fp.TASK_STATUS, fp.TEL_STATUS, fp.id as taskId, nvl2(ppid.count,ppid.count,0) as count from phyexam.PE_VISIT p join phyexam.PE_MASTER_INDEX pmi on p.authority_id = pmi.authority_id and p.pe_id = pmi.pe_id left join interface.pat_master_index ipmi on ipmi.authority_id=pmi.authority_id and ipmi.pid=pmi.patient_id   left join security.security_ihe_patient_id_list spl on spl.pid=ipmi.pid and spl.authority_id=ipmi.authority_id left join security.security_user_baseinfo sub on sub.id=spl.security_user_baseinfo_id left join (select a.authority_id,a.pe_id,a.pe_visit_id, nvl2(count(*),count(*),0) as count from phyexam.pe_result_dict a where a.abnormal_indicator ='H' group by a.authority_id,a.pe_id,a.pe_visit_id )ppid on ppid.authority_id=p.authority_id and ppid.pe_id=p.pe_id and ppid.pe_visit_id=p.pe_visit_id");
if(form.getDoctorType()!=null && form.getDoctorType().trim().equals("YES")){
sql.append(" left join (select ft.* from (select f.*, row_number() over(partition by f.visit_no,f.authority_id, f.pid order by f.followup_fact_time desc) rn")
.append(" from crm.crm_follow_up_record_main f, crm.callcenter_staff_id_list cl where f.followup_fact_time is not null and ( f.operator_id =cl.security_baseinfo_id or f.task_status='1') ");
if(form.getDeptCode()!=null && !"".equals(form.getDeptCode().trim())){
if(form.getDeptCode().trim().equals("0220") || form.getDeptCode().trim().equals("0209"))
sql.append(" and (cl.dept_code='0220' or cl.dept_code='0209')");
else
sql.append(" and cl.dept_code=:deptCodeDoc");
}
sql.append(" ) ft where rn = 1 and ft.followup_type = '2' ");

}else{
sql.append(" left join (select ft.* from (select f.*, row_number() over(partition by f.visit_no,f.authority_id,f.pid order by f.followup_fact_time desc) rn ")
.append(" from crm.crm_follow_up_record_main f where f.followup_fact_time is not null ) ft where rn = 1 and ft.followup_type = '2'");
}
sql.append(" ) fp on fp.authority_id=p.authority_id and fp.pid=p.pe_id and fp.visit_no=p.pe_visit_id")
.append(" where p.tenant_id=:tenantId and p.upload_flag=1");
if(form.getName()!=null && !form.getName().trim().equals("")){
sql.append(" and (sub.name like '%"+form.getName().trim()+"%' or sub.input_code like UPPER('%"+form.getName().trim()+"%') )");
}
if(form.getFollowupType()!=null && !form.getFollowupType().trim().equals("") && !form.getFollowupType().trim().equals("all") ){//0全部,1已隨訪,2未隨訪
if(form.getFollowupType().equals("0")){
sql.append(" and fp.task_status='0'");
}else if(form.getFollowupType().equals("1")){
sql.append(" and fp.task_status='1'");
}else{
sql.append(" and ((fp.task_status!='1' and fp.task_status!='0') or fp.task_status is null)");
}
}
if(form.getSource()!=null && !form.getSource().trim().equals("")){
sql.append(" and p.pe_source=:source");
}
if(form.getResultStatus()!=null && !form.getResultStatus().trim().equals("")){
sql.append(" and p.RESULT_STATUS=:resultStatus");
}

if(form.getStartTime()!=null && !form.getStartTime().trim().equals("")){
sql.append(" and p.pe_pre_date >=to_date(:startTime,'yyyy-MM-dd')");
}
if(form.getEndTime()!=null && !form.getEndTime().trim().equals("")){
sql.append(" and p.pe_pre_date <=to_date(:endTime,'yyyy-MM-dd')+1");
}
if(form.getPatientId()!=null && !"".equals(form.getPatientId().trim())){
sql.append(" and pmi.PATIENT_ID=:patientId");
}
sql.append(" order by p.pe_pre_date desc");
SQLQuery query=getSession().createSQLQuery(sql.toString());
if(form.getDeptCode()!=null && !"".equals(form.getDeptCode().trim()) && form.getDoctorType()!=null && form.getDoctorType().trim().equals("YES") && !form.getDeptCode().trim().equals("0220") && !form.getDeptCode().trim().equals("0209")){
query.setParameter("deptCodeDoc", form.getDeptCode().trim());
}
query.setParameter("tenantId", form.getTenantId());
if(form.getSource()!=null && !form.getSource().trim().equals("")){
query.setParameter("source", form.getSource().trim());
}
if(form.getResultStatus()!=null && !form.getResultStatus().trim().equals("")){
query.setParameter("resultStatus", form.getResultStatus().trim());
}
if(form.getStartTime()!=null && !form.getStartTime().trim().equals("")){
query.setParameter("startTime",form.getStartTime().trim());
}
if(form.getEndTime()!=null && !form.getEndTime().trim().equals("")){
query.setParameter("endTime",form.getEndTime().trim());
}

if(form.getPatientId()!=null && !"".equals(form.getPatientId().trim())){
query.setParameter("patientId", form.getPatientId().trim());
}
if(form.getPage()!=-1){
query.setMaxResults(form.getSIZE());
query.setFirstResult((form.getPage()-1)*form.getSIZE());
}
return query.list();

本地運行正確,但是在雲端的就提示ORD-01722,無效數字,既然提示了,那沒辦法只能硬着頭皮找原因了,初步分析原因如下:

1、參數類型賦值錯誤

2、參數賦值順序不對

3、參數賦值個數不對

然后就跟着這3個原因一個一個的排查,可找了半天發現這3個原因都不是錯誤的產生,沒法,只能跟着日志文件往上在看看,這一看我就蒙了,因為在該sql語句執行之前還執行了一個sql語句 select count(*) from ......

后邊的都是一樣的,相信一般的朋友應該還是曉得是啥子意思,那么看到這里我就開始天窗似的猜想,同樣的語句只有查詢內容不一樣,那么也就是說問題是出在查詢的內容當中,那么哪個內容會出現數據的轉換呢?看了一圈目標鎖定:

1、nvl2(ppid.count,ppid.count,0)

2、nvl2(count(*),count(*),0)

為了先驗證是不是這兩個原因,我就把這兩個字段直接換為0,結果真的就沒問題了(是拿雲端庫部署測試的,為了測試可是犧牲了我的美容時間@_@),那么對於這兩個原因我就納悶了,因為最總其實都是指向nvl2(count(*),count(*),0),那么這個函數怎么會出現無效數字呢?原因指向->count(*)

跟網上看了一些朋友給出的結論,當然是根據他們遇到的情況表示的,說是在這個表里邊有某個字段進行了隱形轉換,將字符串轉換為了數字,

‘1’轉換為1肯定沒有問題,但是‘1A’ 想要轉換為數字肯定就不對了,所以就會提示無效數字,當時想了一下覺得還挺對,后來也針對這個問題請教了我們老大,老大就說了一句會不會存在NULL的情況,就是說count(*)查詢出來后有一個值為NULL,因為nvl2判斷的是“”不是NULL,至於是不是這個原因目前還沒搞清楚,不過先把問題的思路放在這里,希望有相同情況的朋友可以參考,討論,當然更重要的是或許哪天我就會把他解決了(^_^)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM