tags:

views:

65

answers:

3

I am using C#, VS 2005 and SQL 2000

My code is:

StringBuilder sb = new StringBuilder();
sb.Append("insert into dummy(name,amount)values");
foreach (Control ctl in this.flowLayoutPanel1.Controls) 
{
  if (ctl.Name.Contains("tb") && ctl is TextBox) 
  {
     sb.Append(ctl.Text);
  }
} 

foreach(Control bbl in this.flowLayoutPanel1.Controls)
{
   if(bbl.Name.Contains("bb") && bbl is TextBox)
   {
     sb.Append(bbl.Text);
   }
}

SqlCommand cmd = new SqlCommand(sb.ToString(), con);
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();

It throws an error like this:

Incorrect syntax near values

Please help me.

+5  A: 

Looks like you are missing a space after the brackets and after VALUES. And you are missing an opening and closing bracket for your VALUES statement. You will also need to add commas after the values that you are inserting to seperate them. So your syntax should look something like:

insert into dummy(name,amount) values (textBox1value, textBox2value)

EDIT

Assuming that you only have 2 TextBox controls in your flowLayoutPanels, then you could do the following:

StringBuilder sb = null; 
sb = new StringBuilder(); 
sb.Append("insert into dummy(name,amount)values ("); 
foreach (Control ctl in this.flowLayoutPanel1.Controls)  
{ 
   if (ctl.Name.Contains("tb") && ctl is TextBox)  
  { 
     sb.Append(ctl.Text); 
  } 
}  

sb.Append(",");

foreach(Control bbl in this.flowLayoutPanel1.Controls) 
{ 
   if(bbl.Name.Contains("bb") && bbl is TextBox) 
   { 
    sb.Append(bbl.Text); 
   } 
} 

sb.Append(")");

But, I would strongly look into the solution suggested by Jon.

Ardman
@Ardman thx for ur feedback sir, but how to use it in foreach loop as above mention as my controls like textboxes in FLP is runtime guide me proper sir.
mahesh
+1  A: 

@Ardman has mentioned the syntax errors, but there's something much more important: you should not be appending user-entered values into your SQL like this.

Use a parameterized SQL statement instead, and set the values into the parameters. Otherwise you're open to SQL injection attacks.

Jon Skeet
Your assuming that his code will be public facing....
BG100
@Jon Skeet: I could amend my answer to talk about the SQL injection risks by doing something like this but as you've clearly defined it +1 :o)
Ardman
@BG100: No, I'm assuming it will be *human*-facing. Unless the interface is designed specifically to let you enter SQL, it should use a parameterized statement.
Jon Skeet
+1  A: 

The values themselves need to be in brackets and separated by commas as well.

I think your code produces this:

insert into dummy(name,amount)valuesthisname100

But you need to change it to produce this:

INSERT INTO dummy (name, amount) VALUES ('thisname', 100)

some example code that will do this is:

StringBuilder sb = null;
sb = new StringBuilder();
sb.Append("insert into dummy(name,amount)values (");
foreach (Control ctl in this.flowLayoutPanel1.Controls) 
{
   if (ctl.Name.Contains("tb") && ctl is TextBox) 
   {
      sb.Append("'" + ctl.Text + "'");
   }
} 
sb.Append(", ");
foreach(Control bbl in this.flowLayoutPanel1.Controls)
{
   if(bbl.Name.Contains("bb") && bbl is TextBox)
   {
       sb.Append(bbl.Text);
   }
}
sb.Append(")");
SqlCommand cmd1 = new SqlCommand(sb.ToString(), con);
cmd1.CommandType = CommandType.Text;
cmd1.ExecuteNonQuery();

This code is far from ideal, but it should fix your SQL syntax error. Some other enhancements you should think about are:

  • Make sure only one text box is ever found in each of the foreach loops. If more than one then the field count won't match.
  • Put validation or fix-up code in to ensure that no single quote characters appear in text thats entered by the user, or change the SQL to use parameters (thanks Jon Skeet).
  • Put validation to ensure that your second text box is parseable as a number (see Int.TryParse()), assuming that your Amount field is a numeric.

However, a MUCH better way would be to do this (EDITED to help mahesh with his coding, now includes multiple inserts):

string sName = null;
double? nAmount = null;

