How to use SqlDataReader to retrieve information from database, c# - c#

I need to access a variable in my SQL database, along with a username which is already implemented properly. I query the database using this statement:
private const string _getUserByUsernameQuery = #"
SELECT
[User].[username]
FROM
[User] WITH (NOLOCK)
INNER JOIN [Company] WITH (NOLOCK)
ON [User].[companyId] = [Company].[id]
WHERE
[User].[username] = #username
AND [User].[password] = #password";
Then connect to the database and access the username:
using (SqlConnection connection = new SqlConnection(SQLConfiguration.ConnectionString))
{
SqlCommand command = new SqlCommand(_getUserByUsernameQuery, connection);
command.Parameters.AddWithValue("#username", username);
command.Parameters.AddWithValue("#password", password);
try
{
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
if (reader.Read())
{
Username = Convert.ToString(reader["username"]);
//CompanyId = Convert.ToString(reader["companyId"]);
lblUsername = Username;
//lblCompanyId = CompanyId;
Debug.WriteLine("Testing2::");
Debug.WriteLine(lblUsername);
//Debug.WriteLine(lblCompanyId);
}
}
}
catch (Exception)
{
if(connection.State == System.Data.ConnectionState.Open)
connection.Close();
}
}
In the if statement where I set reader["username"] equal to Username, I output Username using debug and the value is correct. What i have in comments relating to CompanyId is what I want to do, but was unable. Doing so doesn't cause errors, but it does ignore the entire statement (even the Username variable which works otherwise). based on my query string, how can I access the variable companyId?

In your _getUserByUsernameQuery you are only selecting the username field. Make sure that fields that you want to read from reader[...] are present in your select statement.

Looks like you need to add company id to your select statement to be able to retrieve it:
private const string _getUserByUsernameQuery = #"
SELECT
[User].[username], [User].[companyId]
FROM
[User] WITH (NOLOCK)
INNER JOIN [Company] WITH (NOLOCK)
ON [User].[companyId] = [Company].[id]
WHERE
[User].[username] = #username
AND [User].[password] = #password";

Related

C# Check if email already exists

