我对如何更高效/正确地运行此查询感到困惑。首先是查询,然后我可以描述所涉及的表:
An exception of type 'System.Data.SqlClient.SqlException' occurred in
System.Data.dll but was not handled in user code
Additional information: String or binary data would be truncated.
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
conn.Open();
cmd.CommandText = "SELECT MAX(EmpID) FROM EmpInfo";
SqlDataReader rdr = cmd.ExecuteReader();
rdr.Close();
// cmd.CommandText = "INSERT INTO EmpInfo(EmpYear,EmpStatus,LName,FName,JobTitle,EmpPay,EmpDoB,EmpSex,EmpAddr,EmpCity,EmpState,EmpZIP,EmpCountry,EmpEAddr,EmpTelNo,EmpMobileNo) values('" + EmpYear + "', 'Active', '" + regLname_text.Text + "', '" + regFname_text.Text + "', 'NULL', '" + PayType_cb.SelectedItem.ToString() + "', '" + regDob_dtp.Value.Date + "', '" + gender + "', '" + regAddr_text.Text + "', '" + regCity_text.Text + "', '" + regState_text.Text + "', '" + regZip_text.Text + "', '" + regCountry_text.Text + "', '" + regEmail_text + "', '" + regTel_text.Text + "', '" + regMob_text.Text + "')";
cmd.CommandText = "INSERT INTO EmpInfo(EmpYear,EmpStatus,LName,FName,JobTitle,EmpPay,EmpDoB,EmpSex,EmpAddr,EmpCity,EmpState,EmpZIP,EmpCountry,EmpEAddr,EmpTelNo,EmpMobileNo) values('" + EmpYear + "', 'Active', '" + regLname_text.Text + "', '" + regFname_text.Text + "', 'NULL', '" + PayType_cb.SelectedItem.ToString() + "', '" + regDob_dtp.Value.Date + "', '" + gender + "', '" + regAddr_text.Text + "', '" + regCity_text.Text + "', '" + regState_text.Text + "', '" + regZip_text.Text + "', '" + regCountry_text.Text + "', '" + regEmail_text + "', '" + regTel_text.Text + "', '" + regMob_text.Text + "')";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO AccountInfo(LName, FName, EmpTemplate,AccountType,EmpStatus) VALUES('" + regLname_text.Text + "','" + regFname_text.Text + "','" + template + "','" + AcctType_cb.SelectedItem.ToString() + "','Active')";
cmd.ExecuteNonQuery();
有200行数据,只有99行符合UPDATE agg_pivot_test AS p
LEFT JOIN jd_cleaning AS c
ON c.Formerly = IIF(c.Formerly LIKE '*or*', '*' & p.LyFinalCode & '*', CStr(p.LyFinalCode))
SET p.CyFinalCode = c.FinalCode
WHERE p.CyFinalCode IS NULL AND c.Formerly IS NOT NULL;
的条件。 agg_pivot_test
需要一些解释。这是WHERE p.CyFinalCode IS NULL
,因为有些天才决定使用JOIN
将去年的数据与今年的数据相关联。它是一个字符串,因为有时多个项目已合并为一个,因此他们使用"或" (例如,IIF
)。因此,如果我想匹配今年的数据,我必须使用Formerly
来匹配去年的632 or 631 or 630
。所以今年的代码可能是Formerly
,但我必须使用LyFinalCode
将629
,Formerly
或632
的项目映射到新代码。合理?这就是631
有一个630
的原因。此外,ON
是一个字符串,IIF
是一个整数...有趣。
无论如何,当你运行查询时,它说再次更新1807条记录,只有200条记录,只有99条符合标准。
有关此情况或如何解决问题的任何建议?
答案 0 :(得分:1)
一个有趣的问题。我以为我以前从来没有遇到过这样的事情。
我猜测发生的是CyFinalCode为空的行,连接语句多次匹配,因此连接表达式正在计算行匹配的笛卡尔积,这就是是行更新消息的基础。这看起来很奇怪,因为在更新语句中,当行匹配只应该是1:1时,我希望访问抱怨多行匹配。
我建议将查询(使用此连接)重写为select语句,并查看查询为您提供的输出方式;类似的东西:
SELECT p.*, c.*
FROM agg_pivot_test p LEFT JOIN jd_cleaning c
ON c.Formerly = IIF(c.Formerly LIKE '*or*', '*' & p.LyFinalCode & '*', CStr(p.LyFinalCode))
WHERE p.CyFinalCode IS NULL AND c.Formerly IS NOT NULL
我也倾向于建议改变" ...& p.LyFinalCode& ..."到" ...& CStr(p.LyFinalCode)& ..." - 虽然我不能真正理解为什么它应该有所作为。
我能想到的另一件事就是改变连接:(这不一定保证更好 - 尽管可能是这样)
UPDATE agg_pivot_test AS p LEFT JOIN jd_cleaning AS c
ON (c.Formerly = CStr(p.LyFinalCode) OR InStr(c.Formerly, CStr(p.LyFinalCode)) > 0)
(鉴于你的语句的语法,我假设这个sql在通过ODBC访问时运行;在这种情况下这应该没问题。如果我错了sql运行服务器端,你需要将InStr更改为SubString。)