最近遇到SQL Server的密码包含特殊字符,导致连接串连接失败。最初遇到的是包含了一个分号“;”, 通过微软官方文档得到了以下解决方法:
- Why happen the issue
Because now we're using ";" to split the SQL connection string when parsing string. So if password include a semicolon ";", it will as the split character. - Resolve way
- I find there is a class "SqlConnectionStringBuilder" in the library "System.Data.SqlClient". It can auto deal with special character for password.
- I already tested it can work.
刚以为很开心这么快解决了问题,原来新的挑战已经默默的打开。BCP导出数据库数据失败,这个问题一直研究了好久,花费时间搜了不少资料,特此记录一下。
1. 首先考虑是分号“;”
找到一篇有用的文章:Is BCP able to connect db with semicolon in the password - Microsoft Q&A
需要用一对花括号{}把密码括起来,比如:
bcp tempdb.sys.objects out slask.bcp -n -U hulda -P "{semi;colon}"
测试可以工作。
2. 其次考虑是花括号{},因为毕竟处理分号时需要加入花括号,那要是密码里面也有花括号,肯定得额外处理了。
测试密码:Sz ~`!@#$%^&*()-_+=|/\:'?,{}[]<>.;
这个密码耗费我不少时间,搜了无数资料,总是测试失败,后来找到一篇有用的文章,算是解决了.
文中有位牛人提到:
gordthompson commented on May 28, 2022
Additional: If the first character is
{
and the password also contains}
then the}
characters need to be doubled-up.Login name:
larry
Password:{M}0e
requires
UID=larry;PWD={{M}}0e};
gordthompson commented on May 28, 2022
So that would be
def odbc_escape(thing): return ( "{" + thing.replace("}", "}}") + "}" if thing.startswith("{") else thing ) print(odbc_escape("{M0e")) # {{M0e} print(odbc_escape("M0e{")) # M0e{ print(odbc_escape("{M}0e")) # {{M}}0e}
看完这段说明,终于绕出了这个坑,之前都是把 { 和 } 都double处理了,结果一直失败,现在知道了,只需要将后花括号}额外处理即可。
所以我上面的密码用BCP运行如下命令即可成功:
bcp.exe "DECLARE @colnames VARCHAR(max); SELECT @colnames = COALESCE(@colnames + ',', '') + COLUMN_NAME FROM [ScreenbeamCmsReceiverLog].INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'DEV_ReceiverLog' ORDER BY ORDINAL_POSITION; SELECT @colnames;" queryout "E:\test.csv" -c -t -S 192.168.7.209 -U sa -P "{Sz ~`!@#$%^&*()-_+=|/\:'?,{}}[]<>.;}"
总结:
a. SQL Server数据库密码有特殊字符时,请用一对花括号{}把密码包起来
b. 如果密码中包含后花括号}需要,需要用多加一个后花括号来转义,即:}}
c. 因为密码需要用双引号"包起来,所以如果密码中有双引号的话,也需要多加一个双引号来转义,即""