private void StartMenu_Load(object sender, EventArgs e)
{
this.CenterToScreen();
if (!File.Exists("schedules.db"))
{
SQLiteConnection.CreateFile("schedules.db");
MessageBox.Show("Created schedules.db");
}
SQLCon = CreateSQLiteConnection();
SQLCon.Open();
using (SQLiteCommand cmd = new SQLiteCommand("SELECT count(*) FROM sqlite_master WHERE type='table' AND name='schedule_ids'", SQLCon))
{
using (SQLiteDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
using (SQLiteCommand loadSchedules = new SQLiteCommand("SELECT name FROM schedule_ids", SQLCon))
{
reader.Close();
using (SQLiteDataReader reader1 = loadSchedules.ExecuteReader())
{
while (reader1.Read())
{
MessageBox.Show("?");
ScheduleList.Items.Add((string)reader1[0]);
}
MessageBox.Show("$");
}
}
}
else
{
reader.Close();
using (SQLiteCommand createTable = new SQLiteCommand("CREATE TABLE schedules_ids (name nvarchar(45), schedule_id int)", SQLCon))
{
createTable.ExecuteNonQuery();
}
}
}
}
}
private SQLiteConnection CreateSQLiteConnection()
{
string path = AppDomain.CurrentDomain.BaseDirectory;
//path = path.Replace(#"bin\Debug\", "");
SQLiteConnectionStringBuilder builder = new SQLiteConnectionStringBuilder();
builder.FailIfMissing = true;
builder.DataSource = Path.Combine(path, "schedules.db");
return new SQLiteConnection(builder.ConnectionString);
}
When I run this (WinForms app), it creates the schedules.db but then I get the error "SQL logic error or missing database no such table: schedule_ids". The weird part is that if I change it from
if (reader.Read())
to
if (!reader.Read())
then I get an error "SQL logic error or missing database table schedule_ids already exists". Any help would be appreciated.
Try a little refactor:
// re-usable variable to avoid typos...
private const string _schedule_Id_TableName = "schedule_ids";
private void StartMenu_Load(object sender, EventArgs e)
{
this.CenterToScreen();
if (!File.Exists("schedules.db"))
{
SQLiteConnection.CreateFile("schedules.db");
MessageBox.Show("Created schedules.db");
}
SQLCon = CreateSQLiteConnection();
SQLCon.Open();
using (SQLiteCommand cmd = new SQLiteCommand(string.Format("SELECT count(*) FROM sqlite_master WHERE type='table' AND name='{0}'", _schedule_Id_TableName), SQLCon))
{
using (SQLiteDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
using (SQLiteCommand loadSchedules = new SQLiteCommand(string.Format("SELECT name FROM {0}", _schedule_Id_TableName), SQLCon))
{
reader.Close();
using (SQLiteDataReader reader1 = loadSchedules.ExecuteReader())
{
while (reader1.Read())
{
MessageBox.Show("?");
ScheduleList.Items.Add((string)reader1[0]);
}
MessageBox.Show("$");
}
}
}
else
{
reader.Close();
// Only create the table if it doesn't already exists...
using (SQLiteCommand createTable = new SQLiteCommand(string.Format("CREATE TABLE IF NOT EXISTS {0}(name nvarchar(45), schedule_id int)", _schedule_Id_TableName), SQLCon))
{
createTable.ExecuteNonQuery();
}
}
}
}
}
private SQLiteConnection CreateSQLiteConnection()
{
string path = AppDomain.CurrentDomain.BaseDirectory;
//path = path.Replace(#"bin\Debug\", "");
SQLiteConnectionStringBuilder builder = new SQLiteConnectionStringBuilder();
builder.FailIfMissing = true;
builder.DataSource = Path.Combine(path, "schedules.db");
return new SQLiteConnection(builder.ConnectionString);
}
Related
I'm stumped, I have been trying to execute this and nothing happens. I know that the code reaches this point but it doesn't matter if I put gibberish in the SQL statement, it doesn't throw an error.
protected string checkLaptopStatus(String cardID)
{
String ConnString = GetConnectSQLServer();
String currentStatus = "";
int i = 0;
using (SqlConnection m_dbConnection = new SqlConnection(ConnString))
{
String sql = "SELECT laptopStatus FROM tblDevices WHERE cardID = " + cardID + "'";
m_dbConnection.Open();
// CODE REACHES THIS POINT BUT NEVER PASSES THIS ?
using (SqlCommand cmd = new SqlCommand(sql, m_dbConnection))
{
using (SqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
currentStatus = Convert.ToString(dr["laptopStatus"]);
i++;
}
}
}
}
return currentStatus;
}
Changed the code as advised and used the exception error message to find out what went wrong. thanks Joel for being kind and helping.
protected void SQLReaderLaptops(string cardID)
{
String ConnString = GetConnectSQLServer();
int i = 0;
String todaysDate = DateTime.Now.ToString("yyyy'-'MM'-'dd");
String laptopID = "";
try {
using (SqlConnection m_dbConnection = new SqlConnection(ConnString))
{
String sql = "Select laptopID From tblDevices WHERE cardID= #cardID";
m_dbConnection.Open();
using (SqlCommand cmd = new SqlCommand(sql, m_dbConnection))
{
cmd.Parameters.AddWithValue("#cardID", cardID);
using (SqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
laptopID = Convert.ToString(dr["laptopID"]);
i++;
}
}
}
}
}
catch(Exception ex)
{
//CAUGHT THE ISSUE HERE AND FOUND IT WAS A BAD COLUMN NAME
}
I am trying to get a select result and write a simple authentication. But i have some problems with reader.HasRows/table.Rows.Count>0, its always false. Maybe reason not in reader/adapter, but i dont have other ideas
Form1.cs[enter image description here][1]
private void button1_Click(object sender, EventArgs e)
{
String loginUser = loginField.Text;
String paswwordUser = passwordField.Text;
DB db = new DB();
DataTable table = new DataTable();
OracleDataAdapter adapter = new OracleDataAdapter();
OracleCommand command = new OracleCommand();
command.CommandType = CommandType.Text;
command.CommandText = "SELECT * from users where login='#uL' AND pass = '#uP' ";
command.Parameters.Add("#uL", OracleDbType.Varchar2).Value = loginUser;
command.Parameters.Add("#uP", OracleDbType.Varchar2).Value = paswwordUser;
command.Connection = db.GetConnection();
db.openConnection();
// OracleDataReader reader = command.ExecuteReader();
adapter.SelectCommand = command;
table.Load(command.ExecuteReader());
adapter.Fill(table);
if (table.Rows.Count>0)
MessageBox.Show("Yes");
else
MessageBox.Show("No");
// reader.Close();
}
DB.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Oracle.DataAccess.Client;
{
class DB
{
OracleConnection connection = new OracleConnection("Data Source=****/XEPDB1;User Id=****;Password=****;");
public void openConnection()
{
if (connection.State == System.Data.ConnectionState.Closed)
connection.Open();
}
public void closeConnection()
{
if (connection.State == System.Data.ConnectionState.Open)
connection.Close();
}
public OracleConnection GetConnection()
{
return connection;
}
}
}
https://i.stack.imgur.com/8m5ZZ.jpg
try to use colon:
command.CommandText = "SELECT * from users where login=:uL AND pass = :uP ";
command.Parameters.Add("uL", OracleDbType.Varchar2).Value = loginUser;
command.Parameters.Add("uP", OracleDbType.Varchar2).Value = paswwordUser;
command.Connection = db.GetConnection();
db.openConnection();
DataSet dataSet = new DataSet();
using (OracleDataAdapter dataAdapter = new OracleDataAdapter())
{
dataAdapter.SelectCommand = command;
dataAdapter.Fill(dataSet, "Users");
}
var dataTable= dataSet.Tables["Users"];
this.BindingContext[dataTable].EndCurrentEdit();
if(dataSet.HasChanges(DataRowState.Modified))
{
// do your stuff here
}
I am having the below code where I am querying the MySQL database. I need to replace my select query to prepare statement
public static void ValidateName(List<Employees> EmpList, string Grp)
{
var connStr = ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
string selectQuery;
for (int i = 0; i < EmpList.Count; i++)
{
selectQuery = "Select EmpName from Employee where group = #Grp AND #Name in (FirstName, LastName);";
using (MySqlConnection conn = new MySqlConnection(connStr))
using (MySqlCommand cmd = new MySqlCommand(selectQuery, conn))
{
cmd.Parameters.Add("#Grp", MySqlDbType.VarChar).Value = Grp;
cmd.Parameters.Add("#Name", MySqlDbType.VarChar).Value = EmpList[i].Name;
conn.Open();
var reader = cmd.ExecuteReader();
List<string> lineList = new List<string>();
while (reader.Read())
{
lineList.Add(reader.GetString(0));
}
if (lineList.Count <=0)
{
WriteValidationFailure(EmpList[i], "Name doesnot exists in the DB");
}
conn.Close();
}
}
}
This code works perfectly. But for improvement I need to use the prepare statements instead of the query I am using. Because I am having similar kinds of various validation in my code, I am not sure how to reuse the parameters effectively.
You are very close. Just call cmd.Prepare(), keep references to the parameters, and reuse the command:
public static void ValidateName(List<Employees> EmpList, string Grp)
{
var connStr = ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
string selectQuery;
selectQuery = "Select EmpName from Employee where group = #Grp AND #Name in (FirstName, LastName);";
using (MySqlConnection conn = new MySqlConnection(connStr)) {
conn.Open();
using (MySqlCommand cmd = new MySqlCommand(selectQuery, conn))
{
var prmGrp = cmd.Parameters.Add("#Grp", MySqlDbType.VarChar);
var prmName = cmd.Parameters.Add("#Name", MySqlDbType.VarChar);
cmd.Prepare();
for (int i = 0; i < EmpList.Count; i++)
{
prmGrp.Value = Grp;
prmName.Value = EmpList[i].Name;
using (var reader = cmd.ExecuteReader()) {
List<string> lineList = new List<string>();
while (reader.Read())
{
lineList.Add(reader.GetString(0));
}
if (lineList.Count <=0)
{
WriteValidationFailure(EmpList[i], "Name doesnot exists in the DB");
}
}
}
}
conn.Close();
}
}
I'm trying to make a query into the Clients table, when the user enters a mobile number, the code checks if it matches any record, if it does, it returns the client's Name & Address into text boxes, but I'm getting this error "Object reference is not set to an instance of an object" by the time I enter anything into that textbox
here is the code, what could be the problem?
private void textBox11_TextChanged(object sender, EventArgs e)
{
clientsearch();
clientsearch2();
}
public void clientsearch()
{
using (System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data source=|DataDirectory|\\crepeDB.accdb;"))
{
conn.Open();
string query = #"select Cname From Clients where Cmobile = #mobile";
System.Data.OleDb.OleDbCommand cmd = new System.Data.OleDb.OleDbCommand(query, conn);
cmd.Parameters.Add("#mobile", System.Data.OleDb.OleDbType.Integer).Value = textBox11.Text;
cmd.ExecuteNonQuery();
string result = cmd.ExecuteScalar().ToString();
textBox12.Text = #result;
}
}
public void clientsearch2()
{
using (System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data source=|DataDirectory|\\crepeDB.accdb;"))
{
conn.Open();
string query = #"select Caddress From Clients where Cmobile = #mobile";
System.Data.OleDb.OleDbCommand cmd = new System.Data.OleDb.OleDbCommand(query, conn);
cmd.Parameters.Add("#mobile", System.Data.OleDb.OleDbType.Integer).Value = textBox11.Text;
cmd.ExecuteNonQuery();
string result = cmd.ExecuteScalar().ToString();
textBox13.Text = #result;
}
}
string result = cmd.ExecuteScalar().ToString();
textBox12.Text = #result;
#result isn't anything. You just want result. Additionally, sending separate queries to the server for this data is pointlessly inefficient. Do this instead:
public void clientsearch()
{
string query = #"select Cname, Caddress From Clients where Cmobile LIKE #mobile + '*'";
using (var conn = new System.Data.OleDb.OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data source=|DataDirectory|\\crepeDB.accdb;"))
using (var cmd = System.Data.OleDb.OleDbCommand(query, conn))
{
cmd.Parameters.Add("#mobile", System.Data.OleDb.OleDbType.Integer).Value = textBox11.Text;
conn.Open();
using (var rdr = cmd.ExecuteReader())
{
if (rdr.Read())
{
textBox12.Text = rdr["Cname"].ToString();
textBox13.Text = rdr["Caddress"].ToString();
}
rdr.Close();
}
}
}
Finally, it's better style to also abstract your database code away from user interface. Ideally you would return a Client class, but since I don't see one I'll show an example using a tuple instead:
public Tuple<string, string> FindClientByMobile(string mobile)
{
string query = #"SELECT Cname, Caddress FROM Clients WHERE Cmobile LIKE #mobile + '*'";
using (var conn = new System.Data.OleDb.OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data source=|DataDirectory|\\crepeDB.accdb;"))
using (var cmd = System.Data.OleDb.OleDbCommand(query, conn))
{
cmd.Parameters.Add("#mobile", System.Data.OleDb.OleDbType.Integer).Value = mobile;
conn.Open();
using (var rdr = cmd.ExecuteReader())
{
rdr.Read();
return Tuple<string, string>.Create(rdr["Cname"].ToString(), rdr["Caddress"].ToString());
}
}
}
If you're playing with a Visual Studio 2017 release candidate, you can also use the new Tuple shortcuts:
public (string, string) FindClientByMobile(string mobile)
{
string query = #"SELECT Cname, Caddress FROM Clients WHERE Cmobile LIKE #mobile + '*'";
using (var conn = new System.Data.OleDb.OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data source=|DataDirectory|\\crepeDB.accdb;"))
using (var cmd = System.Data.OleDb.OleDbCommand(query, conn))
{
cmd.Parameters.Add("#mobile", System.Data.OleDb.OleDbType.Integer).Value = mobile;
conn.Open();
using (var rdr = cmd.ExecuteReader())
{
rdr.Read();
return (rdr["Cname"].ToString(), rdr["Caddress"].ToString());
}
}
}
And then use them like this:
private void textBox11_TextChanged(object sender, EventArgs e)
{
var result = FindClientByMobile(textBox11.Text);
textBox12.Text = result.Item1;
textBox13.Text = result.Item2;
}
I have a constructor that takes data from a SQL Server database and puts it in a local SQLite database:
public ForemanController()
{
connectionString.DataSource = "dxdb02v";
connectionString.InitialCatalog = "QTRAX4619410";
connectionString.UserID = "tunnelld";
connectionString.Password = "david";
string queryString = "SELECT * FROM [QTRAXAdmin].[vwQT_Foreman]";
List<Foreman> list;
// Creates a SQL connection
using (var connection = new SqlConnection(connectionString.ToString()))
{
using (var command = new SqlCommand(queryString, connection))
{
connection.Open();
using (var reader = command.ExecuteReader())
{
list = new List<Foreman>();
while (reader.Read())
{
list.Add(new Foreman { ForeBadge = reader.GetString(0), ForeName = reader.GetString(1) });
}
}
}
connection.Close();
allForeman = list.ToArray();
}
string deleteSQL = "DELETE FROM Foreman;";
using (SQLiteConnection SQLconn1 = new SQLiteConnection(SQLiteConnectionString))
{
using (var command = new SQLiteCommand(deleteSQL, SQLconn1))
{
command.Connection.Open();
command.ExecuteNonQuery();
}
}
using (SQLiteConnection SQLconn2 = new SQLiteConnection(SQLiteConnectionString))
{
SQLiteCommand cmd2 = SQLconn2.CreateCommand();
foreach (Foreman row in allForeman)
{
cmd2.CommandText = "INSERT INTO Foreman (ForeBadge, ForeName) VALUES (#param1, #param2);";
cmd2.Parameters.Add(new SQLiteParameter("#param1", row.ForeBadge));
cmd2.Parameters.Add(new SQLiteParameter("#param2", row.ForeName));
cmd2.ExecuteNonQuery();
}
}
}
Everything seems to be working fine until the last using statement:
using (SQLiteConnection SQLconn2 = new SQLiteConnection(SQLiteConnectionString))
{
SQLiteCommand cmd2 = SQLconn2.CreateCommand();
foreach (Foreman row in allForeman)
{
cmd2.CommandText = "INSERT INTO Foreman (ForeBadge, ForeName) VALUES (#param1, #param2);";
cmd2.Parameters.Add(new SQLiteParameter("#param1", row.ForeBadge));
cmd2.Parameters.Add(new SQLiteParameter("#param2", row.ForeName));
cmd2.ExecuteNonQuery();
}
}
I'm getting this error:
That's because that's the only place you forgot to open the connection.
add this: SQLconn2.Open();
You forgot to open the connection.
SQLConn2.Open();