MS Access更新SQL查询速度非常慢,并且已更新的记录数量相乘

时间:2016-07-18 22:23:35

标签: sql ms-access access-vba

我对如何更高效/正确地运行此查询感到困惑。首先是查询,然后我可以描述所涉及的表:

 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,但我必须使用LyFinalCode629Formerly632的项目映射到新代码。合理?这就是631有一个630的原因。此外,ON是一个字符串,IIF是一个整数...有趣。

无论如何,当你运行查询时,它说再次更新1807条记录,只有200条记录,只有99条符合标准。

有关此情况或如何解决问题的任何建议?

1 个答案:

答案 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。)