SQL Server导出数据管道导入MariaDB报错,MySQL正常的解决求助
这个场景我之前碰到过类似的,核心问题其实不是数据库配置,而是管道传输过程中编码的隐性不匹配——虽然你数据库层面的字符集、排序规则都对齐了,但SQLCMD输出的Latin1字节流,在通过Cygwin管道传给MariaDB的mysql客户端时,客户端没正确识别这个编码,导致字符转换失败;而存成文件后,文件的编码信息(或者MariaDB读取文件时的自动检测)帮你规避了这个问题。
下面是几个不用生成10GB大文件的解决方案,按优先级排序:
1. 直接指定mysql客户端的输入编码
最简单的方法,调用mysql.exe时明确告诉它输入是Latin1编码,和SQL Server的排序规则对应:
sqlcmd -S your_sqlserver_instance -d target_db -Q "YOUR_SELECT_QUERY_TO_GENERATE_INSERTS" -o - | mysql -u mariadb_user -p target_mariadb_db --default-character-set=latin1
原理:SQLCMD输出的是Latin1(ISO-8859-1)编码的字节流,让MariaDB客户端直接按这个编码解析输入,避免它自动检测错误。
2. 强制Cygwin环境的编码为Latin1
Cygwin的终端环境编码可能会影响管道传输的编码处理,先设置环境变量让整个管道链路的编码统一为Latin1:
export LC_ALL=en_US.iso8859-1 export LANG=en_US.iso8859-1 # 之后执行管道命令 sqlcmd -S your_sqlserver_instance -d target_db -Q "YOUR_SELECT_QUERY_TO_GENERATE_INSERTS" -o - | mysql -u mariadb_user -p target_mariadb_db
这样Cygwin会以Latin1编码传递管道数据,和SQLCMD的输出完全匹配,MariaDB客户端就能正确解析。
3. 用iconv做明确的编码中转(兜底方案)
如果上面两种方法都不行,可以用iconv在管道中间做强制编码转换,把SQLCMD的Latin1输出转成MariaDB常用的UTF-8(假设你数据库用的是utf8mb4):
sqlcmd -S your_sqlserver_instance -d target_db -Q "YOUR_SELECT_QUERY_TO_GENERATE_INSERTS" -o - | iconv -f ISO-8859-1 -t UTF-8 | mysql -u mariadb_user -p target_mariadb_db --default-character-set=utf8mb4
这个方法相当于手动对齐两端的编码,完全规避自动检测的问题,稳定性最高。
补充:为什么存文件再导入就没问题?
当你把SQLCMD的输出存成文件时,文件本身会保留Latin1的编码标识(或者MariaDB的source命令会自动检测文件的编码),而管道传输是纯字节流,没有额外的编码标记,MariaDB客户端可能默认用了UTF-8去解析Latin1字节,导致部分特殊字符无法转换,触发1366错误。
内容的提问来源于stack exchange,提问作者Adam

