Best practices for using SqlCommand
I would like to make sure when using SqlCommand that I am using best practices, particularly with regards to security.
Considerations that I am not sure about:
- Is it ok to manually build the string by appending? If not, how should 开发者_如何学CI do it?
- What classes should I be looking at using instead?
If your first question is talking about building SQL by including the values directly, that's almost certainly not okay. It opens you up to SQL injection attacks, as well as issues with conversions (e.g. having to get the right date/time format).
Instead, you should use a parameterized query, and set the values in the parameters. See the docs for SqlCommand.Parameters
for an example.
Out of interest, do you have a particular reason for using SQL directly instead of using one of the many ORMs around? (LLBL, Entity Framework, NHibernate, LINQ to SQL, SubSonic, Massive, SimpleData, Dapper...)
I would say use of parameters is one of the most important aspects for security. This will prevent SQL Injection into your database. The following SQLCommand is an example of how I would construct one (in VB.NET, apologies - no C# knowledge - yet ;))
Dim cmd as New SqlCommand("sp_StoredProcedure", Conn)
cmd.commandType = commandtypes.storedprocedure
cmd.parameters.add("@ID",sqldbtype.int).value = myID
cmd.executenonquery
And an example of an inline SqlCommand:
Dim cmd as New SqlCommand("SELECT Name, Message FROM [Table] WHERE ID=@ID", Conn)
cmd.commandType = commandtypes.storedprocedure
cmd.parameters.add("@ID",sqldbtype.int).value = myID
cmd.executenonquery
My advice: be lazy. Writing voluminous code is a good way to make brain-dead errors (wrong data type, null checks, missing Dispose(), etc), and it has zero performance advantage over many of the helper tools.
Personally, I'm a big fan of dapper (but I'm somewhat biased), which makes things easy:
int customerId = ...
var orders = connection.Query<Order>(
@"select * from Customers where CustomerId = @customerId",
new { customerId });
Which will do parameterisation and materialisation for you without pain, and stupidly fast.
For other scenarios, and in particular when you want to use OO techniques to update the system, an ORM such as EF or L2S will save you work while (and giving you better type-checking via LINQ).
I think this is the best solution
SqlConnection cn = new SqlConnection(strCn);
try
{
using (SqlCommand cmd = new SqlCommand("select * from xxxx", cn))
{
cn.Open();
//do something
cn.Close();
}
}
catch (Exception exception)
{
cn.Close();
throw exception;
}
Depending, when I do POC or personnal small projects I normally build my strings manually but when im in a project for work we have a template for DB usage and connection that I must use and can't reveal here obviously.
But I think it's ok to manually build for basic operations in small project or POC.
- Edit : Like Jon said though you should always use somehting like SqlCommand.Parameters when building your own command. Sorry if I wasn't clear.
If you're concerned about security, I recommend create your queries as Stored Procedures inside the SQL Server Database instead (to prevent worrying about SQL injection), and then from the front end code, just generate a SQL Stored Procedure, add the parameters, and do it that way.
This article should help you out with setting this up.
You should always use the practice of applying the least privileges to database connections by communicating with the database through stored procedures.
Store Procs
using System.Data;
using System.Data.SqlClient;
using (SqlConnection connection = new SqlConnection(connectionString))
{
DataSet userDataset = new DataSet();
SqlDataAdapter myCommand = new SqlDataAdapter("LoginStoredProcedure", connection);
myCommand.SelectCommand.CommandType = CommandType.StoredProcedure;
myCommand.SelectCommand.Parameters.Add("@au_id", SqlDbType.VarChar, 11);
myCommand.SelectCommand.Parameters["@au_id"].Value = SSN.Text;
myCommand.Fill(userDataset);
}
The credentials for the connection string to the database: A. Integrated Security for corporate/intranet B. Keep it encrypted in the registry or a file in Hosting Providers.
Always be on the lookout for hackers trying to upload cross scripting into your forms.
Always check the input for SQL injection.
精彩评论