foreach (Control ctl in this.flowLayoutPanel1.Controls) 
{
   if (ctl.Name.Contains("tb") && ctl is TextBox) sName = ctl.Text;
   if (ctl.Name.Contains("bb") && ctl is TextBox) 
   {
       double nTmp = 0;
       if (double.TryParse(ctl.Text, out nTmp)) nAmount = nTmp;
   }

   if (sName != null && iAmount != null) 
   {
      SqlCommand cmd1 = new SqlCommand("INSERT INTO dummy (name, amount) VALUES (@name, @amount)", con);
      cmd1.Parameters.Add("@name", SqlDbType.VarChar).Value = sName;
      cmd1.Parameters.Add("@amount", SqlDbType.Decimal).Value = nAmount;
      cmd1.ExecuteNonQuery();
      sName = null;
      nAmount = null;
   }
}
BG100
@BG100 thx for ur feedback, but sir it's straight syntax i don't know how to use it in above foreach loop condition. As my textbox is runtime in flowlayout controls.
mahesh
Why make sure that users can't enter quotes (which may naturally occur in their data) rather than just handling it properly via parameterized SQL?
Jon Skeet
As I said, this code is far from ideal but it answered his question. To handle it using parameterised SQL is slightly beyond the scope of this question, however I'll mention it anyway :)
BG100
@BG100: Changing to use a parameterized statement would probably make the code *simpler* (no dynamic SQL construction) - but my point is that leading him down the path of manually validating or escaping the user values is a bad idea. Better to call an abrupt halt to that way of inserting data, and go straight for the far better approach.
Jon Skeet
@Jon Skeet: Ok... I give in! I've added the parameterised version :o)
BG100
@BG100, thx the code like Int.TryParse(bbl.text, is understand but Out iAmount i didn't get sir please expalin it.
mahesh
@mahesh: This code is to make sure that an error isn't raised if the user enters a non-numberic string into the TextBox. iAmount is the integer I've declared at the top to store the value, and "out iAmount" is passing this integer as a parameter to the TryParse function so that it can pass back the parsed integer if its valid.
BG100
@BG100 lot's thx i will be back after implement this code once again thx for ur feedback
mahesh
@BG100 sir, I have tried ur code it's work fine but a little problem is that my runtime control increment type suppose tb have three records in it and bb also. So as per ur perametriz code it's accept only one records and if i have to put my modify code on it so how can i do please guide me.
mahesh
@mahesh: I'm going to need a bit more information to answer that... can you give me an example of what the full names of the controls will be?
BG100
@BG100, runtime control like textboxes name= tb and another textboxes name=bb as above and all that in flowlayoutpanel1. the above textboxes increment type it's may be three or four it's upto user desire how much they have to increment as their requirement for data entry.
mahesh
@BG100 "tb" is Varchar Datatype and "bb" is Decimal Datatype in SQL-2000
mahesh
@mahesh: I've updated to include multiple inserts. I haven't tested this so I hope it works! It's a bit tricky because I don't know how your controls are named and layed out (apart from them containing bb and tb), there is a possibility that the wrong amounts will get assigned to the wrong names... but I can't help with this unless you give me more information.
BG100
@BG100 Ok Sir, I will try it and let u know but sir how can i put my modified code on this page.
mahesh
@mahesh: If you want to post some new code, then I guess the best way would be to just submit a new answer to your own question... anyone know a better answer to this??
BG100
@Mahesh: Sir, please stop writing "Sir" :)
shahkalpesh
@shahkalpesh: how do you know I'm not a knight?? :)
BG100
@shahkalpesh when u learn from some one than he is ur teacher and he should be most respectable for u. don't forget to earn respect first u should have to respect others. i think it's clear
mahesh
@BG100 i have seen ur code but one confusion is that bbl.text is a collection control in foreach loop like ctl.text here is ur not define collection control for bbl.text
mahesh
@mahesh: It doesn't matter, both bbl.text and ctl.text are both part of the same collection of controls, so only one foreach is required.
BG100
@mahesh: Would you mind accepting mine as the correct answer? If you think it's good enough :) - if you don't know how, just click one of the green ticks!
BG100
@BG100 sir, am trying but when i type if(double.tryparse(bbl.text,out ntmp)) nAmount=ntmp; the bbl.text not available in contain collection
mahesh
@mahesh: My apologies, this was a mistake, I've now corrected it. It should be: if (double.TryParse(ctl.Text....
BG100
@mahesh: Are you going to accept my answer?
BG100
BG100, thx sir am appreciate ur feedback and accepted ur answer
mahesh
@mahesh: thanks.... but it doesn't seem to have worked!!
BG100
BG100, sir i didn't get u. u mean ur suggested code. yeah! it's works so why?
mahesh
@mahesh: I mean you accepting my answer... if you ask a question on StackOverflow, you must always accept the best answer by clicking the green tick so that the user gets the credit for it... otherwise people will stop answering your questions.
BG100
BG100, thx sir am once again accepting ur answer, if we require something and given diferent so sir how can i accept it. u can see my profile and read carefully each question and answer and than if u think i am wrong than sir i will leave this community
mahesh
@Mahesh: If you look at my answer you will see the current votes at the top and to the left, and underneath there is a white check mark... click on this to make it green.
BG100
BG100 thx a lot sir
mahesh
@Mahesh: Yes thats it! you got it.... you should do the same for the other questions you've asked. Welcome to the community :)
BG100