我正在尝试通过php将一些数据存储在SQL Server数据库中。
问题是特殊字符未正确转换。我的应用程序的字符集是iso-8859-1 而服务器使用的是windows-1252。
在插入之前手动转换数据没有帮助,似乎有一些 正在进行转换。
运行SQL查询'set char_convert off'也无济于事。
任何人都知道如何才能让它发挥作用?
编辑:我试过ini_set('mssql.charset','windows-1252');同样,但也没有结果。
答案 0 :(得分:23)
客户端字符集是必要的,但还不够:
ini_set('mssql.charset', 'UTF-8');
我搜索了两天如何通过PHP将UTF-8数据(从Web表单)插入到MSSQL 2008中。我到处读到你不能,你需要先转换为UCS2(就像cypher的解决方案推荐的那样)。 在Windows上,SQLSRV被认为是一个很好的解决方案,我无法尝试,因为我在Mac OSX上进行开发。
但是,FreeTDS手册(PHP mssql在OSX上使用的内容)说在开头引号之前添加一个字母“N”:
mssql_query("INSERT INTO table (nvarcharField) VALUES (N'űáúőűá球最大的采购批发平台')", +xon);
根据此讨论,N字符告诉服务器转换为Unicode。 https://softwareengineering.stackexchange.com/questions/155859/why-do-we-need-to-put-n-before-strings-in-microsoft-sql-server
答案 1 :(得分:5)
我建议看看以下几点:
ini_set('mssql.charset', 'utf-8');
,因为没有带charset参数的函数( connect,query 等)答案 2 :(得分:5)
我遇到了同样的问题而ini_set('mssql.charset', 'utf-8')
对我不起作用。
但是,它以大写形式工作:
ini_set('mssql.charset', 'UTF-8');
答案 3 :(得分:4)
如果您使用的是TDS协议版本7或更高版本,则通过线路的所有通信都将转换为UCS2。除非列是nvarchar或ntext,否则服务器将从UCS2转换为表或列排序规则设置的任何内容。您可以将UTF-8存储到常规varchar或文本中,您只需使用低于7的TDS协议版本,如6.0或4.2。这种方法的唯一缺点是你不能查询任何nvarchar,ntext或sys。*表(我认为你也不能做任何CAST()ing) - 因为服务器拒绝发送任何可能转换为UTF-8使用协议版本低于7的任何客户端。
使用TDS协议版本7或更高版本(大致相当于MSSQL 2005或更高版本)时,无法避免转换字符集。
答案 4 :(得分:4)
如果ini_set('mssql.charset', 'UTF-8');
没有帮助,并且您没有root权限来修改系统范围的freetds.conf
文件,请执行以下操作:
1。设置/your/local/freetds.conf
文件:
[sqlservername]
host=192.168.0.56
port=1433
tds version=7.0
client charset=UTF-8
2. 确保您的连接DSN使用的是服务器名,而不是IP:
'dsn' => 'dblib:host=sqlservername;dbname=yourdb
3. 使FreeTDS使用本地freetds.conf文件作为非虚拟用户从php脚本通过env变量:
putenv('FREETDSCONF=/your/local/freetds.conf');
答案 5 :(得分:2)
我在类似的情况下运行(使用PDO ODBD连接),使用以下代码在打印输出之前转换编码:
$data = mb_convert_encoding($data, 'ISO-8859-1', 'windows-1252');
我不得不手动设置源编码,因为mb_detect_encoding()
错误地将其报告为'ISO-8859-1'。
我的数据也被另一个应用程序存储在数据库中,所以我可能处于一种独特的情况,虽然我希望它有所帮助!
答案 6 :(得分:2)
编辑此文件:
/etc/freetds/freetds.conf
...以及更改/设置版本'参数为' 7.0'帮助。编辑freetds.conf并尝试为服务器配置(或全局)更改此参数
即使没有重启apache也能正常工作。
答案 7 :(得分:1)
在我的情况下,在我将“ CharacterSet”参数添加到sqlsrv_connect()
连接的选项中后,它起作用了。
$connectionInfo = array(
"Database"=>$DBNAME,
"ConnectionPooling"=>0,
"CharacterSet"=>"UTF-8"
);
$LAST_CONNECTION = sqlsrv_connect($DBSERVER, $connectionInfo);
在此处查看文档: https://docs.microsoft.com/en-us/sql/connect/php/connection-options?view=sql-server-2017
答案 8 :(得分:0)
您不能只将表格转换为应用程序编码吗?或者在两者中使用utf-8?
我不知道MSSQL是否支持表级编码。
此外,如果上述操作失败,请尝试MB(多字节)字符串函数。
答案 9 :(得分:0)
您应该在连接之前使用 ini_set('mssql.charset','windows-1252')设置charset。如果你在 mssql_connect 之后使用它它没有效果。
答案 10 :(得分:0)
在我的案例中添加ini_set('mssql.charset', 'UTF-8');
并没有帮助我。我必须在列上指定UTF-8字符集:
$age = 30;
$name = utf8_encode("Joe");
$select = sqlsrv_query($conn, "SELECT * FROM Users WHERE Age = ? AND Name = ?",
array(array($age), array($name, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING('UTF-8')));
答案 11 :(得分:0)
我没有注意到有人提到从MSSQL数据库转换结果的另一种方法。好用的旧iconv()
函数:
iconv (string $in_charset, string $out_charset, string $str): string;
就我而言,除获得结果外,其他所有方法都无法提供有意义的转换。当然,这是在解析查询结果的循环内完成的-从CP1251到UTF-8:
foreach ($records as $row=>$col) {
$array[$row]['StatusName'] = iconv ('CP1251', 'UTF-8' , $records[$row]['StatusName']);
}
丑陋,但是可行。
答案 12 :(得分:-4)
您可以使用mysql_set_charset函数: http://it2.php.net/manual/en/function.mysql-set-charset.php