SQL問題診斷
問題 診斷 使用者反應有一個員工不能設定他的考勤月曆了。補充說明,我們員工上班都是按週一到週五上班,朝8晚5下班,但也有上三天晚班休息兩天的上班制度,所以要設定
員工的上班制度。 而現在不能設定這個員工的上班制度了,那麼這個員工也沒法提交加班申請等操作了。而且快到工資結算的時候,如果不能及時提交考勤和加班等資訊,就會影響
最後的工資發放。要及時處理這個問題,只好和開發人員一起查詢正式系統上的日誌。還好和開發人員一起梳理邏輯,很快就找到了可能有問題的SQL. 但此SQL執行正常不知道為什麼會查詢出
不需要的員工資訊,這是查詢出了這個員工不符合要求,所以系統才刪除了這條不符合邏輯的資料。
這是DBA介入除錯此SQL,查詢錯誤查詢的原因。發現相關表中存在的資料如下
SELECT APPNT_DATE
,APPNT_CD
,APPNT_SEQ
,ACTI_STTS_CD
FROM MEMP_AP_APPNT_DET
WHERE ten_id='T01'
AND SITE_ID='EZ00'
AND EMP_ID = '2F4EE7C0599E11E0B358975729707EA8'
AND APPNT_DATE = '20180301';
APPNT_DATE APPNT_CD APPNT_SEQ ACTI_STTS_CD
20180301 AB 10 AA
20180301 DC 9 DA
20180301 YB 8 AA
而程式會對這個表的APPNT_SEQ值求最大值,以此找出這天裡員工的最後的狀態值
但SQL中的查詢條件是這樣的
AND R.APPNT_DATE||R.APPNT_SEQ = (SELECT MAX(X1.APPNT_DATE||X1.APPNT_SEQ)
FROM MEMP_AP_APPNT_DET X1
WHERE X1.TEN_ID = R.TEN_ID
AND X1.SITE_ID = R.SITE_ID
AND X1.EMP_ID = R.EMP_ID
AND X1.APPNT_DATE <= '20180329')
一看到|| 還做比較就感覺要出事,趕緊把這段SQL拿到生產環境執行了一把。查詢出的資料中有不想要的資料。於是在 R.APPNT_DATE||R.APPNT_SEQ前面加TO_NUMBER()
再執行不想要的資料不見了。這說明 R.APPNT_DATE||R.APPNT_SEQ拼出的結果是字元型別,這種字元型別比較後和數字型別比較是有區別的
比如201803019 > 2018030110 所以最大結果是201803019 , 而不是2018030110
最終修改後的SQL
SELECT N.TEN_ID
, ...
FROM TTNA_TBS_PERSN_MAS N
, MEMP_AP_APPNT_DET R -- CUR
, MEMP_AP_APPNT_DET S -- PAST
WHERE N.TEN_ID = 'T01'
AND N.SITE_ID = 'EZ00'
AND N.EMP_ID = N.EMP_ID--NVL('null', N.EMP_ID)
AND N.TEN_ID = R.TEN_ID
AND N.SITE_ID = R.SITE_ID
AND N.EMP_ID = R.EMP_ID
AND R.APPNT_DATE BETWEEN TO_CHAR(TO_DATE('20180329','YYYYMMDD')-100,'YYYYMMDD') AND '20180329'
...
AND TO_NUMBER(R.APPNT_DATE||R.APPNT_SEQ) = (SELECT MAX(TO_NUMBER(X1.APPNT_DATE||X1.APPNT_SEQ)) --update
FROM MEMP_AP_APPNT_DET X1
WHERE X1.TEN_ID = R.TEN_ID
AND X1.SITE_ID = R.SITE_ID
AND X1.EMP_ID = R.EMP_ID
AND X1.APPNT_DATE <= '20180329')
AND TO_NUMBER(R.APPNT_DATE||R.APPNT_SEQ) > TO_NUMBER(S.APPNT_DATE||S.APPNT_SEQ) --update
AND SUBSTR(NVL(R.ACTI_STTS_CD, ' '), 1, 1) <> SUBSTR(NVL(S.ACTI_STTS_CD, ' '), 1, 1) -- ?? ?? ??
AND TO_NUMBER(S.APPNT_DATE||S.APPNT_SEQ) = (SELECT MAX(TO_NUMBER(X2.APPNT_DATE||X2.APPNT_SEQ)) --update
FROM MEMP_AP_APPNT_DET X2
WHERE X2.TEN_ID = S.TEN_ID
AND X2.SITE_ID = S.SITE_ID
AND X2.EMP_ID = S.EMP_ID
AND X2.APPNT_DATE < R.APPNT_DATE)
...
總結 比較過程中字串的比較和數字型別的比較是有很大區別的。這裡不用過多的檢視業務的邏輯,畢竟生產環境下的SQL 執行有一定保證,除非在某些特殊情況有一定問題,那麼我們關注的是問題的細節,這裡就是技術的細節。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/750077/viewspace-2152616/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SQL Server database mail問題診斷一例SQLServerDatabaseAI
- 使用MTR命令診斷網路問題
- 診斷叢集的潛在問題
- Oracle診斷案例-Sql_traceOracleSQL
- 如何診斷和解決db2問題DB2
- 一次gc buffer busy問題的診斷GC
- 壓力測試事務率不高問題診斷
- JProfiler for Mac:提升效能和診斷問題的終極工具Mac
- 如何使用 dotTrace 來診斷 netcore 應用的效能問題NetCore
- 如何使用Apple診斷程式檢查Mac硬體問題APPMac
- 基於 PTS 壓測輕鬆玩轉問題診斷
- 詳解JAVA執行緒問題診斷工具Thread DumpJava執行緒thread
- 雲伺服器用MTR診斷Ubuntu網路問題方法伺服器Ubuntu
- 解密阿里線上問題診斷工具Arthas和jvm-sandbox解密阿里JVM
- 在Linux中,如何診斷和解決系統啟動問題?Linux
- 記一次使用gdb診斷gc問題全過程GC
- .記一次使用gdb診斷gc問題全過程GC
- 5種常見的 DNS 故障診斷及問題處理方法DNS
- 使用SQL_TRACE進行資料庫診斷(轉)SQL資料庫
- 使用 SOS 對 Linux 中執行的 .NET Core 進行問題診斷Linux
- Oracle如何診斷遠端訪問資料庫慢/超時等問題小結Oracle資料庫
- [JVM] 應用診斷工具之Fastthread(線上診斷)JVMASTthread
- ORACLE診斷案例Oracle
- 網路效能監控與流量回溯分析 - 輕鬆診斷網路問題
- Java診斷利器ArthasJava
- 這 8 類問題,SysOM 2.0 OOM 診斷助你快速定位異常 | 龍蜥技術OOM
- 免費網站seo診斷:從哪些維度進行診斷呢?網站
- 教程直播第7期|如何對 OceanBase 進行 SQL 診斷和調優SQL
- Oracle診斷事件列表(轉)Oracle事件
- Java執行緒診斷Java執行緒
- NetDiag 是一個由 Microsoft 提供的網路診斷工具,用於幫助管理員和使用者診斷和排除網路連線和配置方面的問題。它主要用於在 Windows 作業系統中分析和診斷與網路連線相關的問題,尤其是在 Active Directory 環境中的問題。ROSWindows作業系統
- PostgreSQL多查詢條件,多個索引的選擇演算法與問題診斷方法SQL索引演算法
- AI診斷心臟病比人類更準?但這只是識圖,不是診斷AI
- oracle之 redo過高診斷Oracle
- openGauss 支援WDR診斷報告
- 整車EOL 診斷系統
- Mac OSX網路診斷命令Mac
- 9 Oracle Data Guard 故障診斷Oracle