oracle的userenv和nls_lang詳解
1、userenv最常見的使用
userenv函式回傳當前會話(session)的相關資訊,以下sql陳述句可以查詢當前會話連接的資料庫字符集
select userenv('language') from dual;
有關userenv('parameter')回傳值的官網介紹如下

意思就是:回傳的是當前會話使用的language和territory,characterset是資料庫的字符集,
下面我們就去驗證這種情況
2、windows上plsql使用userenv
先看下資料庫真實的語言、地區和字符集

再看下windows上NLS_LANG環境變數

最后看下plsql上userenv執行的結果

可以發現在windows上使用plsql的時候語言和地區使用的是plsql的環境變數NLS_LANG,
3、Linux上sqlplus使用userenv
首先看一下NLS_LANG為空的情況下userenv的回傳值

可以看到userenv('language')的回傳值是AMERICAN_AMERICA.ZHS16GBK,這個值是怎么來的呢?從Oracle官網上看是取的默認值,如下圖

- 如果Oracle通用安裝程式沒有指定NLS_LANG,則默認值是
AMERICAN_AMERICA.US7ASCII - 如果language沒有指定,則language的默認值是
AMERICAN - 如果territory沒有指定,則territory的默認值由language這個值派生而來,
- 如果charset沒有指定,則在創建session的時候charset的值是資料庫的characterset,
- NLS_LANG的每一個component都是可選的,如果只想指定NLS_LANG的territory,那么需要這樣指定:
NLS_LANG=_JAPAN,此時territory的值是JAPAN
具體參見:Choosing a Locale with the NLS_LANG Environment Variable
下面繼續驗證

可以看到指定NLS_LANG之后,userenv('language')從會話中取得的語言和地區發生了變化,但是字符集仍然取得的是資料庫的字符集,
4、問題:中文亂碼在哪個環節產生的?
由以上分析可知,不管是什么樣的客戶端程式(不管是plsql還是sqlplus),在創建會話的時候字符都是取資料庫本身的字符集,因此客戶端程式和session的字符集不一致的時候會產生轉碼,如果轉碼的程序中出現了位元組損失,則存盤的真實資料就是損失之后的資料,至于我們看到的亂碼是因為存盤的資料會在查詢的時候再次轉碼成客戶端程式的字符集,由于資料缺失,因此就亂碼了,
至于中文亂碼的驗證可以參見【字符集】論Oracle字符集“轉碼”程序
記得幫我點贊哦!
精心整理了計算機各個方向的從入門、進階、實戰的視頻課程和電子書,按照目錄合理分類,總能找到你需要的學習資料,還在等什么?快去關注下載吧!!!

念念不忘,必有回響,小伙伴們幫我點個贊吧,非常感謝,
我是職場亮哥,YY高級軟體工程師、四年作業經驗,拒絕咸魚爭當龍頭的斜杠程式員,
聽我說,進步多,程式人生一把梭
如果有幸能幫到你,請幫我點個【贊】,給個關注,如果能順帶評論給個鼓勵,將不勝感激,
職場亮哥文章串列:更多文章

本人所有文章、回答都與著作權保護平臺有合作,著作權歸職場亮哥所有,未經授權,轉載必究!
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/106702.html
標籤:其他
上一篇:WEB 應用快取決議以及使用 Redis 實作分布式快取
下一篇:MySQL主從不生效且無錯誤
