简体   繁体   中英

asp.net SQL Server insert statement tidyup + error

I have a form which inserts data into a database.

There are certain fields that are not always going to be needed. When I leave these blank in my code I get a error saying.

Column name or number of supplied values does not match table definition.

This is how I have the database setup. SQL Server 2008

[youthclubid]
[youthclubname]
[description]
[address1]
[address2]
[county]
[postcode]
[email]
[phone]

Here is the code that I have connecting to the database and doing the insert.

connection.Open();
cmd = new SqlCommand("insert into youthclublist values ('" + youthclubname.Text + "', '" + description.Text + "','" + address1.Text + "','" + address2.Text + "', '" + county.Text + "', '" + postcode.Text + "', '" + email.Text + "', '" + phone.Text + "')", connection);
cmd.ExecuteNonQuery();

You have two major problems:

1) concatenating together your SQL statement is prone to SQL injection attacks - don't do it, use parametrized queries instead

2) You're not defining which columns you want to insert in your table - by default, that'll be all columns, and if you don't provide values for all of them, you'll get that error you're seeing.

My recommendation: always use a parametrized query and explicitly define your columns in the INSERT statement. That way, you can define which parameters to have values and which don't, and you're safe from injection attacks - and your performance will be better, too!

string insertStmt = 
       "INSERT INTO dbo.YouthClubList(Youthclubname, [Description], " +
         "address1, address2, county, postcode, email, phone) " +
       "VALUES(@Youthclubname, @Description, " +
         "@address1, @address2, @county, @postcode, @email, @phone)";

using(SqlConnection connection = new SqlConnection(.....))
using(SqlCommand cmdInsert = new SqlCommand(insertStmt, connection))
{
   // set up parameters
   cmdInsert.Parameters.Add("@YouthClubName", SqlDbType.VarChar, 100);
   cmdInsert.Parameters.Add("@Description", SqlDbType.VarChar, 100);
   .... and so on

   // set values - set those parameters that you want to insert, leave others empty
   cmdInsert.Parameters["@YouthClubName"].Value = .......;

   connection.Open();
   cmdInsert.ExecuteNonQuery();
   connection.Close();
}

This not way to do the code you make use of SqlParameter for this kind of statement.

So your code something like

  SqlConnection thisConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["Northwind_ConnectionString"].ConnectionString);

        //Create Command object
        SqlCommand nonqueryCommand = thisConnection.CreateCommand();

        try
        {

            // Create INSERT statement with named parameters
            nonqueryCommand.CommandText = "INSERT  INTO Employees (FirstName, LastName) VALUES (@FirstName, @LastName)";

            // Add Parameters to Command Parameters collection
            nonqueryCommand.Parameters.Add("@FirstName", SqlDbType.VarChar, 10);
            nonqueryCommand.Parameters.Add("@LastName", SqlDbType.VarChar, 20);


            nonqueryCommand.Parameters["@FirstName"].Value = txtFirstName.Text;
            nonqueryCommand.Parameters["@LastName"].Value = txtLastName.Text;

            // Open Connection
            thisConnection.Open();

            nonqueryCommand.ExecuteNonQuery();
        }

        catch (SqlException ex)
        {
            // Display error
            lblErrMsg.Text = ex.ToString();
            lblErrMsg.Visible = true;
        }

        finally
        {
            // Close Connection
            thisConnection.Close();

        }

The first major issue is that you are concatenating inputs in the query. This makes your application highly vulnerable to SQL Injection . Do not do this. Use a parametrized query .

The regular syntax for insert statement is like this:

Insert into <TableName> (Col1, Col2...Coln) values (val1, val2...valn)

If you need to insert only a selected set of columns, you need to provide the list of columns you are inserting data into in the column list.

If you do not specify the column list, the indication is that you are inserting data to each one of them.

So you may check for the input and if it is not there, you may omit the respective column.

The other better way is use a stored proc. That will ease out the issue.

You need to tell SQL server that which field you want to insert like

        insert into youthclublist(youthclubid, youthclubname, ....) values ('" + youthclubname.Text + "', '" + description.Text + "'.....

and you are fine.

Though new into programming, the easiest way i know to insert into a database is to create a "save" stored procedure, which is then called up through your connection string. Believe me, this is the best way.

Another way around is to use LINQ to SQL. i found this much more easier. Follow this steps.

  1. Add a new LINQ to SQL Classes to your project. Make sure the file extension is '.dbml'. Name it your name of choice say "YouthClub.dbml"
  2. Connect your Database to Visual Studio using the Server Explorer
  3. Drag your table to the OR Designer.(I'm not allowed to post images).

  4. You can now save to the Database with this code

      //Create a new DataContext YouthClubDataContext db = new YouthClubDataContext(); //Create a new Object to be submitted YouthClubTable newYouthClubRecord = new YouthClubTable(); newYouthClubRecord.youthlubname = txtyouthclubname.Text; newYouthClubRecord.description = txtdescription.Text; newYouthClubRecord.address1 = txtaddress1.Text; newYouthClubRecord.address2 = txtaddress2.Text; newYouthClubRecord.county = txtcounty.Text; newYouthClubRecord.email = txtemail.Text; newYouthClubRecord.phone = txtphone.Text; newYouthClubRecord.postcode = txtpostcode.Text; //Submit to the Database db.YouthClubTables.InsertOnSubmit(newYouthClubRecord); db.SubmitChanges(); 

Hope this time I have given a real answer

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM