Error on Quoted Data fetch from Database - c#

i have question that when i fetch data from database and if in the databse have some quoted dat e.g. D`DUN. this data is inserted in DB. when i execute select query like :
Select city from glmast where glname='" + list_customer.Items[i].Value + "'
in list_cutomer there is data in which some data are inserted like D`DUN like quotes. so it gives error like unclosed Quotation.
so, how this will be solved because not all field contain Quotes.
Please Help Me..
Mitesh

You should never use string concatenations when building SQL queries. You should use parametrized queries. Not only that your code will break in situations as the one you have described, but even worse, your code is vulnerable to SQL injection and if your application falls in the hands of malicious users, your database will get busted.
So parametrized queries:
string sql = "SELECT city FROM glmast WHERE glname = #glname";
using (var conn = new SqlConnection("Some connection string"))
using (var cmd = conn.CreateCommand())
{
conn.Open();
cmd.Parameters.AddWithValue("#glname", list_customer.Items[i].Value);
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
// do something with the results
}
}
}

Related

How to check if a song exists?

I can Insert, Update, Delete and Search the MySql Database
I wish to know how to check if a Song Exists in MySql DataBase ...
void CheckIfFileExists(String file, String dir)
{
// $mysqli = new mysqli(SERVER, DBUSER, DBPASS, DATABASE);
string song = Path.GetFileName(file);
song = MySql.Data.MySqlClient.MySqlHelper.DoubleQuoteString(song);
string ConString = " datasource = localhost; port = *;
username = ***; password = *****";
string sql = "SELECT id FROM music WHERE song = " + song);
using (MySqlConnection cn = new MySqlConnection(ConString))
{
cn.Open();
using (MySqlCommand cmd = new MySqlCommand(sql, cn))
{
//if id exixts?
if (???????????)
{
// "Song exists";
}
else
{
// "Song does not exist";
InsertIntoDataBase(String file, String dir);
}
}
}
}
I'll go straight to the real issue, how to upsert correctly, before the question gets closed. Use MySQL's custom INSERT IGNORE and parameterized queries. Using Dapper makes this a one-liner:
var sql=#"INSERT IGNORE INTO music
(ID,song,folder)
VALUES (1, #song,#folder)";
using (var cn= new MySqlConnection(ConString))
{
cn.Execute(sql,new {song=song,folder=#dir});
}
Dapper will open the connection to execute the command and close it afterwards. It will generate a MySqlCommand, generate parameters for every property in the supplied object (#song for song, #folder for folder).
INSERT IGNORE will try to insert a new row to the table. If a row with the same primary key already exists, the INSERT will be ignored.
Generating SQL strings by concatenating input is very dangerous. No amount of quoting can prevent SQL injection attacks, or more benign conversion errors. What would happen if the song was named '0'; DROP TABLE music;-- ? What if the value was a date or number? The query string would end up with invalid characters.
Parameterized queries on the other hand are like C# functions. The parameters are passed to the server outside the string itself, as part of the RPC call. The server generates an execution plan from the query and feeds the parameter values to the compiled execution plan.
The values never change to text or get combined with the query, so there's no way to inject SQL or end up with type conversion issues

Properly check if a record already exists in a database

I have read other questions on this, but it does not help for the most part.
Trying to check if a file has already been uploaded(filename is sent to this table) before creating another record and allowing them to upload the same file again.
I am using this code and it keeps telling me every file is a new file, even when I use the same file for testing. Obviously it should result in "Exists". Connection is already established using "this.Master.Conn" so please no SQLCommand stuff.
I even tried using wildcards in the query.
private string SQLCheck(string FileName)
{
string Check = "Select VideoURL from TrainingVideo2 where VideoURL Like '" + FileName +"' and Status=1;";
Object ob = this.Master.Conn.ExecuteSqlScalarCommand(Check);
string Result;
if (DBNull.Value.Equals(ob))
{
Result = "Exists";
}
else
{
Result = "NewFile";
}
return Result;
}
Also, does anybody have a better(more efficient) way of doing this?
Trying to basically rewrite this in c#.
Private Function CheckName(name As String) As Int32
Dim sql As String = "SELECT ID FROM Company Where Name Like '" & name & "' "
Dim ob As Object = Conn.ExecuteSqlScalarCommand(sql)
If IsDBNull(ob) Then
Return 0
Else
Return CInt(ob)
End If
End Function
There are new and more innovative methods devised to get around the simple "replace all ` and " characters with ..." SQL injection prevention techniques. In your case, if the VideoURL happens to be a varchar (and not nvarchar), then using unicode character U+02BC (URL encoded = %CA%BC) would pass in a quote character as a unicode string, which would bypass your C# checks, but SQL Server will conveniently convert to a quote character in your query. This is just one example of why you should not be doing this :).
In terms of you check, I always prefer using TOP 1 to let SQL Server cut a potential table scan short. So, I would use this query:
Select TOP 1 SomeNonNullIntColumn from TrainingVideo2 where VideoURL Like ... and Status=1;
Execute the query with ExecuteScalar. If the result is null, then the record does not exist.
Never build up an SQL string like that. See SQL injection.
Why are you using like? Do you really have Sql wildcards in that fileName?
Example (sorry for the "SqlCommand stuff", but it's important):
string sql = "select count(*) from TrainingVideo2 where VideoURL = #Name and Status=1"
using (SqlConnection conn = new SqlConnection(connString))
{
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.Add("#Name", fileName);
conn.Open();
return (Int32)cmd.ExecuteScalar() > 0;
}

What does "WHERE x = ?" mean in SQL

This code is written in C# and it is calling database to get the data from it. But I don't understand what does "WHERE b.CompRec = ?" mean
public string GetFileNameAndTitle(int compRec)
{
string fileNameAndTitle = "";
string sql = "SELECT a.FileName, a.Title FROM (Files a INNER JOIN Components b ON a.RecNo=b.FileRec) WHERE b.CompRec = ?";
using (OleDbCommand cmd = new OleDbCommand(sql, cn))
{
cmd.Parameters.AddWithValue("#CompRec", compRec);
OpenConnection(); }
It is a parameterized statement.
cmd.Parameters.AddWithValue("#CompRec", compRec);
That line sets the actual value when the query is executed at the server. This prevents SQL Injection and is the 100% right approach!
It's basically a placeholder where you will put data later. This lets you split up your SQL statement from the data used in the query. This is the syntax of parameterized statements.

Passing values from variables to Insert query in C#, ASP.NET for SQL Server database

I am using jQuery to post back values and its successfully posting back to server I checked with Mozilla FireBug. I am using these values in the insert query in .CS file to insert data in a table. The same query runs successfully in SQL Server Management Studio but when I use this query in .CS file it's not running.
Here is my code:
public static bool SaveCell(string row, string column)
{
var con = new SqlConnection("Data Source=local;Initial Catalog=Test;Integrated Security=True");
using (con)
using (var command = new SqlCommand("Insert into Match_Subcategory_BusinessSector5(SubCategoryID, BusinessSector5ID)"+
"Values("+
"(Select [SubCategory].ID from SubCategory where Kategorie = '#SubCategory')," +
"(SELECT [BusinessSector5].ID FROM BusinessSector5 where Description_DE = '#BusinessSector5'));",con))
{
command.Parameters.AddWithValue("#BusinessSector5", row);
command.Parameters.AddWithValue("#SubCategory", column);
con.Open();
command.ExecuteNonQuery();
}
return true;
}
I am getting this error:
The value NULL can not be inserted into the SubCategoryID column, Test.dbo.Match_Subcategory_BusinessSector5 table. The column does not allow nulls.
Chnage
'#SubCategory'
to
#SubCategory
And
'#BusinessSector5'
to
#BusinessSector5
When using parameterized query you don't need to add anything arround the parameter name, it is not combined in your code, but being sent to the server separately (it sends the sql as you wrote it and a list of parameters). Because of that, you are protected againts sql injections and related problems.
"(Select [SubCategory].ID from SubCategory where Kategorie = #SubCategory)," +
"(SELECT [BusinessSector5].ID FROM BusinessSector5 where Description_DE = #BusinessSector5));",con))
remove quotes from your query

Understanding of nested SQL in C#

using (var connection = new SqlConnection(...))
{
string sql = "SELECT * FROM tableA";
using (var command = new SqlCommand(sql,connection))
{
using (var reader = command.ExecuteReader(...))
{
//***************Sample Start
string sql2 = "INSERT into tableB(column1) VALUES('"+reader["column1"]+"')";
using (var command2 = new SqlCommand(sql2,connection))
{
...
}
//***************Sample End
}
}
}
By using the above code snippet, I believe its the best practice to deal with SQL in C#. Now after I retrieve a list of records from tableA, for each of the row I would like to insert into tableB.
However, it's throwing an exception
There is already an open DataReader associated with this Command which must be closed first
I know this problem can be solved by creating another method and insert into the table from there, I'm wondering if there is any other way. Thanks for any input.
You need to use a different sql connection for the insert than for the select...
...but we can do even better. You can re-write this to be one sql statement, like so:
INSERT into tableB(column1)
SELECT column1 FROM tableA
And then run it all at once like this:
string sql = "INSERT into tableB(column1, column2) SELECT column1, #othervalue As column2 FROM tableA;";
using (var connection = new SqlConnection(...))
using (var command = new SqlCommand(sql,connection))
{
command.Paramters.Add("#othervalue", SqlDbType.NVarChar, 50).Value = "something";
connection.Open();
command.ExecuteNonQuery();
}
The single sql statement is typically much faster, and you end up with less code, too. I understand that this is likely a simplified example of your real query, but I promise you: you can re-write it all as one statement.
Additionally, sometimes you still want to do some client-side processing or display with the new records after the insert or update. In that case, you still only need to send one call to the database, but there will be two separate sql statements in that single call. The final code would look more like this:
string sql = "INSERT into tableB(column1, column2) SELECT column1, #othervalue As column2 FROM tableA;"
sql += "SELECT columnn1, #othervalue As column2 FROM tableA;";
using (var connection = new SqlConnection(...))
using (var command = new SqlCommand(sql,connection))
{
command.Paramters.Add("#othervalue", SqlDbType.NVarChar, 50).Value = "something";
connection.Open();
using (var reader = command.ExecuteReader() )
{
while (reader.Read() )
{
//...
}
}
}
And because someone else brought up MARS (multiple active result sets), I'll add that while this can work, I've had mixed results using it for inserts/updates. It seems to work best when everything that shares a connection is only doing reads.
As has been mentioned in comments, you need a separate database connection for the insert. Each connection can handle one active statement at a time, and you have two here - one for the SELECT, one (at a time) for the INSERT.
Try this for instance:
string srcqry = "SELECT * FROM tableA";
using (SqlConnection srccon = new SqlConnection(ConnectionString))
using (SqlCommand srccmd = new SqlCommand(srcqry, srccon))
{
srccon.Open();
using (SqlDataReader src = srccmd.ExecuteReader())
{
string insqry = "INSERT INTO tableB(column1) VALUES(#v1)";
// create new connection and command for insert:
using (SqlConnection inscon = new SqlConnection(ConnectionString))
using (SqlCommand inscmd = new SqlCommand(insqry, inscon))
{
inscmd.Parameters.Add("#v1", System.Data.SqlDbType.NVarChar, 80);
inscon.Open();
while (src.Read())
{
inscmd.Parameters["#v1"].Value = src["column1"];
inscmd.ExecuteNonQuery();
}
}
}
}
Using parameters solves the SQL Injection vulnerability. You should always do this rather than building the query string from raw user input, or from data that you're pulling from a database, or... well, always. Write some helper methods to make it easier if you like, just make sure you do it.
aside from a bad example, why not just simplify the query to
insert into TableB (column1) select column1 from TableA

Categories

Resources