Linux程序写入oralce数据库中文显示为问号???
1.问题介绍
根本原因是字符集的问题,是数据库的字符集和写入程序的linux系统的字符集不一致导致;
但是用export NLS_LANG=”SIMPLIFIED CHINESE”_CHINA.ZHS16GBK添加环境变量,或者在.bash_profile文件中添加这个环境变量,或者在/etc/profile文件中添加这个环境变量,用source 命令使其生效,后写入oralce数据库的中文还是问号?,接着有重启了系统,重启了服务器,让环境变量生效,还是显示问号;
2.正确的用代码设置字符集的方法
(1)在服务器端查看字符集的类型
用命令:select userenv(‘language‘) from dual 查看数据库的字符集类型是SIMPLIFIED CHINESE_CHINA.ZHS16GBK,注意显示中文末尾必须是ZHS16GBK;
(2)在写入数据库的程序中初始化的数据库之前采用下面的代码设置环境变量
char chValueName[] = "NLS_LANG";
string strLang="SIMPLIFIED CHINESE_CHINA.ZHS16GBK";//必须与数据库服务端的一致
int errorcode=setenv(chValueName, strLang.c_str(), 1);
if (errorcode!=0)
{
ERROR("linux setenv %s failed errorcode %d !",strLang.c_str(),errorcode);
}
else
{
INFO("linux setenv %s succeed !",strLang.c_str());
}
(3)编译程序,重新运行,就可以正常写入汉字到oracle数据库了;
3.字符集介绍
NLS_LANG格式:
NLS_LANG = language_territory.charset
有三个组成部分(语言、地域和字符集),每个成分控制了NLS子集的特性。其中:language
指定服务器消息的语言。
territory 指定服务器的日期和数字格式。
charset 指定字符集,只要这一个一致,就可以写入汉字到数据库,这个字段的值决定了字符转换格式,如果不一致,就会找不到字符,一个汉字就会显示为两个问号;
4.linux添加环境变量的几种方法
(1)直接在终端用命令添加,这个环境变量设置只在该终端窗口中有效,退出窗口就会失效;
export NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK
(2)在.bash_profile文件中添加,/etc/profile对所有用户生效,~/.bash_profile只对当前用户生效。用命令vi .bash_profile添加也是用export NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK
(3)在/etc/profile中添加,对所有的用户有效;修改完后需要用source命令使其生效;
vi /etc/profile
(4)使用shell脚本添加环境变量
if grep -Fxq "export NLS_LANG=\"SIMPLIFIED CHINESE\"_CHINA.ZHS16GBK" /etc/profile
then
echo " export NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK found"
else
echo " add NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK to file"
sed -i ‘$a export NLS_LANG=\"SIMPLIFIED CHINESE\"_CHINA.ZHS16GBK‘ /etc/profile
source /etc/profile
fi
5.windows下设置环境变量
char chValueName[] = "NLS_LANG";
string strLang=SIMPLIFIED CHINESE_CHINA.ZHS16GBK;
HKEY hKey = NULL;
DWORD dwDataLen = SMALL_LEN;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, “System\\CurrentControlSet\\Control\\Session Manager\\Environment”, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
{
DB_DEBUG("RegOpenKey %s fail, err:%ld", “System\\CurrentControlSet\\Control\\Session Manager\\Environment”, GetLastError());
break;
}
//先查看有没有环境变量
if (RegQueryValueEx(hKey, chValueName, NULL, NULL, (BYTE*)chData, &dwDataLen) == ERROR_SUCCESS)
{//如果已经设置且相同则返回
if (strLang.compare(chData) == HPR_OK)
{
RegCloseKey(hKey);
iRetVal = HPR_OK;
break;
}
}
RegCloseKey(hKey);
//如果没有设置或者不同,则重新设置;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, g_chRegEnvPath, 0, KEY_SET_VALUE, &hKey) != ERROR_SUCCESS)
{
break;
}
RegSetValueEx(hKey, chValueName, 0, REG_SZ, (const BYTE*)strLang.c_str(), strLang.length());
DWORD_PTR dwResult = 0;
//使立即生效
LRESULT lRet = SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, LPARAM("Environment"), SMTO_ABORTIFHUNG, 2000, &dwResult);
if (lRet != 0)
{
RegCloseKey(hKey);
DB_DEBUG("Change Oracle nls lang:%s to:%s success!", chData, strLang.c_str());
break;
}
DB_DEBUG("Change Oracle nls lang:%s to:%s failed!", chData, strLang.c_str());
RegCloseKey(hKey);