Sql Server 表中看不见的乱码

本文探讨了数据库中特殊字符导致的乱码问题,并通过具体的SQL操作和转换解决了这一问题。文章提供了详细的步骤,包括使用REPLACE和CONVERT函数来清除不可见字符和乱码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

因为已经改好了,测试没有实际示例,仅操作模拟说明:


 

某表中有一个字段如:

charTest(col Nvarchar(50))

 

 

表中某列有符号'',但是在前端查询出来是时候出现很多这种乱码符号:

'?', '??', '???'

 

将字段拷贝到studio来看,没发现有问题,前后都没有空格,都是正确的:

​​​​​​【hh

​【dd

​【ee

​【aa

 

但是连续的拷贝到同一行时,发现前后出现空字符了:

​​​​​​【hh】​    【hh】​    【hh

 

然后直接更新,去掉所有空格:

update dbo.charTestset col=LTRIM(RTRIM(charTest))

 

不行,在试:

update dbo.charTestset col=REPLACE(col,' ','')

 

还是不行,前面的符号一直去不掉将中间的符号及其空格取出查看长度:


可以看到,SELECT LEN('')看起来没有长度,但是却存在4个长度!

 


在查询SELECT LEN('​​​​   ')中,拷贝符号''前面的空字符。用ascii码查询,发现对应编码为63,再转换为字符,发现竟然是问号'?'!这就是在前端看到的乱码,也就是说空的字符中存在乱码,但是数据库中没看到!查看数据库编码和列的属性都是正常的!



尝试转换字符看一下,都显示出来了:

SELECT col,CONVERT(VARCHAR(100),col)FROM dbo.charTest

 

hh  ?hh

dd  ??dd

ee  ???ee

aa  ????aa



最终的解决办法:

先转换字符,再替换问号为空字符,更新回表中!

update dbo.charTestset col=REPLACE(CONVERT(VARCHAR(100),col),'?','')

 

 

这些再查看,已经不存在看不见的字符了!

SELECT col,CONVERT(VARCHAR(100),col)

FROM dbo.charTest

where col <>CONVERT(VARCHAR(100),col)


这里再给个具体示例:

--	drop table #test
create table #test(col nvarchar(10),coll varchar(10))

insert into #test(col,coll)
select 'AA▪BB','Q★Q'
union all
select N'AA▪BB',N'Q★Q'

select * from #test


可以看到,如果类型为的nvarchar,插入表时必须显式转换nvarchar类型,否则保存的就是乱码.
与上面的实际数据库例子中不同的是:这个示例可以看出转换的乱码





public function ReverseDeliveryFeeVerifyDo($yearMonth): bool { $monthTimeRange = $this->getMonthTimeRange($yearMonth); // 一次性查询出逆向配送费报价数据 避免重复查询数据库 $quoteList = QuoteModel::field('warehous,price')->select()->toArray(); $quoteMap = []; if (!empty($quoteList)) { $quoteMap = array_column($quoteList, 'price', 'warehous'); } else { //Log::warning('【逆向配送费核对仓库名称不匹配】--月份为:' . $yearMonth . "的费用核对匹配不到逆向配送费报价的仓库名称"); return false; } $status = true; // 初始化状态 $itemizationModel = new ItemizationModel(); $batchCount = 0; // 批次计数器 $reconnectInterval = 100; // 每100批重连一次 try { // 使用chunk方法分批处理数据,每批处理50条 ItemizationModel::whereBetween('business_time', [ $monthTimeRange['startTime'], $monthTimeRange['endTime'] ])->field('id,billing_amount,warehouse_name,theoretical_amount,fee_difference')->chunk(10, function ($items) use ($yearMonth, $quoteMap, &$status, $itemizationModel, &$batchCount, $reconnectInterval) { // 批次计数递增 $batchCount++; // 达到重连间隔时,重新连接数据库 if ($batchCount % $reconnectInterval === 0) { $this->reconnectDatabase(); //Log::info("【数据库重连】已处理{$batchCount}批,重新连接数据库"); } $batchData = []; foreach ($items as $item) { $itemData = $item->toArray(); // 转换为数组便于处理 if (!empty($itemData['warehouse_name']) && isset($quoteMap[$itemData['warehouse_name']])) { $itemData['theoretical_amount'] = $quoteMap[$itemData['warehouse_name']]; $itemData['fee_difference'] = $itemData['billing_amount'] - $quoteMap[$itemData['warehouse_name']]; } else { $itemData['theoretical_amount'] = ''; $itemData['fee_difference'] = ''; //Log::warning('【逆向配送费核对仓库名称不匹配】--月份为:' . $yearMonth . "的费用核对匹配不到逆向配送费报价的仓库名称,明细数据id为" . $itemData['id']); } $batchData[] = $itemData; unset($item, $itemData); // 释放单条数据内存 } // 使用模型批量更新 if (!empty($batchData)) { $itemizationModel->saveAll($batchData); } // 释放批次数据内存并触发垃圾回收 unset($items, $batchData); gc_collect_cycles(); }); } catch (\Exception $e) { print_r("报错了直接干死整个进程,具体报错信息如下:".$e->getMessage());die; //Log::error('【逆向配送费核对异常】--月份为' . $yearMonth . "的费用核对发生错误:" . $e->getMessage()); $status = false; } // 释放主函数中的大型变量 unset($quoteList, $quoteMap, $itemizationModel); gc_collect_cycles(); return $status; } /** * 数据库重连方法 */ private function reconnectDatabase() { try { $connection = \think\facade\Db::connect(); $connection->close(); $connection->connect(); } catch (\Exception $e) { print_r("数据库连接失败:".$e->getMessage());die; Log::error('【数据库重连失败】' . $e->getMessage()); } } | 我利用上面的代码读取mysql的数据然后进行逻辑运算然后再更新回去 100万的数据到了80万左右就会报错:SQLSTATE[HY000]: General error: 2006 MySQL server has gone away 错误 我的mysql的配置如下: [mysqld] #服务Id唯一 server-id = 1 port = 3306 log-error = /var/log/mysql/error.log # 只能用IP地址 skip_name_resolve # 数据库默认字符集 character-set-server = utf8 # 数据库字符集对应一些排序等规则 collation-server = utf8_general_ci # 设置client连接mysql时的字符集,防止乱码 init_connect='SET NAMES utf8' # 最大连接数 max_connections = 10000 # 增加连接错误上限 max_connect_errors = 10000 # 服务器等待客户端请求的超时时间(秒),默认8小时 wait_timeout = 28800 # 交互式连接超时时间(秒),默认28800 interactive_timeout = 28800 # 关闭前等待活动的时间(秒),默认28800 net_read_timeout = 28800 net_write_timeout = 28800 我的php.ini里设置如下: post_max_size = 100M upload_max_filesize = 50M memory_limit = 1024M 我的nginx里面的设置如下: client_max_body_size 100M; client_body_buffer_size 1024k; proxy_connect_timeout 3600; # 与上游服务器的连接超时 proxy_read_timeout 3600; # 从上游服务器读取响应的超时 proxy_send_timeout 3600; # 发送请求到上游服务器的超时 fastcgi_connect_timeout 3600; fastcgi_read_timeout 3600; fastcgi_send_timeout 3600; 请帮我分析一下这到底是什么问题导致的呢?
最新发布
07-06
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值