Question: For example, this is the code that I am using:

```
String commandString = "UPDATE Members SET UserName = @newName , AdminLevel = @userLevel WHERE UserID = @userid";
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["sqlconnectionstring"].ConnectionString))
{
    SqlCommand cmd = new SqlCommand(commandString, conn);
    cmd.Parameters.Add("@newName", newName);
    cmd.Parameters.Add("@userLevel", userLevel);
    cmd.Parameters.Add("@userid", userid);
    conn.Open();
    cmd.ExecuteReader();
    Reader.Close();
}

```

Answer: 
That code looks fine. Parameterisation is the way to go, as opposed to concatenating user-supplied values in an adhoc SQL statement which can open you up to sql injection attacks. This can also help with execution plan reuse.

The only thing I'd add, is I prefer to explicitly define the datatype and sizes of the parameters. For example, if you don't then, as an example, all string values will get passed in to the database as NVARCHAR instead of VARCHAR. Hence I like to be explicit.
That's still a static query string. It's not really "dynamic" sql until you also build parts of the string on the fly — something like this:

```
var sql = "SELECT columns FROM Table WHERE 1=1";
if (!string.IsNullOrEmpty(txtName.Text)) sql += " AND Name LIKE '%' + @Name + '%'";
if (!string.IsNullOrEmpty(txtDesc.Text)) sql += " AND CONTAINS(DESCRIPTION, @description)";

```

But even so, this is still "safe" in the sql injection sense as long as you continue to use parameters for every part of the query that originates with user input.