我正在为c#中的sql选择查询。尝试使用SqlParameter
,但是当我调试时,我抛出异常:
必须声明标量变量“@ p1”。
我将via文本框中的值传递给类Customer
中的属性。这就是我的事件处理程序:
var newCustomer = new Customer();
newCustomer.FirstName = textBoxFirstName.Text;
newCustomer.LastName = textBoxLastName.Text;
newCustomer.Address = textBoxAddress.Text;
newCustomer.City = textBoxCity.Text;
newCustomer.State = textBoxState.Text;
newCustomer.Zip = Int32.Parse(textBoxZip.Text);
newCustomer.Phone = Int64.Parse(textBoxPhone1.Text);
newCustomer.Notes = textBoxNotes.Text;
var crochetDataHandler = new CrochetDataHandler();
crochetDataHandler.InsertNewCustomer(newCustomer);
这就是我打电话的方法:
public void InsertNewCustomer(Customer customer)
{
var insertCustomerString =
"Insert into Customer1 (FirstName, LastName, Address, City, State, Zip, Phone, Notes) Values (@p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8)";
SqlCommand newCust = new SqlCommand(insertCustomerString);
newCust.Parameters.Add(new SqlParameter("@p1", customer.FirstName));
newCust.Parameters.Add(new SqlParameter("@p2", customer.LastName));
newCust.Parameters.Add(new SqlParameter("@p3", customer.Address));
newCust.Parameters.Add(new SqlParameter("@p4", customer.City));
newCust.Parameters.Add(new SqlParameter("@p5", customer.State));
newCust.Parameters.Add(new SqlParameter("@p6", customer.Zip));
newCust.Parameters.Add(new SqlParameter("@p7", customer.Phone));
newCust.Parameters.Add(new SqlParameter("@p8", customer.Notes));
newCust.CommandText.ToString();
InsertRecord(insertCustomerString);
我在其他问题中看到了SqlParameter
使用了一些不同的构造函数,但是当我尝试它们时,我得到了相同的异常。
答案 0 :(得分:4)
我不确定您的InsertRecord方法正在做什么,但是您将原始字符串insertCustomerString传递给它而不是您的SqlCommand对象。字符串对您对参数所做的事情一无所知,因此如果InsertRecord期望字符串知道参数的值,那么它将会失望。
答案 1 :(得分:0)
以下是如何操作。
此外,您不应该使用原始System.Data.SqlClient对象,您应该使用通用接口类型。
System.Data.IDbConnection idbc = new System.Data.SqlClient.SqlConnection("connectionstring");
System.Data.IDbCommand cmd = idbc.CreateCommand();
cmd.CommandText = "INSERT INTO Customer1 (FirstName, LastName, Address, City, State, Zip, Phone, Notes) Values (@p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8)";
System.Data.IDbDataParameter parm = cmd.CreateParameter();
parm.DbType = System.Data.DbType.AnsiString;
parm.ParameterName = "@p1";
parm.Value = "ValueOfP1";
cmd.Parameters.Add(parm);
// etc.
if(cmd.Connection.State != System.Data.ConnectionState.Open)
cmd.Connection.Open();
cmd.ExecuteNonQuery();
if (cmd.Connection.State != System.Data.ConnectionState.Closed)
cmd.Connection.Close();
此外,您应该使用并锁定所有有价值的对象;)
using (System.Data.IDbConnection idbc = new System.Data.SqlClient.SqlConnection("connectionstring"))
{
lock (idbc)
{
using (System.Data.IDbCommand cmd = idbc.CreateCommand())
{
lock (cmd)
{
cmd.CommandText = "INSERT INTO Customer1 (FirstName, LastName, Address, City, State, Zip, Phone, Notes) Values (@p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8)";
System.Data.IDbDataParameter parm = cmd.CreateParameter();
parm.DbType = System.Data.DbType.AnsiString;
parm.ParameterName = "@p1";
parm.Value = "ValueOfP1";
cmd.Parameters.Add(parm);
//
if (cmd.Connection.State != System.Data.ConnectionState.Open)
cmd.Connection.Open();
cmd.ExecuteNonQuery();
if (cmd.Connection.State != System.Data.ConnectionState.Closed)
cmd.Connection.Close();
}
}
}
}
作为奖励评论,您不应该使用新的System.Data.SqlClient.SqlConnection, 相反,你应该使用像:
这样的工厂类型System.Data.Common.DbProviderFactory fac = System.Data.Common.DbProviderFactories.GetFactory("System.Data.SqlClient");
System.Data.IDbConnection idbc = fac.CreateConnection();
idbc.ConnectionString = "ConnectionString";
此外,您可以自动将值映射到相应的sql类型:
// From Type to DBType
protected virtual System.Data.DbType GetDbType(Type type)
{
// http://social.msdn.microsoft.com/Forums/en/winforms/thread/c6f3ab91-2198-402a-9a18-66ce442333a6
string strTypeName = type.Name;
System.Data.DbType DBtype = System.Data.DbType.String; // default value
try
{
if (object.ReferenceEquals(type, typeof(System.DBNull)))
{
return DBtype;
}
if (object.ReferenceEquals(type, typeof(System.Byte[])))
{
return System.Data.DbType.Binary;
}
DBtype = (System.Data.DbType)Enum.Parse(typeof(System.Data.DbType), strTypeName, true);
// Es ist keine Zuordnung von DbType UInt64 zu einem bekannten SqlDbType vorhanden.
// http://msdn.microsoft.com/en-us/library/bbw6zyha(v=vs.71).aspx
if (DBtype == System.Data.DbType.UInt64)
DBtype = System.Data.DbType.Int64;
}
catch (Exception)
{
// add error handling to suit your taste
}
return DBtype;
} // End Function GetDbType
public virtual System.Data.IDbDataParameter AddParameter(System.Data.IDbCommand command, string strParameterName, object objValue)
{
return AddParameter(command, strParameterName, objValue, System.Data.ParameterDirection.Input);
} // End Function AddParameter
public virtual System.Data.IDbDataParameter AddParameter(System.Data.IDbCommand command, string strParameterName, object objValue, System.Data.ParameterDirection pad)
{
if (objValue == null)
{
//throw new ArgumentNullException("objValue");
objValue = System.DBNull.Value;
} // End if (objValue == null)
System.Type tDataType = objValue.GetType();
System.Data.DbType dbType = GetDbType(tDataType);
return AddParameter(command, strParameterName, objValue, pad, dbType);
} // End Function AddParameter
public virtual System.Data.IDbDataParameter AddParameter(System.Data.IDbCommand command, string strParameterName, object objValue, System.Data.ParameterDirection pad, System.Data.DbType dbType)
{
System.Data.IDbDataParameter parameter = command.CreateParameter();
if (!strParameterName.StartsWith("@"))
{
strParameterName = "@" + strParameterName;
} // End if (!strParameterName.StartsWith("@"))
parameter.ParameterName = strParameterName;
parameter.DbType = dbType;
parameter.Direction = pad;
// Es ist keine Zuordnung von DbType UInt64 zu einem bekannten SqlDbType vorhanden.
// No association DbType UInt64 to a known SqlDbType
if (objValue == null)
parameter.Value = System.DBNull.Value;
else
parameter.Value = objValue;
command.Parameters.Add(parameter);
return parameter;
} // End Function AddParameter
public virtual T GetParameterValue<T>(System.Data.IDbCommand idbc, string strParameterName)
{
if (!strParameterName.StartsWith("@"))
{
strParameterName = "@" + strParameterName;
}
return InlineTypeAssignHelper<T>(((System.Data.IDbDataParameter)idbc.Parameters[strParameterName]).Value);
} // End Function GetParameterValue<T>
如果你这样做,你可以继续使用所有ado.net数据库提供程序,并且只需要在更改数据库类型时调整getfactory和sql代码中的字符串。
如果按照自己的方式进行操作,首先必须大幅更改代码,然后才能更改sql。