i have design an access query which seem like this:
SELECT Replace(names,'lion','kiss') AS Expr1
FROM table1;
the two values that is lion and kiss, which are temporary, now i want these to be two variables, so that i can pass value to it from c#.
how to call this query from c#, and pass it two values.
I am using access 2007.
Thanks for your help :)
Try something like this (I found this on the subject):
public void ReplaceColumnA(string oldvalue, string newvalue)
{
using(OleDbConnection connection1 = (OleDbConnection)DatabaseConnection.Instance.GetConnection())
{
connection1.Open();
using(OleDbCommand sqlcmd2 = new OleDbCommand("queryname", connection1))
{
sqlcmd2.Parameters.AddWithValue("param1", newvalue);
sqlcmd2.Parameters.AddWithValue("param2", oldvalue);
sqlcmd2.ExecuteNonQuery();
}
}
}
The Access query would look like this:
UPDATE [t]
SET [a] = ?
WHERE [a] = ?
The names of the parameters you pass on don't matter, it's the order you pass them as.
By using the "using" statement you are ensure .NET is properly releasing the connections and resources.
Additionally I STRONGLY recommend switching to SQL Server Express Edition. It's free and a LOT more potent than what you can cook up in Access. Really, you're just shooting yourself in the foot continuing in Access...
You execute it like this:
sqlcmd2.ExecuteNonQuery();
I think you need to modify code like this
string q = "SELECT Replace(names,'{0}','{1}') AS Expr1 FROM table1";
//You can provide any values instead of LION and KISS
string query = string.format(q,"LION","KISS")
using(OleDbConnection cnn = (OleDbConnection)DatabaseConnection.Instance.GetConnection())
{
cnn.Open();
using(OleDbCommand cmd = new OleDbCommand(query, cnn))
{
OleDbDataReader reader = cmd.ExecuteReader();
while(reader.Read())
{
Console.WriteLine(reader["Expr1"].toString());
}
}
}
Related
How would I delete a row from a sql database, either with stored procedures or without, right now I have tried without, using a button press.
This is what I have so far, _memberid has been sent over from a differnt form from the database(For context).
private void btnDelete_Click(object sender, EventArgs e)
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = Lib.SqlConnection;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "Delete * From Members where MemberId = " + _memberId;
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.DeleteCommand = cmd;
adapter.Fill(MembersDataTable); // Im fairly sure this is incorrect but i used it from old code
DialogResult = DialogResult.OK;
}
If you're trying to do a simple ADO.Net-based delete, then it would be somehting like his:
private void DeleteById(int memberId)
{
// or pull the connString from config somewhere
const string connectionString = "[your connection string]";
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
using (var command = new SqlCommand("DELETE FROM Members WHERE MemberId = #memberId", connection))
{
command.Parameters.AddWithValue("#memberId", memberId);
command.ExecuteNonQuery();
}
}
Use parameter to prevent SQL injection.
There are essentially three main things I'm seeing...
One
You don't need the * in the query. DELETE affects the whole row, so there's no need to specify columns. So just something like:
DELETE FROM SomeTable WHERE SomeColumn = 123
Two
There's no need for a SqlDataAdapter here, all you need to do is execute the query. For example:
cmd.ExecuteNonQuery();
The "non query" is basically a SQL command which doesn't query data for results. Inserts, updates, and deletes are generally "non queries" in this context. What it would return is simply the number of rows affected, which you can use to double-check that it matches what you expect if necessary.
Three
Don't do this:
cmd.CommandText = "Delete From Members where MemberId = " + _memberId;
This kind of string concatenation leads to SQL injection. While it looks intuitively like you're using _memberId as a query value, technically you're using it as executable code. It's less likely (though not impossible) to be a problem for numeric values, but it's a huge problem for string values because it means the user can send you any string and you'll execute it as code.
Instead, use query parameters. For example, you might do something like this:
cmd.CommandText = "Delete From Members where MemberId = #memberId";
cmd.Parameters.Add("#memberId", SqlDbType.Int);
cmd.Parameters["#memberId"].Value = _memberId;
This tells the database engine itself that the value is a value and not part of the executing query, and the database engine knows how to safely handle values.
You could use a DataAdapter, but since you aren't using a datatable, it's just easier to do it without like this:
var sql = "DELETE FROM Members WHERE MemberId=#MemberId";
using(var cmd = new SqlCommand(sql, Lib.SqlConnection))
{
cmd.Connection.Open();
cmd.Parameters.Add("#MemberId",SqlDbType.Int).Value = _memberId;
cmd.ExecuteNonQuery();
}
And if you are using Dapper, you can do this:
Lib.SqlConnection.Execute("DELETE FROM Members WHERE MemberId=#MemberId", new {MemberId=_memberId});
If you are still using DataTables, I would highly recommend you look into using this (or something like this) to simplify your database accesses. It'll make CRUD logic on a database a breeze, and your code will me a lot more maintainable because you can get rid of all the odd needs to do casting, boxing/unboxing, and reduce the chances of runtime bugs because of the use of magic strings that happens so often with DataTables (column names). Once you start working with POCO classes, you'll hate having to use DataTables. That said, there are a few places where DataTables are a better solution (unknown data structures, etc), but those are usually pretty rare.
i'm fetching values from a table with datareader like this:
string query = #"SELECT XMLConfig, Enable FROM TableCfg";
using (SqlConnection cnction = new SqlConnection(cnnstr))
{
cnction.Open();
using (SqlCommand sqlCmd = new SqlCommand(query, cnction))
{
SqlDataReader dtRead = sqlCmd.ExecuteReader();
while (dtRead.Read())
{
xmlConf = dtRead.GetString(0);
enabl = dtRead.GetString(1);
}
dtRead.Close();
}
}
The Enable field is a boolean(True/False). Is there a way to fetch only the rows, where field enable="True"?
I tried using LINQ, but i'm new to this and i must be doing something wrong.
using (SqlCommand sqlCmd = new SqlCommand(query, cnction))
{
SqlDataReader dtRead = sqlCmd.ExecuteReader();
var ob =(from IDataRecord r in sqlCmd.ExecuteReader()
where r.GetString(3).ToString() == "True"
select "Enable");
}
Help me please.
Best Regards.
You should really do as much filtering as possible at the database side rather than client-side:
string query = "SELECT XMLConfig FROM TableCfg WHERE Enable = True";
Notice how now you don't even need to fetch Enable, as you already know it will be True for all the matching rows.
You should also consider using LINQ to SQL or Entity Framework rather than the rather low-level stack you're currently using. It's not always appropriate, but it does make things cleaner where it's suitable.
I'm really new to DB programming, and I'm throwing together a little test project that uses ado.net to interact with a MS Access database. I looked around online for the "best practice" way to do it, but couldn't find an up-to-date answer that I trusted.
I just want the "modern" way to insert into an access DB via ado.net while preventing SQL injection attacks. And if there's anything else I should be keeping in mind, let me know that too.
Oh and by the way, I'm aware that there are better options than MS Access. However, I'm doing this at work on lunch breaks and stuff, and my employer would prefer I don't clutter up SQL server space with silly DBs like this.
You could try Dapper. This is a way to execute arbitrary SQL against anything that implements IDbConnection in a manner which avoids SQL injection attacks and has a nice, clean, modern interface.
Failing that, just use OleDbCommand.Parameters.AddWithValue("fieldname", yourobj); (or the OdbcCommand equivalent. Your query would need to contain question marks as parameter placeholders. For Access, you need to add your arguments to the parameters collection in the same order as the fields appear in the SQL query, like this:
Selecting
string sql = "select * from mytable where MyField LIKE ? and MyOtherField = ?";
// Dapper
using (OleDbConnection dbConn = new OleDbConnection("your connection string))
{
dbConn.Open();
var result = dbConn.Query(sql, new { MyField = "some value", MyOtherField = 3 });
foreach (dynamic myrow in result)
{
// you can get at your table rows using myrow.MyField, myrow.SomeOtherField etc
// To avoid myrow being dynamic, call dbConn.Query<T> where T is some type you
// define that matches your table definition
}
}
// The "old-fashioned" way
using (OleDbConnection dbConn = new OleDbConnection("your connection string))
using (OleDbCommand dbCmd = dbConn.CreateCommand())
{
dbConn.Open();
dbCmd.CommandText = sql;
dbCmd.Parameters.AddWithValue("MyField", "some value"));
dbCmd.Parameters.AddWithValue("MyOtherField", 3));
OleDbDataReader reader = dbCmd.ExecuteReader();
while (reader.Read())
{
string myfield = reader["myfield"] == DBNull.Value ? null : (string)reader["myfield"];
int SomeOtherField = reader["someotherfield"] == DBNull.Value ? 0 : (int)reader["someotherfield"];
}
}
Inserting
string sql = "insert into mytable (MyField, MyOtherField) values (?, ?)";
// Dapper
using (OleDbConnection dbConn = new OleDbConnection("your connection string))
{
dbConn.Open();
dbConn.Execute(sql, new { MyField = "some value", MyOtherField = 3 });
}
// The "old-fashioned" way
using (OleDbConnection dbConn = new OleDbConnection("your connection string))
using (OleDbCommand dbCmd = dbConn.CreateCommand())
{
dbConn.Open();
dbCmd.CommandText = sql;
dbCmd.Parameters.AddWithValue("MyField", "some value"));
dbCmd.Parameters.AddWithValue("MyOtherField", 3));
dbCmd.ExecuteNonQuery(sql);
}
Access is also very picky about numeric types when writing code that moves data from objects to and from the database, if I remember correctly. You need to make sure that you are casting to and from exactly the correct types.
I am interesting to add parametrize sql queries in my ASP.net application. I have seen some good articles regarding Avoid SQL Injection.
string sql = string.Format("INSERT INTO [UserData] (Username, Password, Role, Membership, DateOfReg) VALUES (#Username, #Password, #Role, #Membership, #DateOfReg)");
SqlCommand cmd = new SqlCommand(sql, conn);
try
{
cmd.Parameters.AddWithValue("Username", usernameTB.Text);
cmd.Parameters.AddWithValue("Password", passwordTB.Text);
cmd.Parameters.AddWithValue("Role", roleTB.Text);
cmd.Parameters.AddWithValue("Membership", membershipTB.Text);
cmd.Parameters.AddWithValue("DateOfReg", dorTB.Text);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
find the Reference
However this way is not useful to me since I couple the DB connection to separate class since I have reuse it.
public class DBconnection{
public int insertQuery(String query) {
int affectedRowCount = 0;
SqlConnection conn = null;
try{
conn = new SqlConnection("Server=localhost;Database=master;UID=sa;PWD=sa;");
SqlCommand cmd = new SqlCommand( query, conn );
cmd.CommandType = CommandType.Text;
conn.Open( );
affectedRowCount = cmd.ExecuteNonQuery( );
conn.Close( );
} catch ( Exception e ){
String error = e.Message;
}
return affectedRowCount;
}
}
Therefore I only use bellow code part to call above class and Insert values to DB.
String SQLQuery1 = insert into Article values('" + Txtname.Text + "','" + TxtNo.Text + "','" + Txtdescription.Text + "' ,0)");
DBconnection dbConn = new DBconnection();
SqlDataReader Dr = dbConn.insertQuery(SQLQuery1);
Please help me to use Parameterize sqlString to Avoid me Sql Injection.
To use #name , # No and #description without use Textbox inputs.
It's perfectly reasonable to do this, but have your class call back (lambda/delegate) out to get the parameters. This is a static method in a class which is called by various overloaded instance methods:
private static int SqlExec(string ConnectionString, string StoredProcName, Action<SqlCommand> AddParameters, Action<SqlCommand> PostExec)
{
int ret;
using (var cn = new SqlConnection(ConnectionString))
using (var cmd = new SqlCommand(StoredProcName, cn))
{
cn.Open();
cmd.CommandType = CommandType.StoredProcedure;
if (AddParameters != null)
{
AddParameters(cmd);
}
ret = cmd.ExecuteNonQuery();
if (PostExec != null)
{
PostExec(cmd);
}
}
return ret;
}
Then, a usage example:
public void Save()
{
Data.Connect().Exec("Project_Update", Cm =>
{
Cm.Parameters.AddWithValue("#ProjectID", ID);
Cm.Parameters.AddWithValue("#PrimaryApplicantID", PrimaryApplicant.IdOrDBNull());
Cm.Parameters.AddWithValue("#SecondaryApplicantID", SecondaryApplicant.IdOrDBNull());
Cm.Parameters.AddWithValue("#ProjectName", ProjectName.ToDBValue());
});
}
It's also possible to do this with non-stored procedure calls.
In your case it would look like:
DBconnection.InsertQuery(
"INSERT INTO [UserData]
(Username, Password, Role, Membership, DateOfReg)
VALUES (#Username, #Password, #Role, #Membership, #DateOfReg)"
,cmd => {
cmd.Parameters.AddWithValue("Username", usernameTB.Text);
cmd.Parameters.AddWithValue("Password", passwordTB.Text);
cmd.Parameters.AddWithValue("Role", roleTB.Text);
cmd.Parameters.AddWithValue("Membership", membershipTB.Text);
cmd.Parameters.AddWithValue("DateOfReg", dorTB.Text);
}
);
Which puts all your database stuff together the way you want and lets the DBconnection keep its internals isolated.
How about instead of a generic InsertQuery() method you write specific InsertQuery methods?
For example:
public void AddNewUser(User u)
{
var query = "insert Users (name, password) values (#0, #1)";
SqlCommand cmd = new SqlCommand(query, conn);
try
{
cmd.Parameters.AddWithValue("#0", u.UserName);
cmd.Parameters.AddWithValue("#1", u.Password);
}
}
This has the advantage of ALL your SQL logic being in this other class, as opposed to the calling class needing to know how to construct the query etc.
It also makes your code more readable, because you see AddUser or UpdateUser or ChangePassword as method calls, and don't have to read SQL at that moment to try and guess what is going on in the program.
HOWEVER if you're going to do something like this, you should check out some MicroORMs, my personal favorite is PetaPoco (or the NuGet version)
PetaPoco and others like Massive and Dapper would let you do something like:
database.Insert(u);
Where u is a User object that maps to your DB's table. It uses ADO.NET and makes sure to use SQL Parameters.
I would suggest using LINQ to SQL, which automatically parametrizes everything.
Q. How is LINQ to SQL protected from SQL-injection attacks?
A. SQL injection has been a significant risk for traditional SQL queries formed by concatenating user input. LINQ to SQL avoids such injection by using SqlParameter in queries. User input is turned into parameter values. This approach prevents malicious commands from being used from customer input.
You can insert, update and delete from a SQL database in a straightforward manner using a DataContext (right-click on your project to add a new item and add the LINQ to SQL Classes template, then use the Server Explorer to add objects to it).
I haven't worked with this in a while, but I believe your code would then look somewhat like this:
UserData user = new UserData();
user.Username = ...;
user.Password = ...;
user.Role = ...;
user.Membership = ...;
user.DateOfReg = ...;
db.UserDatas.InsertOnSubmit(user);
db.SubmitChanges();
When you call SubmitChanges, LINQ to SQL automatically generates and executes the SQL commands that it must have to transmit your changes back to the database.
Edit1:
As an added note, to retrieve an existing item from a database, you could do this:
var user = (from i in db.UserDatas
where i.UserName == "devan"
select i).Single();
Oh, and as is my standard policy when answering questions about databases with login information, I must implore you, for the love of god and all that is holy, to salt and hash your users' passwords.
I am writing a console program in C# and I need to use a database.
I am looking for very basic tutorials on connecting with and using a db from a C# console program. I haven't been able to find anything basic enough yet and I hope people here can help me find the info I need. I've read the material on MSDN, but MSDN assumes basic knowledge about these things that I am still looking for.
I have created a db within VS Express in my project, created tables, and written some starter records into the tables. I'm trying to find out exactly what each of these things is, and how to determine how to apply them in my project:
SQLConnection
SQLConnection class
SQLCommand
SQLDataAdapter
DataSets
Thanks.
Something like:
using System.Data;
using System.Data.SqlClient;
using(SqlConnection connection = new SqlConnection("")){
SqlCommand command = new SqlCommand(#"
insert into
tblFoo (
col1,
col2
) values (
#val1,
#val2
)",
connection
);
SqlParameter param = new SqlParameter("#val1", SqlDbType.NVarChar);
param.Value = "hello";
command.Parameters.Add(param);
param = new SqlParameter("#val2", SqlDbType.NVarChar);
param.Value = "there";
command.Parameters.Add(param);
command.ExecuteNonQuery();
connection.Close();
}
-- Edit:
Though, of course, when you start doing serious things, I recommend an ORM. I use LLBLGen (it costs money, but most definitely worth it).
-- Edit:
SqlConnection
The thing through which you communicate to the database. This will hold the name of the
server, the username, password, and other misc things.
SqlCommand
Something that holds the sql statement you want to send to the server. This may be an 'update' or 'insert' or 'select' or anything. Depending on what it is, you use a different method to execute it, to possible get data back.
SqlDataAdapter
A strange one; it's used specifically to fill a 'DataSet'. It basically does a bit of work for you, adding the information it finds to the set.
DataSet
Not sure how simple you want this. It's just a collection of returned data, in a table-like format, that you can iterate over. It contains DataTables, because some queries can return more than one table. Typically, though, you'll only have one table, and you can bind to it, or whatever.
Create a sqlconnection, Open it, Create a sqlcommand, execute it to get a sqldatareader, voila. You won't need a dataadapter for a simple example.
string connectionString = "...";
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
string sql = "select field from mytable";
SqlCommand cmd = new SqlCommand(sql, conn);
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
Console.WriteLine(rdr[0]);
}
}
There's a tutorial on ADO.NET that covers a lot of the things you're looking for at http://www.csharp-station.com/Tutorials/AdoDotNet/Lesson01.aspx. Lesson 1 is mostly background but lesson 2 and onwards goes over SQL client objects.
Another tutorial at http://www.codeproject.com/KB/database/sql_in_csharp.aspx covers some of the basics (SqlConnection, SqlCommand).
I bought a book called Pragmatic ADO.NET.
Well, there are two ways to interact with a SQL Server database in C#. The first is with LINQ, and the second is with the SqlClient library.
LINQ
Ever since .NET 3.0, we've had access to LINQ, which is a pretty impressive ORM and way to deal with collections and lists. There are two different ways that LINQ can work with a database. They are:
LINQ to SQL
LINQ to Entities
Scott Gu has a pretty good tutorial on LINQ to SQL, as well. I'd recommend LINQ to SQL for just getting started, and you can use a lot of that in LINQ to Entities going forward.
A sample select to grab all customers in New York would be:
var Custs = from c in Customers
where c.State = 'NY'
select c;
foreach(var Cust in Custs)
{
Console.WriteLine(Cust.Name);
}
SqlClient
The traditional C# way to hit a SQL Server database (pre-.NET 3.0) has been via the SqlClient library. Essentially, you create a SqlConnection to open up a connection to the database. If you need help with your connection strings, check out ConnectionStrings.com.
After you've connected to your database, you will use the SqlCommand object to interact with it. The most important property for this object is the CommandText. This accepts SQL as its language, and will run raw SQL statements against the database.
If you're doing an insert/update/delete, you will use the ExecuteNonQuery method of SqlCommand. However, if you're doing a select, you will use ExecuteReader and return a SqlDataReader. You can then iterate through the SqlDataReader to get your results.
The following is the code to grab all customers in New York, again:
using System.Data;
using System.Data.SqlClient;
//...
SqlConnection dbConn = new
SqlConnection("Data Source=localhost;Initial Catalog=MyDB;Integrated Security=SSPI");
SqlCommand dbComm = new SqlCommand();
SqlDataReader dbRead;
dbConn.Open();
dbComm.Connection = dbConn;
dbComm.CommandText = "select name from customers where state = #state";
dbComm.Parameters.Add("#state", System.Data.SqlDbType.VarChar);
dbComm.Parameters["#state"].Value = "NY";
dbRead = dbComm.ExecuteReader();
if(dbRead.HasRows)
{
while(dbRead.Read())
{
Console.WriteLine(dbRead[0].ToString());
}
}
dbRead.Close();
dbConn.Close();
Hopefully this gives you a good intro to what each approach does and how to learn more.
In general, I recommend using the Microsoft Enterprise Library for DB access. I've used it in a few projects, and am very fond of it.
See the Data Access Quickstart provided by Microsoft that should help you get started
Also, I've also grown accustomed to writing Extension Methods for extracting data from DataRows. For example, I can do something like this:
//Create an extension method, Value,
//to extract a certain type from a DataRow,
//supplying a default value to be used if DbNull.Value is encountered
DateTime someDateValue = dr["SomeDatabaseField"].Value(new DateTime());
Hope this helps!
See ADO.NET Sample Application
Examples cover
SqlClient
using System;
using System.Data;
using System.Data.SqlClient;
class Sample
{
public static void Main()
{
SqlConnection nwindConn = new SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind");
SqlCommand catCMD = nwindConn.CreateCommand();
catCMD.CommandText = "SELECT CategoryID, CategoryName FROM Categories";
nwindConn.Open();
SqlDataReader myReader = catCMD.ExecuteReader();
while (myReader.Read())
{
Console.WriteLine("\t{0}\t{1}", myReader.GetInt32(0), myReader.GetString(1));
}
myReader.Close();
nwindConn.Close();
}
}
OleDb
using System;
using System.Data;
using System.Data.OleDb;
class Sample
{
public static void Main()
{
OleDbConnection nwindConn = new OleDbConnection("Provider=SQLOLEDB;Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind");
OleDbCommand catCMD = nwindConn.CreateCommand();
catCMD.CommandText = "SELECT CategoryID, CategoryName FROM Categories";
nwindConn.Open();
OleDbDataReader myReader = catCMD.ExecuteReader();
while (myReader.Read())
{
Console.WriteLine("\t{0}\t{1}", myReader.GetInt32(0), myReader.GetString(1));
}
myReader.Close();
nwindConn.Close();
}
}
Odbc
using System;
using System.Data;
using System.Data.Odbc;
class Sample
{
public static void Main()
{
OdbcConnection nwindConn = new OdbcConnection("Driver={SQL Server};Server=localhost;" +
"Trusted_Connection=yes;Database=northwind");
OdbcCommand catCMD = new OdbcCommand("SELECT CategoryID, CategoryName FROM Categories", nwindConn);
nwindConn.Open();
OdbcDataReader myReader = catCMD.ExecuteReader();
while (myReader.Read())
{
Console.WriteLine("\t{0}\t{1}", myReader.GetInt32(0), myReader.GetString(1));
}
myReader.Close();
nwindConn.Close();
}
}