How do I modify this registration code so it checks if email entered already exists in the database?
I already have a query written for it, but I don't know how to implement it
[HttpPost("Register")]
public async Task<ActionResult<User>> Register(UserDto request, Guid guid)
{
string query = #"
insert into dbo.Users(UserID,Name,Email,PasswordHash,PasswordSalt)
values (#UserID,#Name,#Email,#PasswordHash,#PasswordSalt)
";
string emailValidationQuery = #"SELECT * FROM dbo.Users WHERE Email = #Email";
CreatePasswordHash(request.Password, out byte[] passwordHash, out byte[] passwordSalt);
string psw = PasswordHash(request.Password);
Guid guid1 = Guid.NewGuid();
guid = guid1;
user.UserID = guid;
user.Username = request.Username;
user.Email = request.Email;
user.PasswordHash = Encoding.UTF8.GetBytes(psw);
user.PasswordSalt = passwordSalt;
DataTable table = new DataTable();
string sqlDataSource = _configuration.GetConnectionString("ContactAppCon");
SqlDataReader myReader;
using (SqlConnection myCon = new SqlConnection(sqlDataSource))
{
myCon.Open();
using (SqlCommand myCommand = new SqlCommand(query, myCon))
{
myCommand.Parameters.AddWithValue("#UserID", Guid.NewGuid());
myCommand.Parameters.AddWithValue("#Name", request.Username);
myCommand.Parameters.AddWithValue("#Email", request.Email);
myCommand.Parameters.AddWithValue("#PasswordHash", psw);
myCommand.Parameters.AddWithValue("#PasswordSalt", passwordSalt);
myReader = myCommand.ExecuteReader();
table.Load(myReader);
myReader.Close();
myCon.Close();
}
}
return Ok(user);
}
Try something like below (open and dispose the connections properly)
string emailValidationQuery = #"SELECT Count(*) FROM dbo.Users WHERE Email = #Email";
....
using SqlCommand command = new SqlCommand(emailValidationQuery, myCon);
int count = (Int32) command.ExecuteScalar();
if(count > 0)
return new User() // or whatever you required
Why not a single statement:
INSER INTO dbo.Users (UserID, Name, Email, ...)
VALUES (#UserID, #Name, #Email, ...)
WHERE NOT EXISTS
(
SELECT 0
FROM dbo.Users WITH (SERIALIZABLE, UPDLOCK)
WHERE Email = #Email
);
If this affects 0 rows (you can check with ##ROWCOUNT), then the e-mail already existed (and maybe you should run an update instead in that case, but it's not clear from the question) or the insert failed for some other reason (which you can check with simple try/catch patterns).
And you can prevent race conditions and avoid costly exceptions by doing it a little differently:
BEGIN TRANSACTION;
IF NOT EXISTS
(
SELECT 0 FROM dbo.Users WITH (SERIALIZABLE, UPDLOCK)
WHERE Email = #Email
)
BEGIN
INSERT ...
END
ELSE
BEGIN
-- UPDATE? RAISERROR? Again requirements aren't clear.
END
COMMIT TRANSACTION;
Don't go for simple or expensive when correct and more efficient are better.

Using Select statement for Insert Statement Value

Can you please help me with this statement, i am trying to retrieve data using SELECT statement and use the date in the INSERT statement.
I want to use the data retrieved for ProfileId Value.
// Get the UserId of the just-added user
MembershipUser currentUser = Membership.GetUser();
Guid currentUserId = (Guid)currentUser.ProviderUserKey;
// Insert a new record into UserPro
string connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
string insertSql = "INSERT INTO User_Friend(ProfileId1, ProfileId) VALUES(#FriendProfileId) SELECT ProfileId FROM User_Profile WHERE UserId = (#UserId)";
using (SqlConnection myConnection = new SqlConnection(connectionString))
{
myConnection.Open();
SqlCommand myCommand = new SqlCommand(insertSql, myConnection);
myCommand.Parameters.AddWithValue("#FriendProfileId", Request.QueryString["ProfileId"].ToString());
myCommand.Parameters.AddWithValue("#UserId", currentUserId);
myCommand.ExecuteNonQuery();
myConnection.Close();
}
How do I use the SELECT result as the ProfileId Value.
The insert statement should be
INSERT INTO User_Friend(ProfileId1, ProfileId)
VALUES ( #FriendProfileId,
(SELECT ProfileId FROM User_Profile WHERE UserId = #UserId))
or maybe SELECT TOP(1) ProfileId to make sure you will never get more than 1 value.
The insert SQL should be:
string insertSql = "INSERT INTO User_Friend(ProfileId1, ProfileId) SELECT #FriendProfileId, ProfileId FROM User_Profile WHERE UserId = (#UserId)";
You just include the variables directly in the SELECT statement in the position corresponding to the column name.

"The given key was not present in the dictionary" when Execute the mysqldatareader in C#

I have run the command without any error in mysql. my other command run fine but this code is not work. do someone know what happen with this code.
private static User GetUser(MySqlCommand cmd)
{
User usr = new User();
MySqlDataReader rdr = cmd.ExecuteReader();
if (rdr.HasRows)
{
while (rdr.Read())
{
usr.Id = Convert.ToInt32(rdr["Id"]);
usr.Level = (Level)Enum.Parse(typeof(Level), rdr["level"].ToString());
usr.Email = rdr["email"].ToString();
usr.CreatedDate = Convert.ToDateTime(rdr["createdDate"].ToString());
usr.LastLoginDate = Convert.ToDateTime(rdr["lastLoginDate"].ToString());
}
}
return usr;
}
public static User GetUserFromID(int userID)
{
string qry = "SELECT * FROM user WHERE ID = ?userID";
User user = new User();
MySqlConnection cnn = new MySqlConnection(Globals.CONNSTRING);
cnn.Open();
using (cnn)
{
MySqlCommand cmd = new MySqlCommand(qry, cnn);
cmd.Parameters.AddWithValue("userID", userID);
user = GetUser(cmd);
}
cnn.Close();
return user;
}
The code I paste here gave me error that
"The given key was not present in the dictionary."
on the line of Line 158:
MySqlDataReader rdr = cmd.ExecuteReader();
Do someone know what wrong happen with this code? I have added CharSet=utf8; in connectionstring as people suggest in SO.
The database I use is mariaDB and connector is mysql latest connector. Do someone know if this have any trouble.
I have no problem while I run my other function. The problem happen in this single function where I use mysqldatareader execution.
You would use # instead of ? as you are calling a parameter from sql which should be called in sql as:
#userID (whatever type it is, VARCHAR, INT etc)
So your sql proc should look like this
Select *
From (TableName)
Where userID = #UserID
So in your form you would call #UserID as that is the parameter you passed in sql.
Try using # instead of ?:
So:
string qry = "SELECT * FROM user WHERE ID = #userID";
and
cmd.Parameters.AddWithValue("#userID", userID);
As explained at the pages of MySQL: http://dev.mysql.com/doc/refman/5.0/en/connector-net-tutorials-intro.html#connector-net-tutorials-parameters

SQL Server select query execution from c#

string user = "1234";
string strSQL = string.Format("Select * From User where UserId = '{0}'",user);
SqlCommand myCommand = new SqlCommand(strSQL, cnn);
reader = myCommand.ExecuteReader();
My User table consists of UserId and Password columns. The UserId column type is nchar and so I've used the single quotes. I get an error saying that
incorrect syntax near the keyword User"
(I guess the table name User is being referred to here).
I have the connection string and other database environment related things correctly for I've checked the database connection status and it is open(during program execution).
What is the error in the syntax? I'm unable to retrieve the rows from my table.
User is a Keyword. Use square bracket around it to avoid the error. Select * from [User]
string strSQL = string.Format("Select * From [User] where UserId = '{0}'",user);
Also, you should always use parameterized query like below to prevent SQL Injection attack:
string strSQL = string.Format("Select * From [User] where UserId = #UserId");
You should really use parameters for this:
string user = "1234";
using (SqlCommand command = new SqlCommand("select * from [User] where UserId = #userid", cnn))
{
command.Parameters.AddWithValue("#userid", user);
using (SqlDataReader reader = myCommand.ExecuteReader())
{
// iterate your results here
}
}
Well spotted by other posters, I never caught the reserved word thing with your table name. I've amended my answer - but can't take credit for missing the obvious!
you should wrap user with brackets []
string strSQL = string.Format("Select * From [User] where UserId = '{0}'",user);
The query above is vulnerable to SQL Injection. It should be parameterized to avoid this. The following is an example:
string user = "1234";
string strSQL = "Select * From [User] where UserId = #userID";
SqlCommand myCommand = new SqlCommand(strSQL, cnn);
myCommand.AddWithValue("#userID", user);
reader = myCommand.ExecuteReader();
use the following
Try-Catch block for proper catching of errors
using statement for proper object disposal
snippet:
string user = "1234";
string strSQL = "Select * From [User] where UserId = #userID";
using (SqlConnection cnn = new SqlConnection("connection string here"))
{
using (SqlCommand myCommand = new SqlCommand(strSQL, cnn))
{
myCommand.Parameters.AddWithValue("#userID", user);
using (SqlDataReader reader = myCommand.ExecuteReader())
{
while (reader.Read())
{
Console.WriteLine(reader["columnName"].ToString());
}
}
}
}
Wrap with []. It is a keyword. Read Reserved Keywords article from MSDN.
string strSQL = string.Format("Select * From [User] where UserId = '{0}'",user);
But more important part, your query is open for an SQL Injection attack. You should always use parameterized queries.
string strSQL = "Select * From [User] where UserId = #userID";
SqlCommand myCommand = new SqlCommand(strSQL, cnn);
myCommand.Parameters.AddWithValue("#userID", user);

Copy datarow from one table to another similar table in different database c#

I have tableA in database1 and tableA in database2 both have similar number of columns and names basically same tables. But both have different data in them. I am trying to get a row from database1/tableA and insert it into database2/tableA.
This is how i am thinking of doing it:
SqlConnection conn = new SqlConnection("database1")
SqlCommand cmd = new SqlCommand("Select * from tableA where id = 1");
connection.Open()
SqlDataReader reader = cmd.ExecuteReader();
if(reader !=null )
var data = reader;
connection.Close();
Then i do the same above steps open a new connection and try to insert data variable values to tableA in database2.
Is this right approach? Is there a better way to do this?
I would do this with an inter-DB query. In MSS 2005/2008, you can "link" two servers together as long as they can see each other. Once that's done, you can refer to the linked database's table by specifying the linked server name, database, schema owner and table in dot notation. That would allow an INSERT SELECT:
INSERT INTO TableA --in database1
{
/*columns*/
}
SELECT /*columns*/ from remoteServer.database2.dbo.TableB
WHERE /*dupe-checking, other conditions*/
If the two databases are on the same server, you don't even have to link; just preface the table on the remote database with the DB name and schema owner (or if it's the default "dbo", use two dots between db name and table name.
you can use this query instead
INSERT INTO DATABASE2.dbo.TABLEA T1
SELECT * FROM DATABASE1.dbo.TABLEA T2
WHERE T2.ID = 1
The following c#, code should work, provided both databases are in the same server.
SqlConnection conn = new SqlConnection("Enter Connection String of DB, in which you insert the records.(in ur example it is,DATABASE2)");
string cmdText=#"INSERT INTO DATABASE2.dbo.TABLEA T2
SELECT * FROM DATABASE1.dbo.TABLEA T1
WHERE T1.ID = 1";
SqlCommand cmd = new SqlCommand(cmdText, conn);
cmd.ExecuteNonQuery();
string connection_String = #""; //your connection string
try
{
using (SqlConnection con = new SqlConnection(connection_String))
{
string sql = "INSERT INTO table_copy_to " +
"(column1, column2, column3 ... columnn) " +
"SELECT column1, column2, column3 ... column FROM table_copy_from";
con.Open();
using (SqlCommand cmd = new SqlCommand(sql, con))
{
int rowEffected = cmd.ExecuteNonQuery();
if (rowEffected > 0)
{
Console.WriteLine("Excuted Successfully ...");
}
else
{
Console.WriteLine("Some problem occur");
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("Exception : " + ex);
}

Categories