C# asp.net c中数据库插入过程的优化#
我正在将asp.net 4和visual studio 2010与ms sql server 2008 express一起使用。我使用了三种不同的方法将数据插入数据库表: 方式1:C# asp.net c中数据库插入过程的优化#,c#,asp.net,sql,sql-server,C#,Asp.net,Sql,Sql Server,我正在将asp.net 4和visual studio 2010与ms sql server 2008 express一起使用。我使用了三种不同的方法将数据插入数据库表: 方式1: DataSet dsTab = new DataSet("Table1"); SqlDataAdapter adp = new SqlDataAdapter("Select * from Table1", con); adp.Fill(dsTab, "Table1"); DataRo
DataSet dsTab = new DataSet("Table1");
SqlDataAdapter adp = new SqlDataAdapter("Select * from Table1", con);
adp.Fill(dsTab, "Table1");
DataRow dr = dsTab.Tables["Table1"].NewRow();
dr["col1"] = txtBox1.Text;
dr["col2"] = txtBox5.Text;
dr["col3"] = User.Identity.Name.ToString();
dr["col4"] = "text";
dr["col5"] = DateTime.Now;
dr["col6"] = txtBox3.Text;
dr["col7"] = txtBox2.Text;
dsTab.Tables["Table1"].Rows.Add(dr);
SqlCommandBuilder projectBuilder = new SqlCommandBuilder(adp);
DataSet newSet = dsTab.GetChanges(DataRowState.Added);
adp.Update(newSet, "Table1");
方式2:
SqlDataAdapter AdapterMessage = new SqlDataAdapter();
AdapterMessage.InsertCommand = new SqlCommand();
AdapterMessage.InsertCommand.Connection = con;
AdapterMessage.InsertCommand.CommandText = "insert into Table1(col1,col2,col3,col4,col5,col6,col7) values ('" + txtBox1.Text + "','" + txtBox5.Text + "','" + User.Identity.Name.ToString(); + "','text','" + DateTime.Now + "','" + txtBox3.Text + "','" + txtBox2.Text + "')";
AdapterMessage.InsertCommand.ExecuteNonQuery();
AdapterMessage.Dispose();
方式3:
string query = "insert into Table1(col1,col2,col3,col4,col5,col6,col7) values ('" + txtBox1.Text + "','" + txtBox5.Text + "','" + User.Identity.Name.ToString(); + "','text','" + DateTime.Now + "','" + txtBox3.Text + "','" + txtBox2.Text + "')";
int i;
SqlCommand cmd = new SqlCommand(query);
con.open();
i = cmd.ExecuteNonQuery();
con.close();
这三种方式中,哪一种是网站使用的最佳方式???取决于数据量(单个或大容量),但我认为SqlCommand的开销可能最小。其他两个示例创建基本插入不需要的附加DataTable或DataAdapter
我还将研究存储过程(使用SqlCommand),因为这是我个人的选择,取决于数据量(单个或大容量),但我认为SqlCommand的开销可能最小。其他两个示例创建基本插入不需要的附加DataTable或DataAdapter
我还将研究存储过程(使用SqlCommand),因为这是我个人的选择您已经展示的唯一不易受到SQL注入攻击的示例是#1 由于其他两个都很脆弱,所以#1是您唯一的选择(在您介绍的三个选项中)。返回代码并立即修复任何#2或#3的示例。如果你不这样做,你的网站就会被黑客入侵 您是否发现您尝试过的各种方法之间存在性能问题?如果不是这样的话,你最好花时间保护你的网站,而不是过度设计你的代码 请看下面的图片。这是向SQL Server提交参数化查询的正确方法,并且在正确使用时消除了SQL注入攻击的可能性 也就是说,如果这是我的代码,我就不会使用这些选项中的任何一个。以下是我认为最好的方法的伪代码:
using (SqlConnection connection = new SqlConnection(
connectionString))
{
SqlCommand command = new SqlCommand(queryString, connection);
//add parameters here
command.Connection.Open();
command.ExecuteNonQuery();
}
您已经展示的唯一不易受到SQL注入攻击的示例是#1 由于其他两个都很脆弱,所以#1是您唯一的选择(在您介绍的三个选项中)。返回代码并立即修复任何#2或#3的示例。如果你不这样做,你的网站就会被黑客入侵 您是否发现您尝试过的各种方法之间存在性能问题?如果不是这样的话,你最好花时间保护你的网站,而不是过度设计你的代码 请看下面的图片。这是向SQL Server提交参数化查询的正确方法,并且在正确使用时消除了SQL注入攻击的可能性 也就是说,如果这是我的代码,我就不会使用这些选项中的任何一个。以下是我认为最好的方法的伪代码:
using (SqlConnection connection = new SqlConnection(
connectionString))
{
SqlCommand command = new SqlCommand(queryString, connection);
//add parameters here
command.Connection.Open();
command.ExecuteNonQuery();
}
SQL Server 2008支持多行插入,如下所示:
INSERT INTO MyTable (FirstCol, SecondCol)
VALUES ('First',1),
('Second',2),
('Third',3),
('Fourth',4),
('Fifth',5)
这可能会减少一些开销。SQL Server 2008支持多行插入,如下所示:
INSERT INTO MyTable (FirstCol, SecondCol)
VALUES ('First',1),
('Second',2),
('Third',3),
('Fourth',4),
('Fifth',5)
这可能会减少一些开销。如果要插入多行,则可以使用该对象。一个简单的例子:
DataTable dt = new DataTable();
SqlConnection oConn = new SqlConnection();
SqlBulkCopy sbc = new SqlBulkCopy(oConn);
sbc.DestinationTableName = "dbo.SomeTable";
sbc.WriteToServer(dt);
sbc.Close();
请记住,
数据表的架构必须是要插入的数据库表的架构。如果要插入多行,则可以使用该对象。一个简单的例子:
DataTable dt = new DataTable();
SqlConnection oConn = new SqlConnection();
SqlBulkCopy sbc = new SqlBulkCopy(oConn);
sbc.DestinationTableName = "dbo.SomeTable";
sbc.WriteToServer(dt);
sbc.Close();
请记住,数据表的模式必须是要插入的数据库表的模式。方式#1:数据集不是对象,我唯一的抱怨是
方法2:SQL注入噩梦
方法3:仍然不易被SQL注入攻击
扩展#3:
- 用于避免使用SQL
注射问题
- 不要从窗体传递值
直接进入查询,直到
已经过验证
还可以用相关名称命名变量,我在下面的示例中这样做了,但是我的名字很糟糕,因为我不知道您试图插入的数据的细节
public static void InsertRecordBasedOnView(String goodNameForTextBoxOne, String goodNameForTextBoxTwo, String goodNameForTextBoxFive, String goodNameForTextBoxThree, String userName)
{
const string query = "insert into Table1(col1,col2,col3,col4,col5,col6,col7) values (@valueOne, @valueTwo, @valueThree, @valueFour, @valueFive, @valueSix, @valueSeven)";
SqlParameter columnOne = new SqlParameter("@valueOne", SqlDbType.NVarChar);
SqlParameter columnTwo = new SqlParameter("@valueTwo", SqlDbType.NVarChar);
SqlParameter columnThree = new SqlParameter("@valueThree", SqlDbType.NVarChar);
SqlParameter columnFour = new SqlParameter("@valueFour", SqlDbType.NVarChar);
SqlParameter columnFive = new SqlParameter("@valueFive", SqlDbType.DateTime);
SqlParameter columnSix = new SqlParameter("@valueSix", SqlDbType.NVarChar);
SqlParameter columnSeven = new SqlParameter("@valueSeven", SqlDbType.NVarChar);
columnOne.Value = goodNameForTextBoxOne;
columnTwo.Value = goodNameForTextBoxFive;
columnThree.Value = userName;
columnFour.Value = "Text";
columnFive.Value = DateTime.Now;
columnSix.Value = goodNameForTextBoxThree;
columnSeven.Value = goodNameForTextBoxTwo;
SqlCommand cmd = new SqlCommand(query);
cmd.Parameters.Add(columnOne);
cmd.Parameters.Add(columnTwo);
cmd.Parameters.Add(columnThree);
cmd.Parameters.Add(columnFour);
cmd.Parameters.Add(columnFive);
cmd.Parameters.Add(columnSix);
cmd.Parameters.Add(columnSeven);
using (SqlConnection connection = new SqlConnection(someConnectionString))
{
connection.Open();
cmd.ExecuteNonQuery();
}
}
方法1:数据集不是对象,这是我唯一的抱怨
方法2:SQL注入噩梦
方法3:仍然不易被SQL注入攻击
扩展#3:
- 用于避免使用SQL
注射问题
- 不要从窗体传递值
直接进入查询,直到
已经过验证
还可以用相关名称命名变量,我在下面的示例中这样做了,但是我的名字很糟糕,因为我不知道您试图插入的数据的细节
public static void InsertRecordBasedOnView(String goodNameForTextBoxOne, String goodNameForTextBoxTwo, String goodNameForTextBoxFive, String goodNameForTextBoxThree, String userName)
{
const string query = "insert into Table1(col1,col2,col3,col4,col5,col6,col7) values (@valueOne, @valueTwo, @valueThree, @valueFour, @valueFive, @valueSix, @valueSeven)";
SqlParameter columnOne = new SqlParameter("@valueOne", SqlDbType.NVarChar);
SqlParameter columnTwo = new SqlParameter("@valueTwo", SqlDbType.NVarChar);
SqlParameter columnThree = new SqlParameter("@valueThree", SqlDbType.NVarChar);
SqlParameter columnFour = new SqlParameter("@valueFour", SqlDbType.NVarChar);
SqlParameter columnFive = new SqlParameter("@valueFive", SqlDbType.DateTime);
SqlParameter columnSix = new SqlParameter("@valueSix", SqlDbType.NVarChar);
SqlParameter columnSeven = new SqlParameter("@valueSeven", SqlDbType.NVarChar);
columnOne.Value = goodNameForTextBoxOne;
columnTwo.Value = goodNameForTextBoxFive;
columnThree.Value = userName;
columnFour.Value = "Text";
columnFive.Value = DateTime.Now;
columnSix.Value = goodNameForTextBoxThree;
columnSeven.Value = goodNameForTextBoxTwo;
SqlCommand cmd = new SqlCommand(query);
cmd.Parameters.Add(columnOne);
cmd.Parameters.Add(columnTwo);
cmd.Parameters.Add(columnThree);
cmd.Parameters.Add(columnFour);
cmd.Parameters.Add(columnFive);
cmd.Parameters.Add(columnSix);
cmd.Parameters.Add(columnSeven);
using (SqlConnection connection = new SqlConnection(someConnectionString))
{
connection.Open();
cmd.ExecuteNonQuery();
}
}
我认为你可以在数据库中使用视图!,或者像这样的实体框架
实体
using (var context = new ADO_NET_Entities())
{
var newDataset = new stuff();
stuff.row1InDatatable = "Something";
stuff.row2InDatable = "Something";
stuff.row3InInDatatable = "Something";
context.stuff.AddObject(newDataset);
context.SaveChanges();
}
这里有更多 我认为你可以在数据库中使用视图!,或者像这样的实体框架
实体
using (var context = new ADO_NET_Entities())
{
var newDataset = new stuff();
stuff.row1InDatatable = "Something";
stuff.row2InDatable = "Something";
stuff.row3InInDatatable = "Something";
context.stuff.AddObject(newDataset);
context.SaveChanges();
}
这里有更多 取决于数据量(单个或大容量),您还应该查看存储过程,因为这是我个人的选择这三个存储过程中有一个是好的-#2和#3尤其糟糕。您应该签出参数化查询,而不是将SQL语句连接在一起-这是一种糟糕的做法,为SQL注入攻击打开了大门。如果你有大量的数据(取决于数据量(单个或大容量),那么它的速度会惊人地快。你还应该看看存储过程,因为这是我个人的选择。这三个过程中有一个是好的-#2和#3尤其糟糕。您应该签出参数化查询,而不是将SQL语句连接在一起-这是一种糟糕的做法,为SQL注入攻击打开了大门。如果你有大量的数据,速度会惊人的快。他的最后两个例子似乎表明他一次只想插入一行。哦,是的,你是对的。当我读到他使用数据集时,我很激动。他最后的两个例子似乎表明他一次只想插入一行。哦,是的,你是对的。当我读到他使用数据集时,我激动不已。我已经多次使用参数。参数既可以用于DataAdapter,也可以用于SqlCommand对象。你是说