I am making a project in which i have a login page.
i am restricting user to enter
AND OR NOT XOR & | ^
is this enough to prevent my application from SQL Injection?
No, not at all.
For example, I could still enter my username as:
; DELETE FROM Users --
Which could still, depending on your DB structure and application code, wipe your entire Users table.
To adequately protect yourself from SQL Injection attacks you should escape any user input and use either parameterized queries or stored procedures (and if you're using stored procedures, be sure you don't have dynamically generated SQL inside the stored procedure) to interact with the database.
You shouldn't bother looking for special words / characters in their username /password. Because you will ALWAYS miss something.
Instead, if you have embedded SQL you should be using parameterized queries. If you do that for all of your queries then you'll be safe from sql injection. Now, XSS is whole other matter.. ;)
This has been covered in depth on this site, just search for sql injection.
Using Stored Procedures or parameterized queries will prevent SQL injection.
1) In addition to that, if you are using ASP.NET, you can enable the page level attribute "ValidateRequest = True" which can validate if any of the input string can lead to Script injection
2) Make sure you dont display the actual system generated error to the end user. That will give a lead to the hacker to probe further and break the system.
3) If you are using a webservice to consume and sync the data to your database, validate all the necessary fields before persisting the data.
Definitely not!
The simplest possible way to avoid SQL injection is by using parameterized queries.
See this SO question: Preventing SQL Injection in ASP.Net VB.Net and all of its answers to give you an idea.
In short, I never use concatenated string queries, but ALWAYS parameters. This way, there is no danger at all, and this is the most secure way to prevent SQL injection.
Here is a good stack overflow link: What is SQL injection?
Secondly, don't forget that it doesn't matter what validation you do in the UI, people can always construct custom HTTP requests and send them to your server (trivial as editing using firebug).
Like others said. Parameterized inputs.
Here's a snipit from some code I wrote at work(removed work specific code). It's not perfect, but my main job is not programming and I was still researching on C# when I wrote this. If I wrote this now, I would have used a datareader instead of a dataset.
But notice how I use variables in the actual SQL string and assign the variables using "da.SelectCommand.Parameters.AddWithValue"
public Boolean Login(string strUserName, string strPassword)
{
SqlConnection sqlConn = new System.Data.SqlClient.SqlConnection();
DataSet ds = null;
SqlDataAdapter da = null;
sqlConn.ConnectionString = strConnString;
try
{
blnError = false;
sqlConn.Open();
ds = new DataSet();
da = new SqlDataAdapter("select iuserid from tbl_Table where vchusername = #vchUserName and vchpassword = #vchPassword", sqlConn);
da.SelectCommand.Parameters.AddWithValue("#vchUserName", strUserName);
da.SelectCommand.Parameters.AddWithValue("#vchPassword", strPassword);
da.SelectCommand.CommandTimeout = 30;
da.Fill(ds);
if (ds.Tables[0].Rows.Count > 0)
{
iUserId = (int)ds.Tables[0].Rows[0]["iuserid"];
}
}
catch (Exception ex)
{
blnError = true;
Log("Login: " + ex.Message);
}
finally
{
if (sqlConn.State != ConnectionState.Closed)
sqlConn.Close();
if (da != null)
da.Dispose();
if (ds != null)
ds.Dispose();
}
if (blnError)
return false;
if (iUserId > 0)
return true;
return false;
}
You should pass the values as parameters to a stored procedure. This way whatever the user enters is just treated as a value rather than appended to the statement and executed
Related
If user puts any username or password from the database it logs in. It doesn't crossmatch between the index of them. I'm working on this as a beginner learner.
if(txtusername.Text != null && txtpassword.Text != string.Empty)
{
sql = string.Format(#" select * from idpass where username ='{0}' ", txtusername.Text );
DataTable dtForNameAndRole = LoadDataByQuery(sql);
if(dtForNameAndRole.Rows.Count > 0)
{
sql = string.Format(#" select * from idpass where password ='{0}' ", txtpassword.Text);
DataTable dtForNameAndRole2 = LoadDataByQuery(sql);
if (dtForNameAndRole2.Rows.Count > 0)
{
sql = string.Format(#" select * from idpass where username = '{0}' and password ='{0}' ", txtusername.Text, txtpassword.Text);
DataTable dtForNameAndRole3 = LoadDataByQuery(sql);
Response.Redirect("Dashboard.aspx");
}
else
{
lblMessage.Text = "No Such Password";
}
}//end of if
else
{
lblMessage.Text = "no such user";
}
}
else
{
msgtr.Visible = true;
lblMessage.Text = "Sorry! Invalid user name or password.";
lblMessage.ForeColor = Color.Red;
return;
}
There are lot of issues in your existing code.
You should not store the plain password in the database.
There is no need of calling the query 3 times. Only one time is sufficient.
You should not query only on password because passwords can be same for many users.
Don’t use * in the select query. You should use the columns as aliases.
Put the breakpoint and debug your code to see what is the query you’re calling. This way you will get to know whether your query is correct or not. And you can run this query in the database as well to check whether it’s working as expected or not.
As suggested by #Larnu, please use parameterized query to prevent the sql injection. You can refer this article for the concept.
as noted, this is for learning. However, VERY important to realize that you want to use the "built in system" for logons. The reasons are too long for this post. But by using the defined built in logon system?
Then you can use the pre-made templates for logons.
You can setup security using IIS (internet services), and NOT have to hand code out a WHOLE web based security system. This will save I can figure about a whole month of solid work. And if you use the built in logon system?
Then you can even drop into a page the asp.net logon control - and it will do all the magic and coding for you - in other words, there is a HUGE system working behind the scenes to manage security and logons for you. In a nutshell?
Don't try and roll your own security system and logon system - it is FAR too much work.
Ok, now that I outlined the above, we are of course still here to learn. So, lets fix up your code you have.
So, first up, I assume that you gone project->(your project properties), and under settings have setup a connection string (don't type those in manually - set that up in settings so you don't have to code out connection strings in code. You want ONE common connecting setting, since then you have one place to change this when you get around to publishing to a actual web site.
That setting is the ones you will find here:
Ok, now our code. Like everyone, it gets a bit tiring to wear out a few keyboards ever time we need to pull some data. And eventually, you want to consider a data framework like EF (entity framework) to class out and "abstract" your data base operations.
However, when starting out - I think it is GREAT idea to try + test and play with some basic and simple database operations - such as your example sql queries.
So, first up, lets build that save world poverty's and the keyboards (so we don't have to re-code over and over some simple SQL queries)
So, lets drop in this code:
DataTable LoadDataByQuery(SqlCommand cmdSQL)
{
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
cmdSQL.Connection = conn;
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
return rstData;
}
So, now your code can become this:
As pointed out we CAN NOT and NEVER just check password alone, since many people might have the same password.
So we can check for user - or give message
Or THEN check for user + password - and give bad password message.
Also, try to code without such a lot of nesting - its hard to debug and hard to follow. I tend to like reverse the conditions, and BAIL OUT of the code when things go wrong and then keep going if code is ok. That way you remove a boatload of nested if /else.
Try this code:
if (txtusername.Text == string.Empty)
{
msgtr.Visible = true;
lblMessage.Text = "Please enter a user name";
return;
}
// check/get user
SqlCommand sql = new SqlCommand();
sql.CommandText = #" select * from idpass where username = #user";
sql.Parameters.Add("#user", SqlDbType.NVarChar).Value = txtusername.Text;
DataTable dtForNameAndRole = LoadDataByQuery(sql);
if (dtForNameAndRole.Rows.Count == 0)
{
msgtr.Visible = true;
lblMessage.Text = "no such user";
return;
}
// if we get this far, then user name = ok
// user ok, try for pass word
sql.CommandText += " AND password = #Pass";
sql.Parameters.Add("#Pass", SqlDbType.NVarChar).Value = txtpassword.Text;
DataTable dtForNameAndRole2 = LoadDataByQuery(sql);
if (dtForNameAndRole2.Rows.Count == 0)
{
msgtr.Visible = true;
lblMessage.Text = "Sorry! Invalid user password";
lblMessage.ForeColor = Color.Red;
return;
}
//get this far, user + password = ok
Response.Redirect("Dashboard.aspx");
}
Note also how our human minds work. For example, we read this post on SO? you read from top to bottom - and your brain is thus wired to work this way.
As a result, note how easy the above code is not only to read, but follow.
Hum, check for user name? no good, setup message - exit - we are done!!
If user ok, hey, lets keep working our way though this problem - lets try user + password? no good, setup message - exit - we are done!
Hey, if we get this far? then we are done!!!
Give the above approach a try - I think you like this idea and style.
Note also, while we DID chew up about 2 extra lines of code to setup parameters?
Those parameters are sql injection safe. We were able to "additive" to the sql and the parameters (thus saving even more code).
We did not have to worry about single quotes - again string concatenations are error prone.
So my lesson and point? We used parameters NOT ONLY to prevent sql injection, but we in fact wound up with again more readable and maintainable code, and did not have to mess with string concatenate into the sql (well, ok, we did some concatenation - but NOT with a messy mix of single and double quotes). I point this out, since not only did we gain sql injection code, but the efforts to write the code was ALSO less. I never liked people just banging the drum to not use sql concatenate strings based on user input - but ALSO one should then at least provide a coding approach that reduces the pain and suffering for having suggested code to prevent sql injection.
I often use the above EVEN WHEN there is no chance of sql injection, since you can even on the fly add to the sql, and as above shows, on the fly even build up and add more parameters as we did above.
Good luck - all the best in the new year.
public DataSet Login()
{
names.Add("#ID"); types.Add(SqlDbType.VarChar); values.Add(RegistrationID);
names.Add("#Password"); types.Add(SqlDbType.VarChar); values.Add(password);
return DAobj.GetDataSet(SP_LoginAuthentication, values, names, types);
}
create proc SP_LoginAuthentication
#ID varchar(50),
#Password varchar(50)
as
begin
select * from TableName where id=#ID and Password=#Password And IsActive=1
end
``~
Almost every tutorial I have read seems to incorrectly setup SqlCacheDependency. I believe they normally mix up the outdated polling method with the query notification method.
Here are two of many examples:
Web Caching with SqlCacheDependency Simplified (non-microsoft)
SqlCacheDependency Class (Microsoft)
Based on my testing, if you are using the broker (MSSQL 2015+) you don't need to make any .config changes nor do you need to make any SqlCacheDependencyAdmin calls (Don't need to define tables, etc).
I simplify just do this...
SqlDependency.Start(connString)
...
queryString = "SELECT ...";
cacheName = "SqlCache" + queryString.GetHashCode();
...
using (var connection = new SqlConnection(connString))
{
connection.Open();
var cmd = new SqlCommand(queryString, connection)
{
Notification = null,
NotificationAutoEnlist = true
};
var dependency = new SqlCacheDependency(cmd);
SqlDataReader reader = cmd.ExecuteReader();
try
{
while (reader.Read())
{
// Set the result you want to cache
data = ...
}
}
finally
{
reader.Close();
}
HostingEnvironment.Cache.Insert(cacheName, data, dependency);
}
(The code that checks if the cache is null or not is not included, as that's all just setup. I just want to show the setting of the cache)
This seems to work without the need to define which tables are involved in the query and make complicated triggers on each table. It just works.
More surprising to me is that the rules for making a query have notification :
Creating a Query for Notification (Can't find documentation newer than 2008) don't seem to apply. I purpose to do a TOP in my SQL and it still works.
For a test, I have it run a query 1000 times involving a table named "Settings". Then I update a value in the table and repeat the query.
I watch the Profiler for any queries involving the word "Settings" and I see the query is executed just 1 time (to set the cache) and then the update statement occurs, and then the query is re-executed one more time (the cache was invalidated and the query ran again)
I am worried that in my 2-3 hours of struggling with the proper way to do this I am missing something and it really is this simple?
Can I really just put any query I want and it'll just work? I am looking for any pointers where I am doing something dangerous/non-standard or any small print that I am missing
var dependency = new SqlCacheDependency(cmd);
when you write query like this you autiomatically define table name in it.Your connection already has db name.
It is non explicit way to do same.
Explicit way to catch exception and to know what went wrong is this.
// Declare the SqlCacheDependency instance, SqlDep.
SqlCacheDependency SqlDep = null;
// Check the Cache for the SqlSource key.
// If it isn't there, create it with a dependency
// on a SQL Server table using the SqlCacheDependency class.
if (Cache["SqlSource"] == null) {
// Because of possible exceptions thrown when this
// code runs, use Try...Catch...Finally syntax.
try {
// Instantiate SqlDep using the SqlCacheDependency constructor.
SqlDep = new SqlCacheDependency("Northwind", "Categories");
}
// Handle the DatabaseNotEnabledForNotificationException with
// a call to the SqlCacheDependencyAdmin.EnableNotifications method.
catch (DatabaseNotEnabledForNotificationException exDBDis) {
try {
SqlCacheDependencyAdmin.EnableNotifications("Northwind");
}
// If the database does not have permissions set for creating tables,
// the UnauthorizedAccessException is thrown. Handle it by redirecting
// to an error page.
catch (UnauthorizedAccessException exPerm) {
Response.Redirect(".\\ErrorPage.htm");
}
}
// Handle the TableNotEnabledForNotificationException with
// a call to the SqlCacheDependencyAdmin.EnableTableForNotifications method.
catch (TableNotEnabledForNotificationException exTabDis) {
try {
SqlCacheDependencyAdmin.EnableTableForNotifications("Northwind", "Categories");
}
// If a SqlException is thrown, redirect to an error page.
catch (SqlException exc) {
Response.Redirect(".\\ErrorPage.htm");
}
}
// If all the other code is successful, add MySource to the Cache
// with a dependency on SqlDep. If the Categories table changes,
// MySource will be removed from the Cache. Then generate a message
// that the data is newly created and added to the cache.
finally {
Cache.Insert("SqlSource", Source1, SqlDep);
CacheMsg.Text = "The data object was created explicitly.";
}
}
else {
CacheMsg.Text = "The data was retrieved from the Cache.";
}
As documented in https://learn.microsoft.com/en-us/dotnet/api/system.web.caching.sqlcachedependency?view=netframework-4.8 "Using a SqlCacheDependency object with SQL Server 2005 query notification does not require any explicit configuration."
So, the CMD has explicit table names in it, and ADO.net is issuing the correct Service Broker configuration commands for you. When the table is updated, SQL Server posts a Service Broker message saying the table has been updated. When ADO.net validates the CMD it checks the explicit tables in the broker for updates.
This is why the SQlCacheDependency associated CMD must use explicit tables.
I am developing C# desktop appllication using MS SQL server database.
I Keep different class as follow connect to database.
using System.Data.Odbc;
class DataBaseConnection
{
private OdbcConnection conn1 = new OdbcConnection(#"FILEDSN=C:/OTPub/Ot.dsn;" + "Uid=sa;" + "Pwd=otdata#123;"); //"DSN=Ot_DataODBC;" + "Uid=sa;" + "Pwd=otdata#123;"
//insert,update,delete
public int SetData(string query)
{
try
{
conn1.Open();
OdbcCommand command = new OdbcCommand(query, conn1);
int rs = command.ExecuteNonQuery();
conn1.Close();
return rs;
}
catch (Exception ex)
{
conn1.Close();
throw ex;
}
}
//select
public System.Data.DataTable GetData(string sql)
{
try
{
conn1.Open();
OdbcDataAdapter adpt = new OdbcDataAdapter(sql, conn1);
DataTable dt = new DataTable();
adpt.Fill(dt);
conn1.Close();
return dt;
}
catch (Exception ex)
{
conn1.Close();
throw ex;
}
}
}
in my reqierd place i make object to that DatabaseConnection class and call to get and set method as requirment.
as an example ----
DataBaseConnection db = new DataBaseConnection();
string SaveNewEmp = "INSERT INTO Employee (Service_ID, Title, Name, Initials, ) VALUES ('" + servicenumber + "','" + title + "','" + fullname + "','" + initials + "')";
int returns = db.SetData(SaveNewEmp);
am i allow to SQl injection from this method?
how avoid sql injection without using stored procedure?
You avoid SQL Injection the same way as you would anywhere else - by keeping SQL code separate from data. You can't do that if you insist on having the interface be based on just passing in a string.
I'd get rid of your wrapper class (it's just obscuring things) and make use of Parameters to pass the data alongside your query.
(I'd also recommend that you just use using statements around the various database objects rather than your current manual efforts to ensure Close is called which is also slightly breaking good error handling by re-throwing exceptions)
(Also, I'd recommend using new OdbcConnection objects wherever you need them rather than trying to share a single one - you'll be thankful you've done this as soon as any notion of multi-threading enters your codebase, which is practically inevitable these days)
Most important technique is to used bind variables like this:
string SaveNewEmp =
"INSERT INTO Employee (Service_ID, Title, Name, Initials) VALUES (?, ?, ?, ?)";
command.Parameters.Add("#servicenumber", OdbcType.Int).Value = ...;
command.Parameters.Add("#title", OdbcType.VarChar).Value = ...;
command.Parameters.Add("#fullname ", OdbcType.VarChar).Value = ...;
command.Parameters.Add("#initials ", OdbcType.VarChar).Value = ...;
Usually this lead also into a performance gain and you don't have to take care about quoting, imagine the title would be It's your day - this would fail with your approach.
Update
Using a list of parameters is straight forward:
public int SetData(string query, OdbcParameterCollection parList)
{
...
OdbcCommand command = new OdbcCommand(query, conn1);
OdbcCommand.Parameters.Add(parList);
}
var parList = new OdbcParameterCollection();
parList.Add("#servicenumber", OdbcType.Int);
parList.Add("#title", OdbcType.VarChar);
...
int ret = SetData(query, parList);
However, I did not test it perhaps you have to run
foreach ( OdbcParameter aPar in parList ) {
OdbcCommand.Parameters.Add(aPar);
}
Using List<>
Damien_The_Unbeliever's answer is mostly good, but I would like to improve it/ version it.
You can also change the SetData and GetData methods and add them an array of parameters (although I do share his/her thoughts in getting rid of the class, you could make it abstract to make more specifica DAL classes).
The only requirement to avoid SQL Injection is using parameters, either using stored procedures (impossible due to question requirements) or queries written in your code.
There is a slight chance of getting into SQL Injection even if using parameters, if the SQL executed (in coded query or in the stored procedure) does use sp_execute_sql or similar. In case of using sp_execute_sql in your query, make sure to avoid writting it with user provided info. You can set parameters to the sp_execute_sql function as a second optional parameter.
This is a recurring (for the last 20 years at least) question, but I earnestly believe I have a new answer... use QueryFirst. You get the advantages of stored procedures, but your SQL lives in .sql files in your application, versioned with your app. You create parameters just by referencing them in your SQL. All the parameter handling code is generated for you. You (and your team) have to use parameters because there's no other way. The possibility of doing something unsafe is removed. And there are tons of other advantages: you edit your sql in a real environment, with syntax validation and intellisense. Your queries are continually integration tested against your db, and their wrapper code regenerated. All errors are trapped as you type, or when you save a .sql, or, last resort, when you build. In theory, there are no runtime errors from data access.
Usually rigour comes at the cost of simplicity/ease-of-dev. This approach is much more rigorous and much easier to use than the traditional sql-in-string-literals approach. Coming soon, language and platform portability. Drag and drop a sql query from C# project on windows into a Node express app on linux or mac, rebuild, and you get a typescript wrapper instead of a C# one. That should get folk's attention.
disclaimer: I wrote QueryFirst.
Download here.
Little blog here.
I'm currently working on application where one of the requirements is the ability to create SP, Tables, Functions, Triggers, etc. from inside ASP.NET. The language I'm using is C# but I don't know if this is even possible. Would you mind pointing me to the right direction or provide me with some code examples?
I tried looking online but I'm unable to find any information regarding this.
#rmayer06, I followed your advice and below is my code:
protected void createproc_Click(object sender, EventArgs e)
{
string sqlscript = File.ReadAllText(Server.MapPath("~/sp_create.sql"));
try
{
SqlConnection con = new SqlConnection();
SqlCommand cmd = new SqlCommand(sqlscript, con);
cmd.CommandType = CommandType.Text;
con.ConnectionString = ConfigurationManager.ConnectionStrings["TCKT"].ConnectionString;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
catch (Exception ex)
{
throw new Exception("An error has occurred" + ex);
}
}
It may be possible using SqlCommand.ExecuteNonQuery(), or by using the classes in Microsoft.SqlServer namespace. I found this in a quick search: http://forums.asp.net/t/1703608.aspx/1
However, I would ask for additional clarification on your requirements if I were you. It seems odd that you would need to create SPs dynamically; generally, it is better to design them as part of the database if they are needed, as SPs will need to be optimized, debugged, etc.
On a related note, I have run database update scripts from within c#, which did create stored procedures as part of updating the database code. If that is what you are doing, I recommend the following:
Script your entire database to a single .SQL file.
Use the sqlcmd utility to execute the file against your local server. This can be done by calling System.Diagnostics.Process.Start() from the web application and supplying the necessary command-line parameters.
As a caveat, your web app process will need permissions to launch the sqlcmd process. Or as an alternative, you can use the SqlCommand class and just dump the entire contents of your SQL script into a string, which you pass to the command. I think I've done that too, and it worked.
Basically, I would like a brief explanation of how I can access a SQL database in C# code. I gather that a connection and a command is required, but what's going on? I guess what I'm asking is for someone to de-mystify the process a bit. Thanks.
For clarity, in my case I'm doing web apps, e-commerce stuff. It's all ASP.NET, C#, and SQL databases.
I'm going to go ahead and close this thread. It's a little to general and I am going to post some more pointed and tutorial-esque questions and answers on the subject.
MSDN has a pretty good writeup here:
http://msdn.microsoft.com/en-us/library/s7ee2dwt(VS.71).aspx
You should take a look at the data-reader for simple select-statements. Sample from the MSDN page:
private static void ReadOrderData(string connectionString)
{
string queryString =
"SELECT OrderID, CustomerID FROM dbo.Orders;";
using (SqlConnection connection = new SqlConnection(
connectionString))
{
SqlCommand command = new SqlCommand(
queryString, connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
try
{
while (reader.Read())
{
Console.WriteLine(String.Format("{0}, {1}",
reader[0], reader[1]));
}
}
finally
{
// Always call Close when done reading.
reader.Close();
}
}
}
It basicly first creates a SqlConnection object and then creates the SqlCommand-object that holds the actual select you are going to do, and a reference to the connection we just created. Then it opens the connection and on the next line, executes your statements and returns a SqlDataReader object.
In the while-loop it then outputs the values from the first row in the reader. Every time "reader.Read()" is called the reader will contain a new row.
Then the reader is then closed, and because we are exiting the "using"-secret, the connection is also closed.
EDIT: If you are looking for info on selecting/updating data in ASP.NET, 4GuysFromRolla has a very nice Multipart Series on ASP.NET 2.0's Data Source Controls
EDIT2: As others have pointed out, if you are using a newer version of .NET i would recommend looking into LINQ. An introduction, samples and writeup can be found on this MSDN page.
The old ADO.Net (sqlConnection, etc.) is a dinosaur with the advent of LINQ. LINQ requires .Net 3.5, but is backwards compatible with all .Net 2.0+ and Visual Studio 2005, etc.
To start with linq is ridiculously easy.
Add a new item to your project, a linq-to-sql file, this will be placed in your App_Code folder (for this example, we'll call it example.dbml)
from your server explorer, drag a table from your database into the dbml (the table will be named items in this example)
save the dbml file
You now have built a few classes. You built the exampleDataContext class, which is your linq initializer, and you built the item class which is a class for objects in the items table. This is all done automatically and you don't need to worry about it. Now say I want to get record with the itemID of 3, this is all I need to do:
exampleDataContext db = new exampleDataContext(); // initializes your linq-to-sql
item item_I_want = (from i in db.items where i.itemID == 3 select i).First(); // using the 'item' class your dbml made
And that's all it takes. Now you have a new item named item_I_want... now, if you want some information from the item you just call it like this:
int intID = item_I_want.itemID;
string itemName = item_I_want.name;
Linq is very simple to use! And this is just the tip of the iceberg.
No need to learn antiquated ADO when you have a more powerful, easier tool at your disposal :)
Reads like a beginner question. That calls for beginner video demos.
http://www.asp.net/learn/data-videos/
They are ASP.NET focused, but pay attention to the database aspects.
topics to look at:
ADO.NET basics
LINQ to SQL
Managed database providers
If it is a web application here are some good resources for getting started with data access in .NET:
http://weblogs.asp.net/scottgu/archive/2007/04/14/working-with-data-in-asp-net-2-0.aspx
To connect/perform operations on an SQL server db:
using System.Data;
using System.Data.SqlClient;
string connString = "Data Source=...";
SqlConnection conn = new SqlConnection(connString); // you can also use ConnectionStringBuilder
connection.Open();
string sql = "..."; // your SQL query
SqlCommand command = new SqlCommand(sql, conn);
// if you're interested in reading from a database use one of the following methods
// method 1
SqlDataReader reader = command.ExecuteReader();
while (reader.Read()) {
object someValue = reader.GetValue(0); // GetValue takes one parameter -- the column index
}
// make sure you close the reader when you're done
reader.Close();
// method 2
DataTable table;
SqlDataAdapter adapter = new SqlDataAdapter(command);
adapter.Fill(table);
// then work with the table as you would normally
// when you're done
connection.Close();
Most other database servers like MySQL and PostgreSQL have similar interfaces for connection and manipulation.
If what you are looking for is an easy to follow tutorial, then you should head over to the www.ASP.net website.
Here is a link to the starter video page: http://www.asp.net/learn/videos/video-49.aspx
Here is the video if you want to download it: video download
and here is a link to the C# project from the video: download project
Good luck.
I would also recommend using DataSets. They are really easy to use, just few mouse clicks, without writing any code and good enough for small apps.
If you have Visual Studio 2008 I would recommend skipping ADO.NET and leaping right in to LINQ to SQL
#J D OConal is basically right, but you need to make sure that you dispose of your connections:
string connString = "Data Source=...";
string sql = "..."; // your SQL query
//this using block
using( SqlConnection conn = new SqlConnection(connString) )
using( SqlCommand command = new SqlCommand(sql, conn) )
{
connection.Open();
// if you're interested in reading from a database use one of the following methods
// method 1
SqlDataReader reader = command.ExecuteReader();
while (reader.Read()) {
object someValue = reader.GetValue(0); // GetValue takes one parameter -- the column index
}
// make sure you close the reader when you're done
reader.Close();
// method 2
DataTable table;
SqlDataAdapter adapter = new SqlDataAdapter(command);
adapter.Fill(table);
// then work with the table as you would normally
// when you're done
connection.Close();
}