C#SqlParameters短手
我正在获取Record
对象List
的数据并将其内容放入数据库中:
// Processes a Record and adds it to the database public bool addRecord(SqlConnection db, List recordsToAdd) { using (SqlCommand command = db.CreateCommand()) { foreach (Record record in recordsToAdd) { // Set the query command text command.CommandText = @"INSERT INTO SMDGROUP_STPRODMASTER (PRODCODE, TOTFREE, TOTPHYS, ITEMTYPE, PRODESC) VALUES ('@PRODCODE', '@TOTFREE', '@TOTPHYS', '@ITEMTYPE', '@PRODESC')"; SqlParameter param1 = new SqlParameter("@CURSTAT", record.curstat); SqlParameter param2 = new SqlParameter("@ITEMDESC", record.itemdesc); SqlParameter param3 = new SqlParameter("@PRODCODE", record.prodcode); SqlParameter param4 = new SqlParameter("@TOTFREE", record.totfree); SqlParameter param5 = new SqlParameter("@TOTPHYS", record.totphys); SqlParameter param6 = new SqlParameter("@ITEMTYPE", record.itemtype); SqlParameter param7 = new SqlParameter("@PRODESC", record.proddesc); command.Parameters.Add(param1); command.Parameters.Add(param2); command.Parameters.Add(param3); command.Parameters.Add(param4); command.Parameters.Add(param5); command.Parameters.Add(param6); command.Parameters.Add(param7); // Execute the query command.ExecuteNonQuery(); } return true; } }
这是我的Record类:
class Record { public string curstat { get; set; } public string itemtype { get; set; } public string itemdesc { get; set; } public string prodcode { get; set; } public string proddesc { get; set; } public string totfree { get; set; } public string totphys { get; set; } }
只是从查看代码,我感觉有一个更短的方法来实现这一点。
但其次,我甚至不确定我是否正确地完成了@PARAMETER
值的替换。
如果我查看command
的内容,它仍然显示带有@
参数的查询字符串。
另外,我在command.ExecuteNonQuery()
上收到此错误:
字符串或二进制数据将被截断。
该语句已终止。
所以,我的问题是:
- 是否有更短的方法来设置和添加多个参数到查询?
- 可能导致错误的原因是什么?
你有一个更大的构造函数:
command.Parameters.Add( "@CategoryName", SqlDbType.VarChar, 80).Value = "toasters";
使用AddWithValue方法将使代码更短一些:
command.Parameters.AddWithValue("@CURSTAT", record.curstat); //...
我做的有点不同。
我有一个扩展方法和一个静态方法来创建SqlParameters。
public static SqlParameter ToParam(this object v,string name){ return new SqlParameter(name,v); }
然后我做这样的事情:
var p = new List(); p.Add(record.curstat.ToParam("@curstat")); p.Add(record.itemdesc.ToParam("@itemdesc")); //etc... command.Parameters.AddRange(p.ToList());
String or binary data would be truncated.
很可能意味着您将太多字符放入VARCHAR字段之一。 即,如果您的列PRODDESC是VARCHAR(50),并且您尝试插入的字符串是70个字符,您将看到该错误。
其他人已经解决了执行参数的替代方法,因此您可以减少代码行。
对于较短的语法,可以使用SqlParameterCollection
类的AddRange
方法。 它的意思是:
command.Parameters.AddRange(new [] { new SqlParameter(...), new SqlParameter(...), new SqlParameter(...) });
您获得的错误表示字符串值不适合表列或参数,并且正在被截断。 与插入的数据相比,应检查列的长度,或使用SqlParameter
构造函数的另一个重载指定参数的长度。
关于错误,这是一个截断问题,即参数的长度比列可以容纳的长。 要解决此问题,请在传递参数时更具体,例如new SqlParameter("@MyParameter", SqlDbType.VarChar, 30)
。
就个人而言,我认为他们目前添加的参数如何可读并且能够完成工作并不会有任何问题。 但是,如果你想减少函数中的代码行,你可以使用@Royi建议的内容,或者只是将参数包装到另一个方法中。
如果要使用以下类:
Class MyParam { public string name {get;set;} public object value {get;set;} }
然后你可以有一个名为myParams的List并执行:
foreach(var p in myParams) command.Parameters.AddWithValue(p.name, p.value);
你显然必须以某种方式链接参数和值,并且没有办法解决这个问题。 但是如果你在类这样的类中执行它,那么实际执行该操作的代码只有一行。
我想是这个消息
String or binary data would be truncated. The statement has been terminated.
来自命令文本中的错误:在SQL查询中,参数(即使它们是字符串)也不需要引用。
用此替换命令
command.CommandText = @"INSERT INTO SMDGROUP_STPRODMASTER (PRODCODE, TOTFREE, TOTPHYS, ITEMTYPE, PRODESC) VALUES (@PRODCODE, @TOTFREE, @TOTPHYS, @ITEMTYPE, @PRODESC)";
为了缩短代码,我认为你可以在某个地方(例如在你的记录类或辅助类中)添加一个方法,该方法从记录对象创建一个参数数组,然后调用AddRange函数。 它应该保持这个function更清洁,你也可以在代码的其他部分使用它。