我有一个从SQL DB读取并写入MySQL的应用程序。此应用程序用于迁移客户端的数据。在测试时,我遇到了单个记录的问题而且我很难过。我已经在使用C#Encoding
类测试了本网站的各种建议,并且每次尝试将其转换为此单条记录都没有成功。
SQL排序规则为SQL_Latin1_General_CP1_CI_AS
MySQL排序规则为latin1_general_ci
,代码示例(在foreach
循环中)如下:
foreach(var pgObj in PgObjList)
{
//byte[] bytes = Encoding.Default.GetBytes(pgObj.Description);
//pgObj.Description = Encoding.ASCII.GetString(bytes);
byte[] utf8Bytes = Encoding.UTF8.GetBytes(pgObj.Description);
byte[] isoBytes = Encoding.Convert(Encoding.ASCII, Encoding.UTF8, utf8Bytes);
string uf8converted = Encoding.UTF8.GetString(isoBytes);
string insertSQL = @"INSERT INTO `mainsite`.`sf_root_items`
(`ID`,
`LoweredName`,
`MenuName`,
`Title`,
`Description`,
`PageType`,
`ExternalUrl`
)
VALUES
('" + pgObj.ID + @"',
'" + pgObj.LoweredName + @"',
'" + pgObj.MenuName + @"',
'" + pgObj.Title + @"',
'" + pgObj.Description + @"',
'" + pgObj.PageType + @"',
'" + pgObj.ExternalUrl + @"'
);";
string outputMsg;
// more code here to execute the MySQL statement
}
我得到的最好结果是转换为ASCII(注释代码)并将文本存储在看起来像汉字的内容中。没有例外但是当我以任何其他方式运行它时,我得到了这条记录的异常。
例外:
MySQL Exception on record#28/r/n
MySql.Data.MySqlClient.MySqlException (0x80004005): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'il vous plaît (RSVP)',
'0',
' at line 15
at MySql.Data.MySqlClient.MySqlStream.ReadPacket()
at MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int64& insertedId)
at MySql.Data.MySqlClient.Driver.GetResult(Int32 statementId, Int32& affectedRows, Int64& insertedId)
at MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId, Boolean force)
at MySql.Data.MySqlClient.MySqlDataReader.NextResult()
at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
at MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery()
at SharepointImportDL.SharepointContentImport.GetSitefinityContent.addRootItems(List`1 PgObjList, String WPConnectionString) in C:\Users\Administrator\Source\Repos\TestBinaryWriter\Test Binary Writer\SharepointImportDL\SharepointContentImport\GetSitefinityContent.cs:line 986
第986行是SQL执行:int output = cmd.ExecuteNonQuery();
值得注意的是,我插入的字符串来自nvarchar列(MSSQL)和varchar(MySQL)列
具有讽刺意味的是,字符串是一个简单的“Répondezs'ilvousplaît(RSVP)”(我想要打击那些不得不使用法语文本的自命不凡的人)所以我不太可能我会再遇到它,但显然我需要处理这种可能性。
答案 0 :(得分:0)
在构建SQL(pgObj.Description
)之前转义字符串(例如string insertSQL
)。否则,您会收到
, 'Répondez s'il vous plaît (RSVP)',
请注意单引号内是否有单引号?还要注意错误如何指出问题:
... syntax to use near 'il vous plaît (RSVP)',
答案 1 :(得分:0)
感谢Palle Due建议参数化查询,我决定在MySQL中编写一个存储过程来处理这些问题。
根据我原来的问题,我的C#代码如下:
foreach(var pgObj in PgObjList)
{
string SP = "sp_insert_root_items";
string outputMsg = "";
MySqlConnection myConnection = new MySqlConnection(WPConnectionString);
MySqlCommand cmd;
try
{
if (myConnection.State != ConnectionState.Open)
{
myConnection.Close();
myConnection.Open();
}
cmd = myConnection.CreateCommand();
cmd.CommandText = SP;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@ID", pgObj.ID);
cmd.Parameters["@ID"].Direction = ParameterDirection.Input;
cmd.Parameters.AddWithValue("@LoweredName", pgObj.LoweredName);
cmd.Parameters["@LoweredName"].Direction = ParameterDirection.Input;
cmd.Parameters.AddWithValue("@MenuName", pgObj.MenuName);
cmd.Parameters["@MenuName"].Direction = ParameterDirection.Input;
cmd.Parameters.AddWithValue("@Title", pgObj.Title);
cmd.Parameters["@Title"].Direction = ParameterDirection.Input;
cmd.Parameters.AddWithValue("@Description", pgObj.Description);
cmd.Parameters["@Description"].Direction = ParameterDirection.Input;
cmd.Parameters.AddWithValue("@PageType", pgObj.PageType);
cmd.Parameters["@PageType"].Direction = ParameterDirection.Input;
cmd.Parameters.AddWithValue("@ExternalUrl", pgObj.ExternalUrl);
cmd.Parameters["@ExternalUrl"].Direction = ParameterDirection.Input;
cmd.Parameters.AddWithValue("@ParentID", "");
cmd.Parameters["@ParentID"].Direction = ParameterDirection.Input;
int output = cmd.ExecuteNonQuery();
// a value greater than 0 means execution was successful
if (output > 0)
{
counter++;
//outputMsg = "Record #" + counter.ToString() + " created";
}
else
{
counter++;
outputMsg = "There was an error inserting record #" + counter.ToString();
}
myConnection.Close();
}
catch (Exception ex)
{
outputMsg = "MySQL Exception on record#" + counter.ToString() + "/r/n" + ex.ToString();
}
returnMsg += outputMsg;
}
存储过程的一个示例如下 - 它是从SQLYog导出的。
DELIMITER $$
/*!50003 CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_insert_root_items`(
IN ID VARCHAR(255),
IN LoweredName VARCHAR(255),
IN MenuName VARCHAR(255),
IN Title VARCHAR(255),
IN Description VARCHAR(500),
IN PageType VARCHAR(255),
IN ExternalUrl VARCHAR(255),
IN ParentID VARCHAR(255)
)
BEGIN
INSERT INTO `wp_sf_page_items`
(`ID`,
`LoweredName`,
`MenuName`,
`Title`,
`Description`,
`PageType`,
`ExternalUrl`,
`ParentID`
)
VALUES(ID, LoweredName, MenuName, Title, Description, PageType, ExternalUrl, ParentID);
END */$$
DELIMITER ;