當應用程式出現錯誤SQL,無法立即修改時,可以通過SQL映射功能,將錯誤的SQL映射為正確的SQL。SQL映射功能設定成功後,應用程式即使發送了錯誤的SQL,也會自動對應為正確的SQL。
注意事項
SQL映射功能會將字串匹配的SQL全部映射為指定的SQL,請謹慎使用。
前提條件
確保所在資料庫已建立polar_sql_mapping外掛程式, 新建立的資料庫預設已建立該外掛程式,舊的資料庫仍需手動建立。
執行以下命令,手動建立外掛程式。
set default_with_rowids to off;
create extension polar_sql_mapping;
使用指南
- 設定
polar_sql_mapping.use_sql_mapping
參數,開啟SQL映射功能,預設為off。alter database [dbname] set polar_sql_mapping.use_sql_mapping=on;
- 設定
polar_sql_mapping.record_error_sql
參數,開啟自動收集錯誤的SQL功能, 預設為off。alter database [dbname] set polar_sql_mapping.record_error_sql=on;
說明 使用完SQL映射功能之後建議關閉錯誤記錄功能,減少對效能的影響。alter database [dbname] set polar_sql_mapping.record_error_sql=off;
- 查詢錯誤的SQL。
返回結果如下:select * from emp;
ERROR: relation "emp" does not exist
- 錯誤的SQL被記錄到了polar_sql_mapping.error_sql_info中,執行以下命令,查詢polar_sql_mapping.error_sql_info詳細資料。
返回結果如下:select * from polar_sql_mapping.error_sql_info ;
id | query | emessage | calls ----+--------------------+-------------------------------+------- 1 | select * from emp; | relation "emp" does not exist | 1
- 建立映射關係,將error_sql_info中ID為1的SQL映射成指定的SQL。
select polar_sql_mapping.insert_mapping_id(1, ' select 1');
- 重新查詢錯誤的SQL。
返回結果如下:select * from emp;
?column? ---------- 1 (1 row)
說明 對於大部分的應用程式都是使用PreparedStmt,在寫新的SQL的時,需要注意預留位置應該是$n而不是'?',樣本如下:
返回結果如下:select * from polar_sql_mapping.polar_sql_mapping_table ;
id | source_sql | target_sql ----+----------------------------------+--------------------------------- 4 | select 1 from dual where a = $1; | select 1 from dual where 1 = $1 (1 row)
參數說明
參數 | 說明 |
polar_sql_mapping.max_num | 用於控制最多被收集的不同的錯誤SQL的數量,超過設定數量的SQL會直接被忽略,如果需要修改則需要重啟,預設值為10。 |
polar_sql_mapping.error_sql_info_clear() | 用於清空已記錄的錯誤SQL。 |
替換運行正常的SQL
如果遇到運行沒有錯誤的SQL,仍然想替換,可按照以下步驟進行操作:
- 設定
polar_sql_mapping.use_sql_mapping
參數,開啟SQL映射功能,預設為off。alter database [dbname] set polar_sql_mapping.use_sql_mapping=on;
- 設定
polar_sql_mapping.record_error_sql
參數,開啟自動收集錯誤的SQL功能, 預設為off。alter database [dbname] set polar_sql_mapping.record_error_sql=on;
說明 使用完SQL映射功能之後建議關閉錯誤記錄功能,減少對效能的影響。alter database [dbname] set polar_sql_mapping.record_error_sql=off;
- 設定匹配模式,所有模式比對的SQL都會被儲存到polar_sql_mapping.error_sql_info中。
在如下樣本中,即含有test_table的SQL都會被抓取(匹配邏輯和SQL中的LIKE操作符一致)。
- 設定匹配模式。
set polar_sql_mapping.error_pattern to '%test_table%';
- 開啟匹配模式。
set polar_sql_mapping.record_error_sql to true;
- 建立被抓取的SQL語句。
select * from test_table; select a from test_table; select max(a) from test_table;
- 查看polar_sql_mapping.error_sql_info中的抓取結果。
返回結果如下:select * from polar_sql_mapping.error_sql_info;
所有含有test_table的SQL都被抓取到了polar_sql_mapping.error_sql_info中。id | query | emessage | calls ----+--------------------------------+----------------------------+------- 1 | select * from test_table; | Error Pattern Force Record | 1 2 | select a from test_table; | Error Pattern Force Record | 1 3 | select max(a) from test_table; | Error Pattern Force Record | 1 (3 rows)
- 設定匹配模式。
- 將錯誤的SQL替換為正確的SQL。
select polar_sql_mapping.insert_mapping_id(x, 'text');
說明 其中,x表示SQL的ID,text表示SQL的文本,請根據實際情況進行替換。 - 使用完後需要進行還原作業,以免影響效能。
reset polar_sql_mapping.error_pattern;