What is the correct way to concatenate a variable when using the oledb command function in c# for a sql query. To apply some context im trying to make what a list box displays dependent on another selection made on a previous list box.This is what I've tried but doesn't work.
OleDbCommand projects = new OleDbCommand("SELECT * FROM Client_projects
WHERE clients = " + (listBox1.SelectedItem.ToString()) , conn);
OleDbDataReader project = projects.ExecuteReader();
while (project.Read())
{
// Add items from the query into the listbox
listBox2.Items.Add(project[1].ToString());
}
String concatenation can lead to SQL Injection problems so you should not use it to build SQL. You should parameterize your query. So something like this...
using (OleDbCommand projects = new OleDbCommand("SELECT * FROM Client_projects WHERE clients = ?", conn))
{
projects.Parameters.Add("?", OleDbType.VarChar).Value = listBox1.SelectedItem.ToString();
OleDbDataReader project = projects.ExecuteReader();
while (project.Read())
{
listBox2.Items.Add(project[1].ToString());
}
}
OleDbCommand Parameters are set in the order they are specified in the SQL, so if you have more than one you must do them in order.
using (OleDbCommand projects = new OleDbCommand("SELECT * FROM Client_projects WHERE clients = ? AND Date = ?", conn))
{
projects.Parameters.Add("?", OleDbType.VarChar).Value = listBox1.SelectedItem.ToString();
projects.Parameters.Add("?", OleDbType.Date).Value = DateTime.Today;
OleDbDataReader project = projects.ExecuteReader();
while (project.Read())
{
listBox2.Items.Add(project[1].ToString());
}
}
You are not using it but for other who might, SqlCommand uses named parameters...
SELECT * FROM Client_projects WHERE clients = #Clients
projects.Parameters.Add("#Clients", SqlDbType.VarChar).Value = listBox1.SelectedItem.ToString();
Related
I am trying to use MYSQL select query with c#.
Following query for searching "ID" is working fine:
conn = new MySqlConnection(cs);
conn.Open();
cmd = conn.CreateCommand();
cmd.CommandText = "select * from catalog_product_entity where entity_id = ?Id";
MySqlDataAdapter adp = new MySqlDataAdapter(cmd);
cmd.Parameters.Add("?Id", SqlDbType.Text).Value = ProductList[i].ProductId.ToString();
adp.Fill(MagentoProduct);
Now, I want to search exact string value in table. I am using following code and its giving empty result:
My Code:
conn = new MySqlConnection(cs);
conn.Open();
cmd = new MySqlCommand("select * from catalog_category_entity_varchar where value = #Value;", conn);
cmd.Parameters.AddWithValue("#Value", "Storybooks");
MySqlDataReader r = cmd.ExecuteReader();
while (r.Read())
{
log.WriteEntry(r.GetString("value"));
}
This is the problem:
where value = '?cname'
That's specifying ?cname as the literal value you're searching for - when you actually just want the parameter. Remove the quotes and it should be fine:
where value = ?cname
(You should use using statements for the connection and command, mind you...)
You could try SQL Reader
c = new MySqlCommand("select * from catalog_product_entity where column_nam = #Value;", conn);
c.Parameters.AddWithValue("#Value", your string);
MySqlDataReader r = c.ExecuteReader();
and then use Reader methods like reader.GetString("column_name"), ....
So i've been making a simple c# win forms application for something league of legends related and i've been using a .SDF Database which I'm very new with.
When trying to make a search option I came across this error:
A Parameter is missing. [Parameter ordinal = 1]
Here is my Code: (I did Add the Parameter to the command.)
public DataTable GetDataTableSummoners(string Summoner, string Champion)
{
DataTable t = new DataTable();
try
{
var cmd = new SqlCeCommand();
cmd.CommandText = "SELECT * FROM Summoner";
if (!String.IsNullOrEmpty(Summoner))
{
SqlCeParameter param = new SqlCeParameter();
param.ParameterName = "#Summoner";
param.Value = Summoner;
cmd.Parameters.Add(param);
cmd.CommandText = "SELECT * FROM Summoner WHERE name = #Summoner";
}
var adapter = new SqlCeDataAdapter(cmd.CommandText, conn);
adapter.Fill(t);
}
catch (System.Data.SqlServerCe.SqlCeException ex)
{
System.Diagnostics.Debug.Print("Error: " + ex.Message);
}
return t;
}
You're adding the parameter to the command - but then you're ignoring the command itself here:
var adapter = new SqlCeDataAdapter(cmd.CommandText, conn);
You're only passing in the command text, which doesn't include the parameter. You want:
var adapter = new SqlCeDataAdapter(cmd, conn);
(I'd also suggest using a using statement for the command, and changing your method parameter names to follow .NET naming conventions. Oh, and you don't appear to be using the champion parameter...)
Oh, and you can add a parameter much more easily like this (also specifying the type, which is a good idea):
cmd.Parameters.Add("#Summoner", SqlDbType.NVarChar).Value = Summoner;
In DataAdapter Pass complete Command Object not only Command Text
var adapter = new SqlCeDataAdapter(cmd, conn);
or You can add parameter like this
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(commandText, connection);
command.Parameters.Add("#ID", SqlDbType.Int);
command.Parameters["#ID"].Value = customerID;
}
or you can use command.Parameters.AddWithValue also.
I have an ODBC connection to a database and I would like the user to be able to view data within any table. As this is an ASP.net application I cannot trust that the table name sent doesn't also contain nasties. I have tried using a parameterised query but I always get an error saying that I "Must declare the table variable" - this appears to be an issue because it is the table name
string sql = "SELECT TOP 10 * FROM ? ";
OdbcCommand command = new OdbcCommand(sql, dbConnection);
command.Parameters.Add(new OdbcParameter("#table", tableName));
OdbcDataAdapter adapter = new OdbcDataAdapter();
adapter.SelectCommand = command;
adapter.Fill(tableData);
What is the best method to achieve this in a secure way?
Use a stored procedure, it's the safest way.
Some hints:
You probably may also use the System.Data.SqlClient namespace objects
Enclose your connection, command and adapter objects initializations in using statements
Here's a simple example:
string sqlStoredProcedure = "SelectFromTable";
using (OdbcConnection dbConnection = new OdbcConnection(dbConnectionString))
{
dbConnection.Open();
using (OdbcCommand command = new OdbcCommand(sqlStoredProcedure, dbConnection))
{
command.CommandType = System.Data.CommandType.StoredProcedure;
command.Parameters.Add(new OdbcParameter("#table", tableName));
using (OdbcDataAdapter adapter = new OdbcDataAdapter(command))
{
adapter.SelectCommand = command;
adapter.Fill(tableData);
}
}
}
Another way to go would be to retrieve all table names and validate the tableName string variable as an entry in the list, maybe using:
DataTable tables = dbConnection.GetSchema(OdbcMetaDataCollectionNames.Tables);
Here's a simple implementation based on your scenario:
string sql = "SELECT TOP 10 * FROM {0}";
using (OdbcConnection dbConnection = new OdbcConnection(dbConnectionString))
{
dbConnection.Open();
DataTable tables = dbConnection.GetSchema(OdbcMetaDataCollectionNames.Tables);
var matches = tables.Select(String.Format("TABLE_NAME = '{0}'", tableName));
//check if table exists
if (matches.Count() > 0)
{
using (OdbcCommand command = new OdbcCommand(String.Format(sql, tableName), dbConnection))
{
using (OdbcDataAdapter adapter = new OdbcDataAdapter(command))
{
adapter.SelectCommand = command;
adapter.Fill(tableData);
}
}
}
else
{
//handle invalid value
}
}
i m trying to retrieve the Specialization ID from a table called Specializationtbl, using C# MSVS 2008 and the table includes SpecializationName and SpecializationID beside some other rows and my question is related to some error " No Data to present ", the command goes as bellow:
SqlCommand READSpecID = new SqlCommand("SELECT * FROM Specializationtbl WHERE SpecializationName='" + comboBox1.Text + "'" , DBcnction);
DBcnction.Open();
SqlDataReader ReadSpecID_ = READSpecID.ExecuteReader();
ReadSpecID_.Read();
int SpecID_ = Convert.ToInt16(ReadSpecID_["SpecID"].ToString());
DBcnction.Close();
i also tried to Select the "SpecID" instead of all the rows, but cant seem to seal the query correctly and keep receiving "No data present " error, any idea where am i making the mistake?
1) Try opening DBcnction before assigning the value to READSPecID
DBcnction.Open();
SqlCommand READSpecID = new SqlCommand("SELECT * FROM Specializationtbl WHERE SpecializationName='" + comboBox1.Text + "'" , DBcnction);
2) Run the command in SSMS:
SELECT * FROM Specializationtbl WHERE SpecializationName ='yourvalue'
and see if any results are returned
3) Check comboBox1.Text has a value in it
4) Validate the contents of comboBox1.Text (Or use paremetrised queries or a stored procedure) to ensure you do not become a victim of SQL Injection: http://en.wikipedia.org/wiki/SQL_injection
Refactor to solve your TWO problems:
Your SQL injection problem when building your SQL statement.
Use ExecuteScalar if you only need one value.
Implement using blocks.
string retVal;
using (var conn = new SqlConnection(SomeConnectionString))
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "SELECT SpecID FROM Specializationtbl WHERE SpecializationName= #Name";
cmd.Parameters.AddWithValue("#Name", comboBox1.Text);
conn.Open();
retVal = cmd.ExecuteScalar().ToString();
}
int specID = int.Parse(retVal);
If you really needed more than one value from your statement:
using (var conn = new SqlConnection(SomeConnectionString))
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "SELECT SpecID, Value2 FROM Specializationtbl WHERE SpecializationName= #Name";
cmd.Parameters.AddWithValue("#Name", comboBox1.Text);
conn.Open();
var dr = cmd.ExecuteReader();
while (dr.Read())
{
Customer c = new Customer {
ID = dr["SpecID"].ToString(),
Value = dr["Value2"].ToString(),
};
}
}
Need to first test if there are any rows. I suspect the query is returning zero rows.
if (ReadSpecID_.HasRows)
{
ReadSpecID_.Read();
}
i have database in access with auto increase field (ID).
i insert record like this (in C#)
SQL = "insert into TermNumTbl (DeviceID,IP) values ('" + DeviceID + "','" + DeviceIP + "') ";
OleDbCommand Cmd = new OleDbCommand(SQL, Conn);
Cmd.ExecuteNonQuery();
Cmd.Dispose();
Conn.Close();
how to get the last inserting number ?
i dont want to run new query i know that in sql there is something like SELECT ##IDENTITY
but i dont know how to use it
thanks in advance
More about this : Getting the identity of the most recently added record
The Jet 4.0 provider supports ##Identity
string query = "Insert Into Categories (CategoryName) Values (?)";
string query2 = "Select ##Identity";
int ID;
string connect = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|Northwind.mdb";
using (OleDbConnection conn = new OleDbConnection(connect))
{
using (OleDbCommand cmd = new OleDbCommand(query, conn))
{
cmd.Parameters.AddWithValue("", Category.Text);
conn.Open();
cmd.ExecuteNonQuery();
cmd.CommandText = query2;
ID = (int)cmd.ExecuteScalar();
}
}
I guess you could even write an extension method for OleDbConnection...
public static int GetLatestAutonumber(
this OleDbConnection connection)
{
using (OleDbCommand command = new OleDbCommand("SELECT ##IDENTITY;", connection))
{
return (int)command.ExecuteScalar();
}
}
I like more indicate the type of command
is very similar to the good solution provided by Pranay Rana
using (OleDbCommand cmd = new OleDbCommand())
{
cmd.CommandType = CommandType.Text;
cmd.CommandText = sql_Insert;
cmd.ExecuteNonQuery();
cmd.CommandText = sql_obtainID;
resultado = (int)comando.ExecuteScalar();
}
query = "Insert Into jobs (jobname,daterecieved,custid) Values ('" & ProjectNAme & "','" & FormatDateTime(Now, DateFormat.ShortDate) & "'," & Me.CustomerID.EditValue & ");"'Select Scope_Identity()"
' Using cn As New SqlConnection(connect)
Using cmd As New OleDb.OleDbCommand(query, cnPTA)
cmd.Parameters.AddWithValue("#CategoryName", OleDb.OleDbType.Integer)
If cnPTA.State = ConnectionState.Closed Then cnPTA.Open()
ID = cmd.ExecuteNonQuery
End Using
Using #Lee.J.Baxter 's method (Which was great as the others id not work for me!) I escaped the Extension Method and just added it inline within the form itself:
OleDbConnection con = new OleDbConnection(string.Format(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source='{0}'", DBPath));
OleDbCommand cmd = con.CreateCommand();
con.Open();
cmd.CommandText = string.Format("INSERT INTO Tasks (TaskName, Task, CreatedBy, CreatedByEmail, CreatedDate, EmailTo, EmailCC) VALUES('{0}','{1}','{2}','{3}','{4}','{5}','{6}')", subject, ConvertHtmlToRtf(htmlBody), fromName, fromEmail, sentOn, emailTo, emailCC);
cmd.Connection = con;
cmd.ExecuteScalar();
using (OleDbCommand command = new OleDbCommand("SELECT ##IDENTITY;", con))
{
ReturnIDCast =(int)command.ExecuteScalar();
}
NOTE: In most cases you should use Parameters instead of the string.Format() method I used here. I just did so this time as it was quicker and my insertion values are not coming from a user's input so it should be safe.
Simple,
What we do in excel for copy text in above cell?
Yes, just ctrl+" combination,
and yes, it's work in MS ACCESS also.
You can use above key stroke combination for copy above records field text, just make sure if you have duplicate verification applied or edit field data before move next field.
If you aspects some more validation or any extraordinary then keep searching stack overflow.