Nested Insert Into Errors - c#

I've created this Insert Into SQL query, it takes information from the table lessons where the text box containing the lesson ID matches with any of the lessons. I have tested this Query works as it returns the correct values to a datagrid view in.
The second part of the query is supposed to get the student ID and Student Name from the text box that the user has input information. Then transfer this into the Less/Stud table.
This table has a the following Columns
Lesson Name Lesson ID Student ID Student Name Optional?
I do not need to worry about the Optional column as that is a check box not needed yet, below is the current query that doesnt work. It returns the following errors:
Incorrect Syntax near '/'
Incorrect Syntax near 'Test Student Name'
The second error within the ' ' always contains the information from the student name text box.
INSERT INTO Less/Stud ([LessonName],[Lesson ID],[Student ID],[Student Name])
SELECT LessonName, LessonID
FROM Lessons
WHERE ClassID ='" + txtClassID.Text + "'
AND (SELECT [Student ID], [StudentName]
'" + txtStuId.Text + "', '" + txtName.Text + "' "

You need to put all four columns being inserted in the outer select:
INSERT INTO Less/Stud ([LessonName],[Lesson ID],[Student ID],[Student Name])
SELECT LessonName, LessonID, '" + txtStuId.Text + "', '" + txtName.Text + "' "
FROM Lessons
WHERE ClassID ='" + txtClassID.Text + "'

There are two errors in your query.
If your table is Less/Stud then you must call the table name with square brackets like [Less/Stud]
Your Insert query have 4 columns but your SELECT query have only 2 columns. Thats also must be changed.
And the most important one, your query is prone to SQL injection. Try to use parameterized query.

Is "Less/Stud" your table name? I would suggest putting that in quotes, because the / seems to be confusing the database.
The WHERE clause also seems to be incomplete. A subselection is being started, but never completed.
You should also only put the fields you actually want to insert data into in the first line. Since you only provide 2 values in the SELECT clause, you can not define 4 fields to insert into.
EDIT: It turns out you want to insert values from a textbox into the Student ID and Student Name fields, based on your clarification. I have altered my suggested query to reflect this. I have not been able to test this, so I might have some mismatching quotes here and there, but I think it should be something like this:
"INSERT INTO [Less/Stud] ([LessonName],[Lesson ID],[Student ID],[StudentName])
SELECT LessonName
, LessonID
, '" + txtStuId.Text + "'
, '" + txtName.Text + "'
FROM Lessons
WHERE ClassID ='" + txtClassID.Text + "' "
You might want to consider using the String.Format() method to put the textbox values into the SQL string though. I personally think the string would be more readable that way. It would look like this:
var yourQuery = String.Format(
"INSERT INTO [Less/Stud] ([LessonName],[Lesson ID],[Student ID],[StudentName]) SELECT LessonName, LessonID, '{0}', '{1}' FROM Lessons WHERE ClassID ='{2}' "
, txtStuId.Text
, txtName.Text
, txtClassId.Text
);
Breaking up the SQL statement itself into multiple lines might also be a good idea, especially for even longer and/or more complicated statements.

Related

Error using a trigger in c#

I made a Table using a Database in visual 2015 and in the table I have name, n1 , n2 , and avg. I made a insert button with 3 textboxes where I insert my name, number1 and number2 and when I press the button I want to save them in a table. If I use 4 textboxes (one for avg) it works, but I want to use a trigger. So.. I created a trigger >
CREATE TRIGGER [Trigger]
ON [dbo].[Table1]
FOR DELETE, INSERT, UPDATE
AS
BEGIN
UPDATE Table1
SET avg = (N1+N2)/2
END
and here is my insert string
string ins = "insert into Table1 values ('"; ins += textBox1.Text + "','" + textBox2.Text + "','" + textBox3.Text + "')";
and I get this error..
Column name or number of supplied values does not match table definition.
I don't know what to do :(
Ok, I still don't think we have all the information, but I'll give a crack at it...
The error message is from the insert statement, not from the trigger.
For your insert, I'd format it so you specifically state which values/columns will be inserted into the table.
It appears as though your average column is a non-nullable field, without a default constraint. So when you try to insert just the 3 values, it wants 4, because it HAS to have 4 (non-nullable). That's why it's throwing the error.
I'd structure your isnert like this:
insert
into Table (Col1, Col2, Col3)
values (val1, val2, val3)
Then, add a default constraint [then updated by trigger], OR, make the Average column nullable, so it can again then be updated via the trigger.
I bet you have a primary key column or another column you're not telling us about.
Either make the Primary Key column Auto-Increment, or make each column allow nulls or give each column a default value.
Also look up SQL Injection as your insert statement is susceptible to attacks.
There is also a problem with your syntax:
string ins = "insert into Table1 values ('"; ins += textBox1.Text + "','" + textBox2.Text + "','" + textBox3.Text + "')";
It should be
string ins = "insert into Table1 values ('" + textBox1.Text + "','" + textBox2.Text + "','" + textBox3.Text + "')";

Creating reusable SQL commands in c# programing

I have following query that works.
string sqlCommandText = "SELECT * FROM Admin_T where AdminID =
'" + textBox.Text + "'";
It is a fix command and I cannot use it with user given Table names and Column names at run time.
What I am actually trying to make is command like
string sqlCommandText = "SELECT * FROM Admin_T where
'" + UserGivenColumnName + "' = '" + conditionTB.Text + "'";
"UserGivenColumnName" can be any column that is part of that specific table.
Trying to create flexibility so that same command can be used under different circumstances.
SqlCommand and none of related classes used by ADO.NET does not support such a functionality as far as I know.
Of course your should never build your sql queries with string concatenation. You should always use parameterized queries. This kind of string concatenations are open for SQL Injection attacks.
But prepared statements only for values, not column names or table names. If you really wanna put your input string to your column name, create a whitelist and use it as a validation before you put it in your query.
http://codeblog.jonskeet.uk/2014/08/08/the-bobbytables-culture/
I think an Object-Relational Mapper (ORM) is perhaps the droid you are looking for. Entity Framework might be a good place to start.
Please also do take the time to understand what SQL injection is, as the other users have also prompted you to.
It is not returning anything as it is just comparing two strings
With the 'UserGivenColumnName' it is a string comparison
And those two strings are not equal
You can do it (column) by just not including the '
But it is still a bad idea
SQLinjection is a very real and very bad thing
string sqlCommandText =
"SELECT * FROM Admin_T where " + UserGivenColumnName + " = '" + conditionTB.Text + "'";
or
string sqlCommandText =
"SELECT * FROM Admin_T where [" + UserGivenColumnName + "] = '" + conditionTB.Text + "'";

Query working fine in SQL but not in the code

I have a simple query updating the ProductPrice column by replacing old data and updating ProductQuantity which is being added to the previous one.
I wrote the query in SQL and it's working fine, but in the VS code it's concatenating the ProductQuantity. Like if I have 20 in product quantity then after this the result should be 20 + 50 = 70 but after executing query in code it updates the value to 2050
The query in SQL is:
UPDATE ProductLog
SET ProductQuantity = ProductQuantity + 50,
ProductPrice = 20
WHERE ProductCode = 1
The query in my C# code is:
sql = "";
sql += "UPDATE ProductLog
SET ProductQuantity = ProductQuantity
+ '"
+ productQuantity
+ "', ProductPrice = '"
+ productPrice
+ "' WHERE ProductCode = '"
+ ProductCode
+ "'";
I am not able to find my mistake in code query. Please guide me in this regard.
The column's datatype in the table is varchar.
Jack,
That is because when you are manually generating a query via string concatenation, it will not add the numeric values together. It will run all your variables through their respective .ToString() methods, get the result, and concatenate the result into your string. Depending on how you are executing this query (ADO.NET, Linq2SQL, or Entity Framework) you are better off using the mechanisms in those technologies to update your values as opposed to manually creating those strings. If you want to continue doing this way you will have to retrieve the value for "ProductQuantity", add that value to 50 (or whatever value you want) and then do the concatenation before executing the query.

Why is SQL statement returning all rows when passing " "?

I am using this SQL statement to get rows:
SELECT firstname, lastname
FROM myTable
WHERE ((lastname LIKE '" + parameter + "%')
parameter gets a value form a textbox. The default value of textbox is " "
My problem is I am getting all the rows when nothing is entered in the textbox. I tried to use
WHERE lastname =
This simply gives me all the records that has " "
What is the correct way of getting data that excludes blanks in the database and also does not give your any record when blank or " " is passed as a parameter
You're using a wilcard, so for a blank search string, you end up with
... WHERE lastname LIKE '%'
which will match everything. If nothing is entered into the search form, you should simply detect that at the script level and NOT run the query, e.g. in php-ish terms:
if (strlen($_GET['keywords']) == 0) {
die("No search terms entered");
}
First, I hope you do some sanitizing to avoid sql injection.
Then you can at your choice :
not run the query if sanitizing parameter including a trim() is empty
have SELECT firstname, lastname FORM myTable WHERE ((lastname LIKE '" + parameter + "%') AND ''<>'" + parameter + "'"
the second one being a bad practice from a performance point, and it would assume you've given up sanitizing (very bad)
Also you should note that, in your sanitizing process, you will have to escape or remove special characters _ and %, see
http://msdn.microsoft.com/en-us/library/ms179859(v=sql.105).aspx
I you do not handle this, a non empty parameter equal to % will lead to a like '%%', which is equivalent to like '%'
SELECT firstname, lastname
FROM myTable
WHERE lastname LIKE '" + parameter + "%'
AND NULLIF(lastname,'') IS NOT NULL
AND '" + parameter + "' <> ''
Quite simply only return records where lastname startswith your 'parameter' and only where 'parameter' is not empty string.
Edit: Added code for the requirement that it never returns record with blank lastname.
Well you could just test for string.IsNullOrEmpty on parameter variable in your code so that you don't even need to make the database call.
In my view its the most efficient thing to do.

Problem with a sql statement

string insertCommand =
"INSERT INTO Users (UserID) VALUES" + "" + "(CONVERT(uniqueidentifier, '" +
UsersIdentityToinsert + "'),'"+ userName+",0,null')";
it tells me:
There are fewer columns in the INSERT statement than values specified
in the VALUES clause. The number of
values in the VALUES clause must match
the number of columns specified in the
INSERT statement.
But i have four columns?
you only have UserID in the insert list but in the value list, you have two values - a uniqueidentifier and a username
this would work better: (assuming the name of your username column)
string insertCommand =
"INSERT INTO Users (UserID, username) VALUES" + "" +
"(CONVERT(uniqueidentifier, '" + UsersIdentityToinsert + "'),'"+ userName+"')";
EDIT:
I feel i need to address this part a bit more clearly:
But i have four columns?
The error you received refers to the number of columns specified in the INSERT statement - not the actual table so if you start an INSERT with:
INSERT INTO AnyTable (ColumnA, ColumnB)
you need to match the number of columns here in your VALUES clause
VALUES ("Value1", "Value2")
You are missing "UserName" in column Names, that is, Column Name and values mismathch.
string insertCommand =
"INSERT INTO Users (UserID,UserName) VALUES" + "" +
"(CONVERT(uniqueidentifier, '" + UsersIdentityToinsert + "'),'"+ userName+"')";

Categories