C# Creating and Populating an Oracle Database - c#

To start i don't have access to the database, we hit a problem with our university account and waiting for it to be reset. How ever i do have code that is giving me some problems and frankly i'm not sure i have even gone about this in the right way.
I am only trying to make a simple test program that creates a table, populates it then reads it.
If this isn't enough information i am sorry i should of waited but its bugging me getting these little errors in the code before i even get to a point i can compile to test tomorrow.
Here is the code to create the table, there does not seem to be any errors in the code
static void buildTable()
{
try
{
string sqlBuild = "CREATE TABLE Item ("
+ "Item_ID VARCHAR2(1),"
+ "Item_Name VARCHAR2(16),"
+ "Price_Consumer VARCHAR(5)"
+ " ); ";
OracleCommand cmd = new OracleCommand(sqlBuild, con);
Connect();
cmd.ExecuteNonQuery();
Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
Here is the code to populate the table and this is where i am getting errors.
static void populateTable()
{
string[,] items;
items = new string[5,3] { { "1", "Mozzarella", "9.99" }, { "2", "Peperoni", "12.99" }, { "3", "Meat Feast", "14.99" }, { "4", "Chicken Tikka", "12.99" }, { "5", "Spicy Vegetarian", "11.99" } };
try
{
OracleCommand cmd = new OracleCommand();
OracleDataReader r = cmd.ExecuteReader();
r.Read();
for (int i = 1; i < 6; i++)
{
for(int j = 1; j < 4; j++)
{
OracleCommand comd = new OracleCommand();
comd.Connection = con;
comd.CommandText = "insert into Item(Item_ID, Item_Name, Price_Consumer) values(" items[i, j].ToString() + ", " + items[i, j].ToString() + ", " + items[i, j].ToString() ");";
Connect();
comd.ExecuteNonQuery();
Close();
}
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
the errors are on the items[i,j], it tells me it expects an " ; "
lastly this is what im near 100% will work as this i have done in the past, but i have never tried to use c# to create or populate a table.
static void itemList()
{
string s = "\n";
try
{
Connect();
OracleCommand cmd = new OracleCommand(sql, con);
OracleDataReader r = cmd.ExecuteReader();
r.Read();
while (r.Read())
{
s = s + r["Item_ID"].ToString() + ", " + r["Item_Name"].ToString() + ", " + "£" +r["Price_Consumer"].ToString();
}
Close();
Console.WriteLine(s);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
here is the addtional code that might be relevant
static void Connect()
{
con = new OracleConnection();
con.ConnectionString = "User Id=username;Password=password;Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=host)(PORT=port))(CONNECT_DATA=(SERVICE_NAME=SID)))";
con.Open();
Console.WriteLine("Connected to Oracle" + con.ServerVersion);
}
static void Close()
{
con.Close();
con.Dispose();
}
Declarations
static OracleConnection con;
static string sql = "select * from Item";

Your internal loop is not needed. When you try to insert a row, you don't call the insert one time for each column, but you call the insert one time for each row
Another problem are your columns of type VARCHAR, this means that you need to insert strings there, but you don't do it correctly.
This could be solved putting single quotes around those string to be recognized as such by the database engine.
for (int i = 1; i < 6; i++)
{
comd.CommandText = #"insert into Item(Item_ID, Item_Name, Price_Consumer)
values('" + items[i, 0].ToString() + "', '" +
items[i, 1].ToString() + "', '" +
items[i, 2].ToString() '");";
However while this will work for your simple example, this is still wrong. You should never concatenate string to build an sql command. This leads to Sql Injection and to a parsing error if the value to insert contains a single quote.
The only correct way to do it is through a parameterized query as this
comd.CommandText = #"insert into Item(Item_ID, Item_Name, Price_Consumer)
values(:ID, :Name, :Price)";
comd.Parameters.AddWithValue(":ID", items[i, 0].ToString());
comd.Parameters.AddWithValue(":Name",items[i, 1].ToString());
comd.Parameters.AddWithValue(":Price",items[i, 2].ToString());
(As a side benefit, look at how the command is more understandable now)

This line is not well formatted and is missing two + symbols:
comd.CommandText = "insert into Item(Item_ID, Item_Name, Price_Consumer) values(" +
items[i, j].ToString() + ", " +
items[i, j].ToString() + ", " +
items[i, j].ToString() + ");";
If you split it in a similar way to the above then it is easier to spot the errors

You are missing a '+' sign here

Related

objDataReader is Null - ASP.NET C#

I am quite new to ASP.NET and C#, so I still do not have much of an idea as to how things work. I basically get an error when I run my program and create a maintenance task. My code is shown right below:
private DataTable getMaintenance()
{
DataTable maintenance_dt = new DataTable();
maintenance_dt.Columns.Add("maintenance_ID");
maintenance_dt.Columns.Add("DAILY_MAINTENANCE");
maintenance_dt.Columns.Add("ADMIN_COMMENT");
string SQLstr = "SELECT MAINTENANCE_ID,DAILY_MAINTENANCE,ADMIN_COMMENT FROM " + maintenance_table + " where " + key + " like " + value + " order by MAINTENANCE_ID ";
using (DataTableReader objDataReader = OS.OSFunctions.executeSQLQuery(SQLstr))
{
while (objDataReader.Read())
{
DataRow mItem = maintenance_dt.NewRow();
mItem[0] = objDataReader["MAINTENANCE_ID"].ToString();
mItem[1] = objDataReader["DAILY_MAINTENANCE"].ToString();
if (objDataReader["ADMIN_COMMENT"] != DBNull.Value)
{
mItem[2] = objDataReader["ADMIN_COMMENT"].ToString();
}
else
{
mItem[2] = "";
}
maintenance_dt.Rows.Add(mItem);
}
}
return maintenance_dt;
}
The error I get from running this states
Object reference not set to an instance of an object. objDataReader was null
This occurs when I attempt to create a maintenance task. The code for that is also below right here:
protected void createMaintenance_Click(object sender, System.EventArgs e)
{
string SQLstr;
if (txtMaintenanceName.Text.Length > 0)
{
if (maintenance_table == "ACTIVE_DAILYMAINTENANCE")
{
SQLstr = "SELECT TOP(1) MAINTENANCE_ID FROM ACTIVE_DAILYMAINTENANCE WHERE SCHEDULE_DATE = " + value + " ORDER BY MAINTENANCE_ID desc";
using (DataTableReader objDataReader = OS.OSFunctions.executeSQLQuery(SQLstr))
{
if (objDataReader.Read())
{
int id = Convert.ToInt32(objDataReader["Maintenance_ID"]) + 1;
SQLstr = "insert into " + maintenance_table + " (maintenance_id, DAILY_MAINTENANCE, " + key + ", ADMIN_COMMENT) values ('" + id + "',"
+ " '" + txtMaintenanceName.Text + "'," + value + ",'" + txtAdminMaintenanceComment.Text + "')";
OS.OSFunctions.executeSQLNonQuery(SQLstr);
}
}
}
else
{
SQLstr = "insert into " + maintenance_table + "(DAILY_MAINTENANCE, " + key + ", ADMIN_COMMENT) values ('" + txtMaintenanceName.Text + "'," + value + ",'" + txtAdminMaintenanceComment.Text + "')";
OS.OSFunctions.executeSQLNonQuery(SQLstr);
}
}
Again, it is the getMaintenance() method giving me the error. This also isn't all my code, I do call the getMaintenance() function sometime later in the code for CreateMaintenance. Any help would be greatly appreciated.
EDIT: CODE TRYING OUT DATA SET
private DataSet getMaintenance()
{
DataSet maintenance_ds = new DataSet();
string SQLstr= "SELECT MAINTENANCE_ID,DAILY_MAINTENANCE,ADMIN_COMMENT FROM " + maintenance_table + " where " + key + " like " + value + " order by MAINTENANCE_ID ";
using(SqlConnection connection=new SqlConnection(ConfigurationManager.ConnectionStrings["SQLConnectionString"].ConnectionString))
{
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand(SQLstr, connection);
adapter.Fill(maintenance_ds);
return maintenance_ds;
}
}
So, you execute
DataTableReader objDataReader = OS.OSFunctions.executeSQLQuery(SQLstr)
in your using. SQLstr is
"SELECT MAINTENANCE_ID,DAILY_MAINTENANCE,ADMIN_COMMENT FROM " + maintenance_table + " where " + key + " like " + value + " order by MAINTENANCE_ID ";
You will need to use a debugger and jump to this line just before the error is thrown. First of all, you will need to find out what maintenance_table, key and value is. Try finding out what the generated query is and run it in your RDBMS, I think it will most likely return a null for some reason.
It is possible that you are just missing a wildcard character of % being wrapped around value if you have the intention to have a "contains" rather than an "equals" check.
Anyway, in order to detect what the error is you will need to find out what is being generated and why your query results in a null. Once you know what the problem is, you will also know what you need to fix, which largely simplifies the problem.
Since you do not use a parameterized query, I have to mention that if any of the dynamic values you concatenate to the query may come from untrusted sources, such as user input, then your query is vulnerable to SQL injection and you will need to protect your project against this potential exploit.
You do realize that you can send the sql to a datatable, and the columns and the data table is created for you.
so, use this code to get/return a data table.
It not clear if you "else" is to update a existing row, or insert a new one, but the code can look somthing like this:
protected void createMaintenance_Click(object sender, System.EventArgs e)
{
DateTime value = DateTime.Today;
string maintenance_table = "";
string SQLstr = "";
string key = "";
if (txtMaintenanceName.Text.Length > 0)
{
if (maintenance_table == "ACTIVE_DAILYMAINTENANCE")
{
// add new row
int id = NextMaintID(value);
string strSQL = #"SELECT * FROM " + maintenance_table + " WHERE Maintenance_ID = 0";
DataTable rstSched = MyRst(strSQL);
DataRow MyNewRow = rstSched.NewRow();
MyNewRow["maintenance_id"] = id;
MyNewRow["DAILY_MAINTENANCE"] = txtMaintenanceName.Text;
MyNewRow["ADMIN_COMMENT"] = txtAdminMaintenanceComment.Text;
rstSched.Rows.Add(MyNewRow);
MyUpdate(rstSched, strSQL);
}
}
else
{
// update (or add to daily?????
string strSQL = #"SELECT * FROM " + maintenance_table + " WHERE Maintenance_ID = " + key;
DataTable rstSched = MyRst(strSQL);
DataRow MyRow = rstSched.Rows[0];
MyRow["DAILY_MAINTENANCE"] = txtMaintenanceName.Text;
MyRow["ADMIN_COMMENT"] = txtAdminMaintenanceComment.Text;
MyUpdate(rstSched, strSQL);
}
}
So, I only need a few helper routines - (make them global in a static class - you can then use it everywhere - saves boatloads of code.
so these were used:
public DataTable MyRst(string strSQL)
{
// return data table based on sql
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
cmdSQL.Connection.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
public DataTable MyRstP(SqlCommand cmdSQL)
{
// return data table based on sql command (for parmaters)
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (cmdSQL)
{
cmdSQL.Connection = conn;
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
void MyUpdate(DataTable rstData, string strSQL)
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
conn.Open();
SqlDataAdapter da = new SqlDataAdapter(cmdSQL);
SqlCommandBuilder daU = new SqlCommandBuilder(da);
da.Update(rstData);
}
}
}
and of course this:
int NextMaintID (DateTime value)
{
int result = 0;
string SQLstr = #"SELECT TOP(1) MAINTENANCE_ID FROM ACTIVE_DAILYMAINTENANCE
WHERE SCHEDULE_DATE = #scDate ORDER BY MAINTENANCE_ID desc";
SqlCommand cmdSQL = new SqlCommand(SQLstr);
cmdSQL.Parameters.Add("#scDate", SqlDbType.Date).Value = value;
DataTable rstNextID = MyRstP(cmdSQL);
result = ((int)rstNextID.Rows[0]["Maintenance_ID"]) + 1;
return result;
}
So, how do you eat a elephant?
Answer: One bite at a time!!!
So, break out just a "few" helper routines that allows data operations against a data table object. That update command will work with edits, adds to rows, and even delete row method of a single row. All such updates can be thus be done with ONE simple update command.

Error in C# insert statement for SQL Server

I am trying to pass an insert statement in a C# Winforms to SQL Server. I keep getting a syntax error that just doesn't make sense to me
error in syntax near "("
My syntax is perfectly fine, as when I copy and paste into SQL Server Mgmt Studio, the code runs perfectly.
Any help would be greatly appreciated!
Thanks!
try
{
using (var cmd = new SqlCommand("INSERT INTO " + intodrop.SelectedText + "(" + colnamedrop.SelectedText.ToString() + "," +
colnamedrop2.SelectedText.ToString() + ") " + "VALUES" + " (" + valuebox.Text + ");"))
{
cmd.Connection = con;
cmd.Parameters.AddWithValue("#tbl", intodrop.SelectedText);
cmd.Parameters.AddWithValue("#colname", colnamedrop.SelectedText);
cmd.Parameters.AddWithValue("#values", valuebox.Text);
cmd.Parameters.AddWithValue("#colname2", colnamedrop2.SelectedText);
con.Open();
if (cmd.ExecuteNonQuery() > 0)
{
MessageBox.Show("Record inserted");
}
else
{
MessageBox.Show("Record failed");
}
}
}
catch (Exception g)
{
MessageBox.Show("Error during insert: " + g.Message);
}
Check if SelectedText property returns right values. Try to use Text property instead.
var cmd = new SqlCommand("INSERT INTO " + intodrop.Text +
"(" + colnamedrop.Text + ',' + colnamedrop2.Text + ") "
+ "VALUES" + " (" + valuebox.Text + ");")
You missed comma between column names when insert sql statement preparing. When printing you have comma and display correctly.
Concatenated sql statement without any inputs validation is widely open for sql injection attacks. Try to use parameter as much as possible.
It looks like you are trying to insert values to two columns, but you are appending them like this "Col1+Col2", instead of "Col1+','+Col2".
using (var cmd = new SqlCommand("INSERT INTO " + intodrop.SelectedText + "(" + colnamedrop.SelectedText.ToString() + ','+
colnamedrop2.SelectedText.ToString() + ") " + "VALUES" + " (" + valuebox.Text + ");"))
I hope this resolves the issue.
First try hard coding your insert value after that change it based on your need. Confirm the column data types are assigned correctly.
try
{
using (SqlCommand cmd = new SqlCommand("INSERT INTO Property ( FolioNo,PropertyType) VALUES (001,'WIP')"))
{
cmd.Connection = con;
con.Open();
if (cmd.ExecuteNonQuery() > 0)
{
MessageBox.Show("Record inserted");
}
else
{
MessageBox.Show("Record failed");
}
}
}
catch (Exception g)
{
MessageBox.Show("Error during insert: " + g.Message);
}
1) You should have two texbox for entering your values. If no column names you gray the value of column 1, ditto for column 2.
This allows you not to have to enter quote (do not forget to make an escape quotes
2) use the string.format function for more readability
try
{
//Add columns selected
List<string> Mycolumns = new List<string>();
If (! string.IsNullOrEmpty(colnamedrop.Text)) Mycolumns.Add(colnamedrop.Text);
If (! string.IsNullOrEmpty(colnamedrop2.Text)) Mycolumns.Add(colnamedrop2.Text);
//Add values selected with escaped quoted and string quoted
List<string> Myvalues ​​= new List<string>();
If (! string.IsNullOrEmpty(colvalue1.Text)) Myvalues.Add("'" + colvalue1.Text.Replace("'", "''") + "'");
If (! string.IsNullOrEmpty(colvalue2.Text)) Myvalues.Add("'" + colvalue2.Text.Replace("'", "''") + "'");
//If nothing selected, no action
if (Mycolumns.Count==0 && Myvalues.Count==0) return;
//Build query
String Query = string.Format ( "INSERT INTO {0} ({1}) VALUES ({2})", intodrop.Text, string.Join(Mycolumns, ", "), string.Join(Myvalues, ", "));
//Execute query
using (var cmd = new SqlCommand(Query, con ))
{
con.Open();
if (cmd.ExecuteNonQuery() > 0)
{
MessageBox.Show("Record inserted");
}
else
{
MessageBox.Show("Record failed");
}
con.Close();
}
}
catch (Exception g)
{
MessageBox.Show("Error during insert: " + g.Message);
}

Problems storing key in MS SQL db with C# Code

To get more familiar with both c# and ms sql, I made a key generator which is working good. But I want to store they key at a database so I made a method that runs a query and it should store the key(I thought)
This is my method:
public SqlDataReader InsertInto(string tableName, string[] values)
{
string query = "";
try
{
query = "INSERT INTO " + tableName + " VALUES('" + values[0] + "')";
for (int i = 1; i < values.Length; ++i)
query += ", '" + values[i] + "'";
query += ")";
}
catch
{
// ignored
}
return ExecuteQuery(query);
}
And this is the code where I execute my query:
private SqlDataReader ExecuteQuery(string query)
{
SqlConnection connection = null;
SqlDataReader dataReader = null;
try
{
using (connection = new SqlConnection(Hash.RunDecryption()))
{
using (SqlCommand command = new SqlCommand(query, connection))
{
connection.Open();
using (dataReader = command.ExecuteReader())
{
}
}
}
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show("Failed to execute data! " + ex.Message, "Error!", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
dataReader?.Close();
CloseConnection(connection);
}
finally
{
dataReader?.Close();
CloseConnection(connection);
}
return dataReader;
}
And the query that is being generated is this INSERT INTO Keys VALUES('fap0zkxbvw3')
But I get the following error:
Failed to execute data! Incorrect syntax near ')'.
The immediate problem is that you have 1 too many closing brackets:
query = "INSERT INTO " + tableName + " VALUES('" + values[0] + "')";
should be
query = "INSERT INTO " + tableName + " VALUES('" + values[0] + "'";
But you should really look into properly constructing your queries, using parameterizations, stored procedures, etc.

Error while using MySqlTransaction for multiple inserts

I have a form in windows where I am doing insert statement for header and detail.
I am using MySqlTransaction for the form. When there is no error in header and detail the transaction gets committed but when there is an error in insert query of detail then the following error comes while rollback
There is already an open DataReader associated with this Connection
which must be closed first.
Here is my code.
public string Insert_Hardening_Measures_HdrANDDtl(BL_Vessel_Hardening_Measures objHdr, List<BL_Vessel_Hardening_Measures> objDtl)
{
string success = "true";
string success1 = "";
MySqlConnection MySqlConnection1 = new MySqlConnection(strCon);
MySqlConnection1.Open();
MySqlTransaction MyTransaction = MySqlConnection1.BeginTransaction();
MySqlCommand MyCommand = new MySqlCommand();
MyCommand.Transaction = MyTransaction;
MyCommand.Connection = MySqlConnection1;
try
{
MyCommand.CommandText = "insert into hardening_measures_hdr (Hardening_Measures_Hdr_id,Month,Year) values (" + objHdr.Hardening_Measures_Hdr_id + ",'" + objHdr.Month + "','" + objHdr.Year + "')";
MyCommand.ExecuteNonQuery();
for (int i = 0; i < objDtl.Count; i++)
{
MyCommand.CommandText = "insert into hardening_measures_dtl (Hardening_Measures_Dtl_id,Hardening_Measures_Hdr_id,Hardening_Measures_Mst_id,Value) values (" + objDtl[i].Hardening_Measures_Dtl_id + "," + objDtl[i].Hardening_Measures_Hdr_id + ",'" + objDtl[i].Hardening_Measures_Mst_id + ",'" + objDtl[i].Value + "')";
MyCommand.ExecuteNonQuery();
}
MyTransaction.Commit();
MySqlConnection1.Close();
}
catch
{
MyTransaction.Rollback();
}
return success;
}
Anybody who have come through this kind of problem please suggest something

Writing to more than one Column in Access from more than one Column in Datagrid

I'm stuck with a bit of a problem here. I'm importing data from a datagridview to an Access database with OLEDB and an INSERT Statement but now I'm stuck because the Access table has multiple columns that has the is required option turned on so I'm wondering how can I use the INSERT Statement to get the values from more than one column in datagrid to more than one column in Access. My code works this way you click on any cell in the datagrid and than on the column name in the listview. Here is my code and sorry if it's a little(OK a lot messy) but I'm new to coding.
private void datExcel_CellClick(object sender, DataGridViewCellEventArgs e)
{
string sqlSelect = "SELECT [" + datExcel.Columns[e.ColumnIndex].Name + "] FROM [" + cboSource.Text + "] ";
_ColumnValues = new List<string>();
OleDbCommand cmd = _SourceConn.CreateCommand();
cmd.CommandText = sqlSelect;
OleDbDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
if (!string.IsNullOrWhiteSpace(reader.GetValue(0).ToString()))
{
_ColumnValues.Add(reader.GetValue(0).ToString());
}
}
reader.Close();
}
and another part if you need it
private void lvwDestination_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
_tablesname = lvwDestination.SelectedItems[0].Text;
for (int i = 1; i < _ColumnValues.Count; i++)
{
string Colname = _ColumnValues[i];
string sqlIns = "INSERT INTO " + cboTableName.Text + " ([" + _tablesname + "]) VALUES ('" + Colname + "')";
OleDbCommand cmd = _DestConn.CreateCommand();
cmd.CommandText = sqlIns;
cmd.ExecuteNonQuery();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
The best way to do this is by building your INSERT INTO Statement Dynamically using the += operator BUT you can also use StringBuilder. In my case I used +=.

Categories