Check if Windows user credentials have access to a SQL Server table - c#

The user enters data in the form. When the save button is pressed, I execute a SQL query to save the data.
I would like to know:
If the user has write access to the database so I can display an error if they don't
If the select/insert statement was successfully executed
My general code looks like this:
string query = "some query text for an insert, select, or update statement";
DataTable dataTable = new DataTable();
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
try
{
using (SqlCommand command = new SqlCommand(query, connection))
{
// I am paramterizing the query like this
command.Parameters.AddWithValue("#<param>", <value>);
SqlDataAdapter dataAdapter = new SqlDataAdapter(command);
dataAdapter.Fill(dataTable);
}
}
catch (SqlException exception)
{
// Will I get an exception if the user does not have credentials to access this database?
MessageBox.Show("An error occurred trying to save data to SQL: " + exception.Message);
}
connection.Close();
// How do I know if the select/insert was successful?
}
At this point, I look in the DataTable to find the data to display in a DataGridView to the user (for select queries).

Related

Compare a value in a table in SQL to an entry in a textbox

I have a table EmployeeRank1 in SQL Server that has a column Name. Under column Name there are two pre-defined names of employees. Moreover, in the table there is a column Password, which contains a generic password, which is "123456".
In WPF I have a textbox and that asks for name and one password box that asks for password. Underneath them, there is a button that says "Login".
The questions is how do I compare the content of Name and Pasword in my table to the input in the text box and the password box?
If the Name entered exists and the Password is correct, a new WPF page will be opened. Otherwise, a message stating that either the name or the password is incorrect will be printed.
This is what I have until now:
// check if the input matches and open the new WPF Page
private void EmployeeRank1Button_Click(object sender, RoutedEventArgs e)
{
try
{
// create a query and select everything from the EmployeeRank1 table
string query = "select * from EmployeeRank1";
// create a connection to the database and run the query
SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(query, sqlConnection);
// use the sqlDataAdapter
using(sqlDataAdapter)
{
// create a new DataTable that allows us
// to store data from tables within objects
DataTable employeeRank1Table = new DataTable();
// fill the sqlDataAdapter with all the
// information from the query(from the employeeRank1Table)
sqlDataAdapter.Fill(employeeRank1Table);
// TODO: compare Name and Password entered in the TextBox and PasswordBox to the data in the table
if (tbName.Text == *Name in Table* && pbPassword.Password == *Password in Table*)
{
EmployeeRank1 employeeRank1 = new EmployeeRank1();
employeeRank1.Show();
}
}
}
catch(Exception exception)
{
MessageBox.Show(exception.ToString());
}
}
You don't need to retrieve the whole table in memory. Just use a WHERE statement in your sql command with Name = #nameparam AND Password = #passparam, use an SqlCommand to retrieve a SqlDataReader and if the reader has a row, then bingo, the user exists.
Said that, remember that storing passwords in clear text is a big NO NO in a security concerned application. See this q/a for the reasons
private void EmployeeRank1Button_Click(object sender, RoutedEventArgs e)
{
try
{
// create a query and select just the record we need
string query = "select * from EmployeeRank1 where Name = #name AND Password = #pass";
// A local sqlconnection in a using statement ensure proper disposal at the end of this code
using SqlConnection con = new SqlConnection(connectionstring);
con.Open();
// Let's the database do the work to search for the password and name pair
SqlCommand cmd = new SqlCommand(query, con);
cmd.Parameters.Add("#Name", SqlDbType.NVarChar).Value = tbName.Text ;
cmd.Parameters.Add("#pass", SqlDbType.NVarChar).Value = tbPassword.Text ;
SqlDataReader reader = cmd.ExecuteReader();
// If the reader has rows then the user/pass exists in the db table
if(reader.HasRows)
{
EmployeeRank1 employeeRank1 = new EmployeeRank1();
employeeRank1.Show();
}
}
catch(Exception exception)
{
MessageBox.Show(exception.ToString());
}
}
Note also that I used a local SqlConnection and not a global one inside a using statement. This is the correct way to use a Disposable object like a connection. Keeping a global connection is prone to resource leaks and all sorts of problems if something fails.

Compare Sno and display complete infromation form SQL Server Table

I'm developing auction site as my University Final year project.
But I'm stuck in one problem i-e Which I click "View Details" hyperlink in Grid-view, it should compare Sno and Display its complete information present in SQL Server Table in new Tab.
Screenshot of Grid-view
string query1 = "select * from Sell ";
What condition I should apply in the above SQL Query to perform my task
If I understand you question, it sounds like you are wanting to have a link view details link clicked that retrieves the data from you sql database for the specific item being clicked.
If this is the case you are first going to want to get your sql data into a string which takes a couple more steps then what your are attempting in your example.
Instead try using a stored procedure which takes a parameter being the item your fetching and use this model:
public string StringFromDatabase()
{
SqlConnection connection = null;
try
{
var dataSet = new DataSet();
connection = new SqlConnection("Your Connection String Goes Here");
connection.Open();
var command = new SqlCommand("Your Stored Procedure Name Goes Here", connection)
{
CommandType = CommandType.StoredProcedure
};
var dataAdapter = new SqlDataAdapter { SelectCommand = command };
dataAdapter.Fill(dataSet);
return dataSet.Tables[0].Rows[0]["Item"].ToString();
}
catch (Exception ex)
{
throw new Exception(ex.Message, ex);
}
finally
{
if (connection != null)
{
connection.Close();
}
}
}

