C# 参数化SQL查询
很多文章都是关于使用C#的SQL中的参数的,但我仍然缺少一些东西。我没有收到错误消息,但没有插入数据。少了什么?我有名为fname、lname、address、city、state和zip的文本框C# 参数化SQL查询,c#,.net,sql,tsql,ado.net,C#,.net,Sql,Tsql,Ado.net,很多文章都是关于使用C#的SQL中的参数的,但我仍然缺少一些东西。我没有收到错误消息,但没有插入数据。少了什么?我有名为fname、lname、address、city、state和zip的文本框 private void enter_button_Click(object sender, EventArgs e) { string first, last, addy, city1, stat, zippy; first = fname.Text; SqlParam
private void enter_button_Click(object sender, EventArgs e)
{
string first, last, addy, city1, stat, zippy;
first = fname.Text;
SqlParameter firstparam;
firstparam = new SqlParameter();
firstparam.ParameterName = "@first";
firstparam.Value = first;
last = lname.Text;
SqlParameter lastparam;
lastparam = new SqlParameter();
lastparam.ParameterName = "@last";
lastparam.Value = last;
addy = address.Text;
SqlParameter addressparam;
addressparam = new SqlParameter();
addressparam.ParameterName = "@addy";
addressparam.Value = addy;
city1 = city.Text;
SqlParameter cityparam;
cityparam = new SqlParameter();
cityparam.ParameterName = "@city1";
cityparam.Value = city1;
stat = state.Text;
SqlParameter stateparam;
stateparam = new SqlParameter();
stateparam.ParameterName = "@stat";
stateparam.Value = stat;
zippy = zip.Text;
SqlParameter zipparam;
zipparam = new SqlParameter();
zipparam.ParameterName = "@zippy";
zipparam.Value = zippy;
try
{
Validate(fname);
Validate(lname);
Validate(city);
Validate(state);
}
catch (Exception ex)
{
throw new Exception(ex.ToString(), ex);
}
try
{
exValidate(address);
}
catch (Exception ex1)
{
throw new Exception(ex1.ToString(), ex1);
}
try
{
numValidate(zip);
}
catch (Exception ex2)
{
throw new Exception(ex2.ToString(), ex2);
}
string connection = "Data Source=TX-MANAGER;Initial Catalog=Contacts;Integrated Security=True";
var sqlstring = string.Format("INSERT INTO Contacts ([First] ,[Last] ,[Address] ,[City] ,[State],[ZIP]) VALUES {0}, {1}, {2}, {3}, {4}, {5})", @first, @last, @addy, @city1, @stat, @zippy);
SqlConnection conn = new SqlConnection(connection);
SqlCommand comm = new SqlCommand();
comm.CommandText = sqlstring;
try
{
conn.Open();
//SqlTransaction trans = conn.BeginTransaction();
//comm.Transaction = trans;
comm.Parameters.Add("@first", SqlDbType.Text);
comm.Parameters.Add("@last", SqlDbType.Text);
comm.Parameters.Add("@addy", SqlDbType.Text);
comm.Parameters.Add("@city1", SqlDbType.Text);
comm.Parameters.Add("@stat", SqlDbType.Text);
comm.Parameters.Add("@zippy", SqlDbType.SmallInt);
}
catch (Exception commex)
{
throw new Exception(commex.ToString(), commex);
}
conn.Close();
}
所以我换了这个,但还是什么都没发生
string connection = "Data Source=TX-MANAGER;Initial Catalog=Contacts;Integrated Security=True";
var sqlstring = string.Format("INSERT INTO Contacts ([First] ,[Last] ,[Address] ,[City] ,[State],[ZIP]) VALUES {0}, {1}, {2}, {3}, {4}, {5})", @first, @last, @addy, @city1, @stat, @zippy);
SqlConnection conn = new SqlConnection(connection);
SqlCommand comm = conn.CreateCommand();
comm.CommandText = sqlstring;
try
{
conn.Open();
//SqlTransaction trans = conn.BeginTransaction();
//comm.Transaction = trans;
comm.Parameters.AddWithValue("@first", first);
comm.Parameters.AddWithValue("@last", last);
comm.Parameters.AddWithValue("@addy", addy);
comm.Parameters.AddWithValue("@city1", city1);
comm.Parameters.AddWithValue("@stat", stat);
comm.Parameters.AddWithValue("@zippy", zippy);
comm.ExecuteNonQuery();
您忘记执行命令;) 编辑:您也没有使用在方法开始时创建的参数
...
try
{
conn.Open();
//SqlTransaction trans = conn.BeginTransaction();
//comm.Transaction = trans;
comm.Parameters.Add(firstparam);
comm.Parameters.Add(lastparam);
comm.Parameters.Add(addressparam);
comm.Parameters.Add(cityparam);
comm.Parameters.Add(stateparam);
comm.Parameters.Add(zipparam);
// This is what you forgot:
comm.ExecuteNonQuery();
}
...
顺便说一句,不要这样做:
catch (Exception ex1)
{
throw new Exception(ex1.ToString(), ex1);
}
它没有用,只是添加了一个新的异常级别,没有添加任何有用的内容。只需让异常在堆栈中冒泡,直到它到达一个实际执行有用操作的catch块。有很多方法。其中一种方法是将try块中的行替换为:
comm.Parameters.AddWithValue("@first", first);
comm.Parameters.AddWithValue("@last", last);
comm.Parameters.AddWithValue("@addy", addy);
comm.Parameters.AddWithValue("@city1", city1);
comm.Parameters.AddWithValue("@stat", stat);
comm.Parameters.AddWithValue("@zippy", zippy);
如果这样做,就不需要所有的SqlParameter初始化
显然,您需要执行以下命令:
comm.ExecuteNonQuery();
这将大大缩短:
using (SqlConnection connection = new SqlConnection(connectionString))
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = "INSERT INTO Contacts ([First], [Last], [Address], [City], [State], [ZIP]) VALUES (@first, @last, @address, @city, @state, @zip)";
command.Parameters.AddWithValue("@first", first);
// or
// command.Parameters.Add("@first", SqlDbType.Type).Value = first;
// ...
connection.Open();
command.ExecuteNonQuery();
}
但首先,这里是你错过的:
comm.Parameters.Add(firstparam);
// instead of
// comm.Parameters.Add("@first", SqlDbType.Text);
及
首先,如果不执行该命令,则需要调用
comm.ExecuteNonQuery()代码>,其次,您的SQL字符串将出错。这一行:
var sqlstring = string.Format("INSERT INTO Contacts ([First] ,[Last] ,[Address] ,[City],
[State],[ZIP]) VALUES {0}, {1}, {2}, {3}, {4}, {5})", @first, @last, @addy, @city1,
@stat, @zippy)
可以是:
var sqlstring = "INSERT INTO Contacts ([First] ,[Last] ,[Address] ,[City] ,[State],[ZIP])
VALUES (@first, @last, @addy, @city1, @stat, @zippy)";
第三,您实际上没有将参数添加到命令中。您可以这样创建一个参数:
SqlParameter zipparam;
zipparam = new SqlParameter();
zipparam.ParameterName = "@zippy";
zipparam.Value = zippy;
但您要添加以下内容:
comm.Parameters.Add("@zippy", SqlDbType.SmallInt);
不参考zipparam
。这意味着值zippy
从未实际添加到命令中。您可以使用以下方法在一行中完成这一切:
comm.Parameters.Add(new SqlParameter(@Zippy, SqlDbType.SmallInt)).Value = zippy;
所提供样本中的关键问题包括:
sqlstring
的定义应该在字符串中包含参数定义
- 当通过创建新的错误对象引发错误时,将重置调用堆栈
SqlConnection
和SqlCommand
对象未正确处理(例如,conn.Close()
调用不是异常处理程序的Finally
部分
- 未设置
SqlParameters
的值
- 未调用
SqlCommand
对象上的Execute
xx方法
- 字符串值存储在
varchar
类型中,而不是Text
。Text是不推荐用于存储blob的SQL Server数据类型
我将按照如下方式重构代码:
private void enter_button_Click(object sender, EventArgs e)
{
var first = fname.Text;
var last = lname.Text;
var addy = address.Text;
var city1 = city.Text;
var stat = state.Text;
var zippy = zip.Text;
Validate(fname);
Validate(lname);
Validate(city);
Validate(state);
exValidate(address);
numValidate(zip);
using (var conn = new SqlConnection("Data Source=TX-MANAGER;Initial Catalog=Contacts;Integrated Security=True"))
using (var cmd = new SqlCommand(@"INSERT INTO Contacts ([First], [Last], [Address], [City], [State], [ZIP]) VALUES (@first, @last, @addy, @city1, @stat, @zippy)", conn))
{
cmd.Parameters.AddRange(
new[]
{
new SqlParameter(@"first", SqlDbType.VarChar).Value = first,
new SqlParameter(@"last", SqlDbType.VarChar).Value = last,
new SqlParameter(@"addy", SqlDbType.VarChar).Value = addy,
new SqlParameter(@"city1", SqlDbType.VarChar).Value = city1,
new SqlParameter(@"state", SqlDbType.VarChar).Value = stat,
new SqlParameter(@"zippy", SqlDbType.SmallInt).Value = zippy
});
conn.Open();
cmd.ExecuteNonQuery();
}
}
注意:我更喜欢提供参数的数据类型,因为当没有提供类型时,SqlCE并不总是正常工作。如果出现异常,您的连接将不会关闭,因为您在catch子句中重新引发异常,并且conn.Close()
在(不存在)之外最后阻塞。改用using语句
。另外,他的所有SqlParameters(firstparam、lastparam等…)都没有链接到SqlCommand(comm)SqlParameterCollectionI认为您不正确:看一看,添加的参数没有价值。带值的参数没有添加。好的。代码本身有很多缺陷。嵌入的SQL语句本身是/不正确的。@GarethD在他的回答中指出了这一点。您可以只编写comm.parameters.Add(@Zippy),SqlDbType.SmallInt).Value=zippy
;所以我改成了这个,但仍然没有发生任何事情。@marcmiller2007:再次验证您是否为参数设置了值,并将其添加到命令中。然后执行命令。还要检查连接字符串。它说它不能接受字符串。var first、last等被设置为字符串,但sql字符串是使用@fi设置的rst等,而不是parameters.addRange()之前的值;我需要首先为SqlParameters设置值,因此当设置SQL字符串时,它是使用SqlParameter设置的。值对吗?我不能只移动AddRange,因为那时SqlCommand没有初始化,这会在初始化之前的每个命令调用中抛出错误。我在SQL字符串中添加了缺少的括号。此外,数据类型在数组中应该是Varchar
,而不是text
,我最终创建了一个sqlParameter数组,并按如下方式分配每个索引:sqlparam[0]=new sqlParameter(@“first”,SqlDbType.text);sqlparam[0].Value=first;这用于分配数组中的值,然后调用:comm.Parameters.AddRange(sqlparam);
private void enter_button_Click(object sender, EventArgs e)
{
var first = fname.Text;
var last = lname.Text;
var addy = address.Text;
var city1 = city.Text;
var stat = state.Text;
var zippy = zip.Text;
Validate(fname);
Validate(lname);
Validate(city);
Validate(state);
exValidate(address);
numValidate(zip);
using (var conn = new SqlConnection("Data Source=TX-MANAGER;Initial Catalog=Contacts;Integrated Security=True"))
using (var cmd = new SqlCommand(@"INSERT INTO Contacts ([First], [Last], [Address], [City], [State], [ZIP]) VALUES (@first, @last, @addy, @city1, @stat, @zippy)", conn))
{
cmd.Parameters.AddRange(
new[]
{
new SqlParameter(@"first", SqlDbType.VarChar).Value = first,
new SqlParameter(@"last", SqlDbType.VarChar).Value = last,
new SqlParameter(@"addy", SqlDbType.VarChar).Value = addy,
new SqlParameter(@"city1", SqlDbType.VarChar).Value = city1,
new SqlParameter(@"state", SqlDbType.VarChar).Value = stat,
new SqlParameter(@"zippy", SqlDbType.SmallInt).Value = zippy
});
conn.Open();
cmd.ExecuteNonQuery();
}
}