C# SQL命令中的字符串插值

C# SQL命令中的字符串插值,c#,string,string-interpolation,C#,String,String Interpolation,在下面的insert SQL命令中是否有更简单的方法来使用name和phone变量 这是一种方法,但我不知道如何实现 String name = textBox1.Text; String phone = textBox2.Text; var query = "insert into Customer_info(Customer_Name,Customer_Phone) " + "values('" + name +

在下面的insert SQL命令中是否有更简单的方法来使用
name
phone
变量

这是一种方法,但我不知道如何实现

String name = textBox1.Text;
String phone = textBox2.Text;  
     
var query = "insert into Customer_info(Customer_Name,Customer_Phone) " +
            "values('" + name + "','" + phone + "');";
SqlCommand com = new SqlCommand(query,con);

try {
    con.Open();
    com.ExecuteNonQuery();
    con.Close();
}

catch (Exception Ex) {
    con.Close();
}

要使用字符串插值,您需要编写:

var query = $"insert into Customer_info(Customer_Name,Customer_Phone) values('{name}','{phone}');";
但是,您当然倾向于SQL注入,这是您应该避免的


使用
SqlCommand.Parameters
collection添加参数并确保该线程的安全。

不要这样做!说真的,别这样。字符串插值不适合构建SQL。只需使用参数:

var query = @"
insert into Customer_info(Customer_Name,Customer_Phone)
values(@name,@phone);";
//...
cmd.Parameters.AddWithValue("name", name);
cmd.Parameters.AddWithValue("phone", phone);
cmd.ExecuteNonQuery();
或者使用dapper之类的库(它可以为您删除所有凌乱的ADO.NET代码,如命令、参数和读取器):

您真正应该做的是使用参数化查询,因此您的查询如下所示:

var query = "insert into Customer_info(Customer_Name,Customer_Phone)" +
"values(@name, @phone);";
insert into Customer_info(Customer_Name,Customer_Phone) values ('';
DROP TABLE [Customer_Info];
-- ','');
然后使用
SQLCommand
对象将参数传递给查询:

using (var command = new SqlCommand(query, connection))
{
    command.Parameters.AddWithValue("@name", name);
    command.Parameters.AddWithValue("@phone", phone);

    command.ExecuteNonQuery();
}
这样做的原因是它避免了SQL注入的风险(这是最常见的方法之一)。考虑一下当前的查询,如果传入的<代码>名称<代码>包含一些SQL,例如包含的话:

",;下拉表[客户信息]--

这意味着您构造的SQL(如果电话为空)将如下所示:

var query = "insert into Customer_info(Customer_Name,Customer_Phone)" +
"values(@name, @phone);";
insert into Customer_info(Customer_Name,Customer_Phone) values ('';
DROP TABLE [Customer_Info];
-- ','');

如果代码连接到SQL as的用户具有足够的权限,这很可能会导致您的
Customer\u Info
表被删除。

而不是使用串联字符串或字符串插值从用户输入构建查询字符串,改为使用参数-请参阅。try-catch方法在哪里?@gragascomping我在捕获什么,为什么?坦率地说,
使用
尝试
/
捕获
有用得多-Rob的回答显示了它的位置。那么您将如何输出错误?例如,内部捕捉功能
ex.Message
@GragasIncoming如果你是说你是问题中的
试试看
/
捕获物
:我回答问题时他们不在问题中;另外:您的
捕获
吞下异常;此外,您很少需要
Close()
连接,在这里,终生使用
using
的情况要常见得多。请注意,我们是dapper版本:dapper实际上无论如何都会正确处理连接生存期-如果在您调用
Execute
时连接未打开,它将打开、执行并关闭它,等等(如果它最初打开,它显然不会关闭)@GragasIncoming re“那么您将如何输出错误?”-我可能会捕捉到更接近将显示错误的代码;如果您的数据访问代码和UI代码是混合的,这并不是很好的分离concerns@GragasIncoming,不,这真的不是你怎么做的。。。您将值连接到
查询中
,我将它们作为参数传入。这些是构造传递给SQLServer的查询的根本不同的方法。为了这段代码是为该公司的客户着想,请花半个小时来弄清楚为什么级联不好。下面是来自OWASP的一个页面,其中还有一些示例可能会有所帮助:我认为它需要
connection.Open()因为它给出了一个错误。