oracle的userenv和nls_lang詳解

oracle的userenv和nls_lang詳解

一、userenv最多見的使用

userenv函數返回當前會話(session)的相關信息。如下sql語句能夠查詢當前會話鏈接的數據庫字符集linux

select userenv('language') from dual;

有關userenv('parameter')返回值的官網介紹以下程序員

意思就是:返回的是當前會話使用的language和territory。characterset是數據庫的字符集。sql

下面咱們就去驗證這種狀況數據庫

二、windows上plsql使用userenv

先看下數據庫真實的語言、地區和字符集windows

再看下windows上NLS_LANG環境變量session

最後看下plsql上userenv執行的結果oracle

能夠發如今windows上使用plsql的時候語言和地區使用的是plsql的環境變量NLS_LANG。ide

三、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')從會話中取得的語言和地區發生了變化,可是字符集仍然取得的是數據庫的字符集。

四、問題:中文亂碼在哪一個環節產生的?

由以上分析可知,無論是什麼樣的客戶端程序(無論是plsql仍是sqlplus),在建立會話的時候字符都是取數據庫自己的字符集。所以客戶端程序和session的字符集不一致的時候會產生轉碼。若是轉碼的過程當中出現了字節損失,則存儲的真實數據就是損失以後的數據。至於咱們看到的亂碼是由於存儲的數據會在查詢的時候再次轉碼成客戶端程序的字符集,因爲數據缺失,所以就亂碼了。

至於中文亂碼的驗證能夠參見【字符集】論Oracle字符集「轉碼」過程



記得幫我點贊哦!

精心整理了計算機各個方向的從入門、進階、實戰的視頻課程和電子書,按照目錄合理分類,總能找到你須要的學習資料,還在等什麼?快去關注下載吧!!!

resource-introduce

念念不忘,必有迴響,小夥伴們幫我點個贊吧,很是感謝。

我是職場亮哥,YY高級軟件工程師、四年工做經驗,拒絕鹹魚爭當龍頭的斜槓程序員。

聽我說,進步多,程序人生一把梭

若是有幸能幫到你,請幫我點個【贊】,給個關注,若是能順帶評論給個鼓勵,將不勝感激。

職場亮哥文章列表:更多文章

wechat-platform-guide-attention

本人全部文章、回答都與版權保護平臺有合做,著做權歸職場亮哥全部,未經受權,轉載必究!

相關文章
相關標籤/搜索