Print SQL query message in C#

I have written a code which contains a SQL query. The SQL query works fine (because I can see the effect on the database). But I want to show the message of the SQL. When we run this query on SQL server, it gives the message below and we understand the query has been executed correctly:
"The query has been executed successfully for the user xxx."
Below is the code I have written for SQL query execution which works fine but I want to be able to print the above message I mentioned.
//SQL Server Connection
string con_str_reenable = "Data Source=SQLSERVER;Initial Catalog=DATABASE;Integrated Security=True";
SqlConnection con_db_reenable = new SqlConnection(con_str_reenable);
//SQL Query:
string reenable_query="The query is pasted here(Exec **** XXX)";
SqlCommand rep_com = new SqlCommand(reenable_query, con_db_reenable);
try
{
SqlDataAdapter sda1 = new SqlDataAdapter();
sda1.SelectCommand = rep_com;
DataTable dbdataset1 = new DataTable();
sda1.Fill(dbdataset1);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error");
}
}
Please help me be able to print the message without changing SQL access codes above.
Thanks
That's just what SSMS displays.. You can do a similar thing, eg executing a ExecuteNonQuery returns the number of Rows affected - so you could print a message "x number of records updated".
In your example with populating a DataTable you can print out "The query has been executed successfully for the user xxx" every time there isn't an exception.
Try InfoMessage event in SqlConnection
Microsoft's sample:
// Assumes that connection represents a SqlConnection object.
connection.InfoMessage += new SqlInfoMessageEventHandler(OnInfoMessage);
protected static void OnInfoMessage(object sender, SqlInfoMessageEventArgsargs) {
foreach (SqlError err in args.Errors) {
Console.WriteLine("The {0} has received a severity {1}, state {2} error number {3}\non line {4} of procedure {5} on server {6}:\n{7}",
err.Source, err.Class, err.State, err.Number, err.LineNumber, err.Procedure, err.Server, err.Message);
}
}
And of course you can use ExecuteNonQuery method which returns how many rows was processed.
From my understanding of your question, you could use string.Format
For example:
//Declare variable for storing user string
string username = "xxx"; //You can always change it later
string reenable_query= string.Format("Exec procedure_name #parameter = {0}",username); //{0} will be replaced by the username
SqlCommand rep_com = new SqlCommand(reenable_query, con_db_reenable);
try
{
SqlDataAdapter sda1 = new SqlDataAdapter();
sda1.SelectCommand = rep_com;
DataTable dbdataset1 = new DataTable();
sda1.Fill(dbdataset1);
//Show Message *Add here
string show = string.Format("The query has been executed successfully for the user {0}", username);
MessageBox.Show(show);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error");
}
But I recommend using a different method of executing your query, your current code is unprotected from SQL Injections, I suggest you do this
using (SqlConnection connect = new SqlConnection())
{
DataSet tmp = new DataSet();
connect.ConnectionString = conString;
connect.Open();
SqlDataAdapter adapter = new SqlDataAdapter(*your query*, connect);
adapter.Fill(tmp);
}

How I can Select a Table from a SQL Server Database correctly?

I want to built a connection to a SQL Server database with a SELECT command.
The connection is ok but I get a error if I make a error. I want to get the Select values to a DataTable.
This I get if I try this:
The SELECT-Perssision was denied for UserApplicationRequests-Objekt, DB_CM0-Datenbank, dbo-Schema.
I use a Login Dialog in my application for building the connection string. In this form:
user id=[username];password=[password];server=[servername];Trusted_Connection=yes;database=DB_CM0
And here is my code for the SELECT command.
public DataTable GetDataTable(string sql)
{
using (con = new SqlConnection(connectionstring))
{
try
{
SqlCommand command = new SqlCommand(sql, con);
SqlDataAdapter adapter = new SqlDataAdapter(command);
DataTable tb = new DataTable();
adapter.Fill(tb);
con.Open();
command.ExecuteReader();
return tb;
}
catch (Exception)
{
return null;
}
}
}
My SQL command:
string sql = "SELECT * FROM [DB_CM0].[dbo].[UserApplicationRequests]";
its happening because of security issue..below steps might help you
Open SQL Server Management studio
Navigate to the database 'CNET_85731' >> Security >> Users
Right click on the one which you are using in your code
And finally, just uncheck 'db_denydatareader' inside "Database Role
membership" section.
Your connection string uses the sql authentication login method and integrated security login method simultaneously... Windows integrated security will have the priority in this case and attempt to use your windows user permissions to interact with the database... maybe this is not the behaviour you intended.

read data from ODBC using DataSet

I have created ODBS user DNS for database, opened VS, created DataSet and imported one table members. I would like to read all records from dataset, how to do that? I have tried query below but it return no result. I can preview data using preview menu in designer but do not find a way to get data using code.
var dataSet = new DataSet1();
var membersDataTable = dataSet.members;
var take = membersDataTable.Take(100);
It looks like you have created the schema for a DataSet, but you have not run any queries to load the DataSet.
using (OdbcConnection connection =
new OdbcConnection(connectionString))
{
string queryString = "SELECT * FROM Members";
OdbcDataAdapter adapter =
new OdbcDataAdapter(queryString, connection);
// Open the connection and fill the DataSet.
try
{
connection.Open();
adapter.Fill(dataSet);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
// The connection is automatically closed when the
// code exits the using block.

Categories