通過ORA錯誤反思sql語句規範
今天快下班的時候,有個開發的同事問我一個問題,說他在客戶端執行一條sql語句,裡面包含子查詢,如果單獨執行子查詢,會報"invalid identifier"的錯誤,但是整個sql語句一致性就沒有錯誤,而且資料的結果還是正確的,碰到這種問題,想必都是信心滿滿,越是奇怪越想探個究竟。
為了能夠簡單說明這個問題,我使用如下下面的語句來模擬一下。
select *from test1_customer where customer_id in (select customer_id from test2_customer where cycle_code>100);
執行這個語句沒有錯誤。
81 rows selected.
但是執行子查詢中的語句卻報出了ORA-00904的錯誤。
select customer_id from test2_customer where cycle_code>100
*
ERROR at line 1:
ORA-00904: "CYCLE_CODE": invalid identifier
檢視錶test2_customer的欄位,確實沒有發現cycle_code這個欄位,但是查詢竟然還是能夠執行。
原因只有一個,那個欄位就是從別的表中引用的。只有test1_customer
建表的語句如下:
create table test1_customer as select object_id customer_id,object_name customer_name, object_id cycle_code from user_objects;
create table test2_customer as select object_id customer_id,object_name customer_name, object_id bill_cycle from user_objects;
為了能夠簡單說明這個問題,我使用如下下面的語句來模擬一下。
select *from test1_customer where customer_id in (select customer_id from test2_customer where cycle_code>100);
執行這個語句沒有錯誤。
81 rows selected.
但是執行子查詢中的語句卻報出了ORA-00904的錯誤。
select customer_id from test2_customer where cycle_code>100
*
ERROR at line 1:
ORA-00904: "CYCLE_CODE": invalid identifier
檢視錶test2_customer的欄位,確實沒有發現cycle_code這個欄位,但是查詢竟然還是能夠執行。
原因只有一個,那個欄位就是從別的表中引用的。只有test1_customer
建表的語句如下:
create table test1_customer as select object_id customer_id,object_name customer_name, object_id cycle_code from user_objects;
create table test2_customer as select object_id customer_id,object_name customer_name, object_id bill_cycle from user_objects;
在子查詢中執行select customer_id from test2_customer where cycle_code>100,欄位cycle_code因為在test2_customer中不存在,於是會自動去引用test1_customer的欄位值,剛好匹配到了,就輸出了結果。
select *from test1_customer where customer_id in (select customer_id from test2_customer where cycle_code>100);
這個問題如果在複雜的場景中還是很難排查的,可能就因為一點點的小問題會導致資料的問題。
所以從這個問題可以反思我們在寫sql語句的時候還是需要一些基本的規範,這樣就不會導致一些模糊的定義,不明不白的問題。
當引用了多個表的時候最好還是給表起個簡單的別名,這樣在分析sql語句的時候也比較直觀和方便。
上面的查詢可以簡單的修改為:
select *from test1_customer t1 where t1.customer_id in (select t2.customer_id from test2_customer t2 where t2.bill_cycle>100);
如果有問題的話,也能夠很快定位倒底是哪裡出了問題。
SQL> select *from test1_customer t1 where t1.customer_id in (select t2.customer_id from test2_customer t2 where t2.cycle_code>100);
select *from test1_customer t1 where t1.customer_id in (select t2.customer_id from test2_customer t2 where t2.cycle_code>100)
*
ERROR at line 1:
ORA-00904: "T2"."CYCLE_CODE": invalid identifier
引申一下,在建立表,索引,序列的時候也都可以通過規範的命名規則,這樣自己也很方便檢視。
比如
ACCOUNT_PK就代表是一個主鍵索引,
ACCOUNT_1UQ就是一個唯一性索引
ACCO_COMPANY_CODE_NN 就代表欄位COMPANY_CODE是一個not null 約束
select *from test1_customer where customer_id in (select customer_id from test2_customer where cycle_code>100);
這個問題如果在複雜的場景中還是很難排查的,可能就因為一點點的小問題會導致資料的問題。
所以從這個問題可以反思我們在寫sql語句的時候還是需要一些基本的規範,這樣就不會導致一些模糊的定義,不明不白的問題。
當引用了多個表的時候最好還是給表起個簡單的別名,這樣在分析sql語句的時候也比較直觀和方便。
上面的查詢可以簡單的修改為:
select *from test1_customer t1 where t1.customer_id in (select t2.customer_id from test2_customer t2 where t2.bill_cycle>100);
如果有問題的話,也能夠很快定位倒底是哪裡出了問題。
SQL> select *from test1_customer t1 where t1.customer_id in (select t2.customer_id from test2_customer t2 where t2.cycle_code>100);
select *from test1_customer t1 where t1.customer_id in (select t2.customer_id from test2_customer t2 where t2.cycle_code>100)
*
ERROR at line 1:
ORA-00904: "T2"."CYCLE_CODE": invalid identifier
引申一下,在建立表,索引,序列的時候也都可以通過規範的命名規則,這樣自己也很方便檢視。
比如
ACCOUNT_PK就代表是一個主鍵索引,
ACCOUNT_1UQ就是一個唯一性索引
ACCO_COMPANY_CODE_NN 就代表欄位COMPANY_CODE是一個not null 約束
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23718752/viewspace-1431617/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 透過ORA錯誤反思sql語句規範SQL
- sql語句錯誤SQL
- SQL語句規範總結SQL
- SQL語句規範的寫法SQL
- 通過sql語句分析足彩SQL
- 一個SQL語句引發的ORA-00600錯誤排查(二)SQL
- 一個SQL語句引發的ORA-00600錯誤排查(一)SQL
- 通過分析SQL語句的執行計劃優化SQL語句SQL優化
- merge語句導致的ORA錯誤分析
- oracle 通過sql profile為sql語句加hintOracleSQL
- 通過SQL PROFILE自動優化SQL語句SQL優化
- 一次sql語句優化的反思SQL優化
- 通過sql跟蹤解決ORA-00942錯誤一例SQL
- ORACLE 通過SPM為SQL語句加HINTOracleSQL
- 通過java來格式化sql語句JavaSQL
- 通過使用hint unnest調優sql語句SQL
- 依據錯誤號來跟蹤sql語句SQL
- 執行SQL語句遇到3113錯誤SQL
- 通過sql語句分析足彩(第三篇)SQL
- 通過錯誤的sql來測試推理sql的解析過程SQL
- 通過儲存過程執行通過DBLINK的查詢語句失敗-單個語句成功--ORA-00604儲存過程
- 通過SQL語句提取儲存過程中的內容SQL儲存過程
- MySQL_通過binlog檢視原始SQL語句MySql
- 通過java程式抽取日誌中的sql語句JavaSQL
- 用 Phoenix 通過 SQL 語句更新操作 HBase 資料SQL
- 通過錯誤的sql來測試推理sql的解析過程(二)SQL
- 通過分析SQL語句的執行計劃優化SQL 二SQL優化
- MySQL在ROW模式下通過binlog提取SQL語句MySql模式
- 通過圖表簡化sql語句的表關聯SQL
- 通過分析SQL語句的執行計劃優化SQL(總結)SQL優化
- sql 儲存過程命名規範SQL儲存過程
- 規範 API 介面錯誤響應格式API
- 通過Linux命令過濾出binlog中完整的SQL語句LinuxSQL
- SQL語句與正規表示式SQL
- 透過sql語句分析足彩SQL
- 通過日誌檢視mysql正在執行的SQL語句MySql
- 【轉】通過sql語句獲取資料庫的基本資訊SQL資料庫
- hibernate在JPA規範中在控制檯無法出現SQL語句SQL