Null Exception of array: not initialising from Oracle database - c#

I have connected my Visual studio 2013 to Oracle XE 11 Database. I'm trying to retrieve information from the tables I have in the database using the following code, but it seems that the array decor isn't getting initialised with the values I'm setting it with in the foreach loop.
Please help.
conn.Open(); // it is an OleDbConnection
String[] decor;
DataTable table1 = new DataTable();
OleDbDataAdapter oda1 = new OleDbDataAdapter("select name from Product where Commodity_Type='decor'",conn);
oda1.Fill(table1);
int j=0;
foreach (DataRow row in table1.Rows)
{
decor[j] = row["name"].ToString();
j++;
}

You did not initialise the variable decor
decor = new String[(table1.rows.Count())]
and that's the error you should have found by yourself.

Try this code:
You need to initialized decor after filling the table.
conn.Open();
DataTable table1 = new DataTable();
OleDbDataAdapter oda1 = new OleDbDataAdapter("select name from Product where Commodity_Type='decor'",conn);
oda1.Fill(table1);
String[] decor = new String[(table1.rows.Count())]
int j=0;
foreach (DataRow row in table1.Rows) {
decor[j] = row["name"].ToString();
j++;
}

Related

.Net SQL Server connection simple class with procedure

I need write simple class in C#. I have 2 tables. But for understanding I use just 1 table.
public string[] GetCustOrders(int CustomerCODE)
{
SqlConnection myConn = new SqlConnection("server=(local);Initial Catalog=dbName;Integrated Security=True");
SqlDataAdapter myData = new SqlDataAdapter("CustOrdersOrdersDetails", myConn);
myData.SelectCommand.CommandType = CommandType.StoredProcedure;
myData.SelectCommand.Parameters.Add(new SqlParameter("#CustomerCODE", SqlDbType.Int, 0));
myData.SelectCommand.Parameters["#CustomerCODE"].Value = CustomerCODE;
// string[] as = string[6];
string[] as1 = string[3];
// string[] as2 = string[3];
DataSet ds = new DataSet();
myData.Fill(ds);
return as;
}
And my stored procedure code:
CREATE PROCEDURE CustOrdersOrdersDetails
#CustomerCODE int
AS
SELECT
Name,
Action,
Comments
FROM
System2
WHERE
Code = #CustomerCODE
The stored procedure will select just 1 row from the table. But I dont know how fromSqlDataAdapter` get each value of cell of this one row and give this value for my array as1.
Ex., "as[1]=" and after = I need give value of Action from selected row.
I know this simple, but I think... and think, that I can do this just give all values of my row to the DataSet and after that give each value of each cell to each string from my array. But I tray and cant finish this class...
Can anyone help?
int i = 0;
// For each table in the DataSet, print the row values.
foreach(DataTable table in ds.Tables)
{
foreach(DataRow row in table.Rows)
{
foreach (DataColumn column in table.Columns)
{
as[i]=row[column]);
i++;
}
}
}

Dataset to xml Null Values

I have the code below, where from 3 tables I take the data and write an xml.
I want write (when a record column has null value) the column on the xml with null value. For example if (Category_name == Null ) to write on the xml (Null) Right now the code skip the column and don’t even have this column on the xml.
string xmlFileData = "";
string[] tables = new string[] { "category", "company", "config" };
string query;
xmlFileData += "<MyXml>";
SqlConnection conn;
dbconnect obj;
obj = new dbconnect();//initailizing class object
for (int i = 0; i < tables.Length; i++)
{
string ifemptquery;
DataSet ds = new DataSet();
DataSet ds1 = new DataSet();
conn = obj.getConnection(); //calling connection function
ifemptquery = "SELECT * FROM " + tables[i] ";
SqlCommand cmd1 = new SqlCommand(ifemptquery, conn);
conn.Open();
SqlDataAdapter da1 = new SqlDataAdapter(cmd1);
DataTable dt1 = new DataTable();
da1.Fill(dt1);
conn.Close();
if (dt1.Rows.Count > 0)
{
query = "SELECT * FROM " + tables[i] ";
SqlCommand cmd = new SqlCommand(query, conn);
conn.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(ds);
conn.Close();
conn.Dispose();
ds.DataSetName = tables[i];
string vartbname = tables[i];
string trimed_tbname = vartbname.Replace("_", "");
ds.Tables[0].TableName = trimed_tbname;
xmlFileData += ds.GetXml();
}
else
{
}
}
xmlFileData += "</MyXml>";
File.WriteAllText(Server.MapPath("~/xmlbackup/") + "Backup.xml", xmlFileData);
I have been searching the whole world for a solution of writing null fields to XML using DataSet.WriteXML(). The answer posted by Vlad is the one I also used in my project but I found that following works in a much more performance optimized way. I have created a function for your convenience. Change your dataset tables one after the other by calling the following function and replacing the tables.
private DataTable GetNullFilledDataTableForXML(DataTable dtSource)
{
// Create a target table with same structure as source and fields as strings
// We can change the column datatype as long as there is no data loaded
DataTable dtTarget = dtSource.Clone();
foreach (DataColumn col in dtTarget.Columns)
col.DataType = typeof(string);
// Start importing the source into target by ItemArray copying which
// is found to be reasonably fast for nulk operations. VS 2015 is reporting
// 500-525 milliseconds for loading 100,000 records x 10 columns
// after null conversion in every cell which may be usable in many
// circumstances.
// Machine config: i5 2nd Gen, 8 GB RAM, Windows 7 64bit, VS 2015 Update 1
int colCountInTarget = dtTarget.Columns.Count;
foreach (DataRow sourceRow in dtSource.Rows)
{
// Get a new row loaded with data from source row
DataRow targetRow = dtTarget.NewRow();
targetRow.ItemArray = sourceRow.ItemArray;
// Update DBNull.Values to empty string in the new (target) row
// We can safely assign empty string since the target table columns
// are all of string type
for (int ctr = 0; ctr < colCountInTarget; ctr++)
if (targetRow[ctr] == DBNull.Value)
targetRow[ctr] = String.Empty;
// Now add the null filled row to target datatable
dtTarget.Rows.Add(targetRow);
}
// Return the target datatable
return dtTarget;
}
Refer similar question here - dataSet.GetXml() doesn't return xml for null or blank columns
Apart from solutions mentioned there, you can also traverse through dataset and write XML using XmlTextWriter. This method is not recommended if you are dealing with huge data.

Finding unique rows in SQL Server Table

I'm looking at the example here:
http://msdn.microsoft.com/en-US/library/y06xa2h1(v=vs.80).aspx
string s = "primaryKeyValue";
DataRow foundRow = dataSet1.Tables["AnyTable"].Rows.Find(s);
if (foundRow != null)
{
MessageBox.Show(foundRow[1].ToString());
}
else
{
MessageBox.Show("A row with the primary key of " + s + " could not be found");
}
They don't specify where does dataSet1 come from and does this represent some database?
I'm trying to use this example in my code to find unique rows but I can't seem to implement this syntax. I'm only using connection string to open connection to SQL and I use SqlDataAdapter to perform functions...
EDIT:
SqlConnection myConnection = new SqlConnection("Data Source=server; Initial Catalog=Dashboard; Integrated Security=SSPI; Persist Security Info=false; Trusted_Connection=Yes");
SqlDataAdapter da = new SqlDataAdapter();
try
{
//Opens the connection to the specified database
myConnection.Open();
//Specifies where the Table in the database where the data will be entered and the columns used
da.InsertCommand = new SqlCommand("INSERT INTO DashboardLibAnswer(Id,Date,Time,Question,Details,Answer,Notes,EnteredBy,WhereReceived,QuestionType,AnswerMethod,TransactionDuration)"
+ "VALUES(#Id,#Date,#Time,#Question,#Details,#Answer,#Notes,#EnteredBy,#WhereReceived,#QuestionType,#AnswerMethod,#TransactionDuration)", myConnection);
//Specifies the columns and their variable type where the data will be entered
//Special note: Conversion from String > DateTime will cause exceptions that will only import some part of data and not everything
da.InsertCommand.Parameters.Add("#Id", SqlDbType.NVarChar);
da.InsertCommand.Parameters.Add("#Date", SqlDbType.Text);
da.InsertCommand.Parameters.Add("#Time", SqlDbType.Text);
da.InsertCommand.Parameters.Add("#Question", SqlDbType.Text);
da.InsertCommand.Parameters.Add("#Details", SqlDbType.Text);
da.InsertCommand.Parameters.Add("#Answer", SqlDbType.Text);
da.InsertCommand.Parameters.Add("#Notes", SqlDbType.Text);
da.InsertCommand.Parameters.Add("#EnteredBy", SqlDbType.NVarChar);
da.InsertCommand.Parameters.Add("#WhereReceived", SqlDbType.NVarChar);
da.InsertCommand.Parameters.Add("#QuestionType", SqlDbType.NVarChar);
da.InsertCommand.Parameters.Add("#AnswerMethod", SqlDbType.NVarChar);
da.InsertCommand.Parameters.Add("#TransactionDuration", SqlDbType.NVarChar);
//Using the global variable counter this loop will go through each valid entry and insert it into the specifed database/table
for (int i = 0; i < counter; i++)
{
//Iterates through the collection array starting at first index and going through until the end
//and inserting each element into our SQL Table
DataSet dashboardDS = new DataSet();
da.Fill(dashboardDS, "DashboardLibAnswer");
DataTable dt = dashboardDS.Tables["DashboardLibAnswer"];
foreach (DataColumn col in dt.Columns)
{
if (col.Unique)
{
da.InsertCommand.Parameters["#Id"].Value = collection.getIdItems(i);
da.InsertCommand.Parameters["#Date"].Value = collection.getDateItems(i);
da.InsertCommand.Parameters["#Time"].Value = collection.getTimeItems(i);
da.InsertCommand.Parameters["#Question"].Value = collection.getQuestionItems(i);
da.InsertCommand.Parameters["#Details"].Value = collection.getDetailsItems(i);
da.InsertCommand.Parameters["#Answer"].Value = collection.getAnswerItems(i);
da.InsertCommand.Parameters["#Notes"].Value = collection.getNotesItems(i);
da.InsertCommand.Parameters["#EnteredBy"].Value = collection.getEnteredByItems(i);
da.InsertCommand.Parameters["#WhereReceived"].Value = collection.getWhereItems(i);
da.InsertCommand.Parameters["#QuestionType"].Value = collection.getQuestionTypeItems(i);
da.InsertCommand.Parameters["#AnswerMethod"].Value = collection.getAnswerMethodItems(i);
da.InsertCommand.Parameters["#TransactionDuration"].Value = collection.getTransactionItems(i);
da.InsertCommand.ExecuteNonQuery();
}
}
//Updates the progress bar using the i in addition to 1
_worker.ReportProgress(i + 1);
} // end for
//Once the importing is done it will show the appropriate message
MessageBox.Show("Finished Importing");
} // end try
catch (Exception exceptionError)
{
//To show exceptions thrown just uncomment bellow line
//rtbOutput.AppendText(exceptionError.ToString);
} // end catch
//Closes the SQL connection after importing is done
myConnection.Close();
}
if you populate a dataset from your data adapter, you'll be able to follow the same logic -
http://msdn.microsoft.com/en-us/library/bh8kx08z(v=vs.71).aspx
It might be worth showing what you actually have to get more specific help
EDIT
I think I'm understanding what you want - if you fill your datatable from the already populated table, just check the item doesn't already exist before adding it - i.e.
if (dt.Rows.Find(collection.getIdItems(i)) == null)
{
// add your new row
}
(just to be sure I knocked together a quick test - hopefully this helps):
// MyContacts db has a table Person with primary key (ID) - 3 rows - IDs 4,5,6
SqlConnection myConnection = new SqlConnection("Data Source=.; Initial Catalog=MyContacts; Integrated Security=SSPI; Persist Security Info=false; Trusted_Connection=Yes");
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = new SqlCommand("select * from Person", myConnection);
myConnection.Open();
DataSet dashboardDS = new DataSet();
da.Fill(dashboardDS, "Person");
dashboardDS.Tables[0].PrimaryKey = new[] { dashboardDS.Tables[0].Columns["ID"]};
List<int> ids = new List<int> {4, 6, 7};
foreach (var id in ids)
{
if (dashboardDS.Tables[0].Rows.Find(id) == null)
{
Console.WriteLine("id not in database {0}", id); //i.e. 7
}
}
You will first need to open a connection to your database. This is an excellent source for connection strings: The Connection String Reference.
Then you will need to fill the dataset with data from some table. Since we are only interested in the schema information we are only selecting one row (SELECT TOP 1 ...).
Then we can go through the columns and check their Unique property (Boolean):
string connString =
"server=(local)\\SQLEXPRESS;database=MyDatabase;Integrated Security=SSPI";
string sql = #"SELECT TOP 1 * FROM AnyTable";
using (SqlConnection conn = new SqlConnection(connString)) {
conn.Open();
SqlDataAdapter da = new SqlDataAdapter(sql, conn);
using (DataSet ds = new DataSet()) {
da.Fill(ds, "AnyTable");
DataTable dt = ds.Tables["AnyTable"];
foreach (DataColumn col in dt.Columns) {
if (col.Unique) {
Console.WriteLine("Column {0} is unique.", col.ColumnName);
}
}
}
}
UPDATE #1
Sorry, I missunderstood your question. The above example returns unique columns, not unique rows. You can get unique (distinct) rows by using the DISTINCT keyword in SQL:
SELECT DISTINCT field1, field2, field3 FROM AnyTable
You can then fill the data table the same way as above.
Usually the word "unique" is used for unique constraints and unique indexes in database jargon. The term "distinct" is used for rows which are different.
UPDATE #2
Your updated question seems to suggest that you don't want find unique rows, but that you want to insert unique rows (which is the exact opposite).
Usually you would select distinct items from a collection like this. However it is difficult to answer your question accurately, since we don't know the type of your collection.
foreach (var item in collection.Distinct()) {
}
UPDATE #3
The easiest way to insert distinct values in the SQL Server table is to filter the rows at their origin, when reading them from the CSV-File; even before splitting them.
string[] lines = File.ReadAllLines(#"C:\Data\MyData.csv");
string[][] splittedLines = lines
.Distinct()
.Select(s => s.Split(','))
.ToArray();
Now you have distinct (unique) splitted lines that you can insert into the SQL Server table.

store select result

i want to extract my table names and save it into variables this is my cod that return 3 answer:student, teacher and score. how can i change it to save these tree table name to 3 variable. thank you.
try
{
SqlDataReader myreader = null;
SqlCommand mycommand = new SqlCommand("select * FROM information_schema.tables WHERE table_type = 'BASE TABLE'", myconnect);
myreader = mycommand.ExecuteReader();
while (myreader.Read())
{
Console.WriteLine(myreader[2].ToString());
}
}
A simple builtin way is using Connection.GetSchema:
using (var con = new System.Data.SqlClient.SqlConnection(conStr))
{
con.Open();
DataTable schemaTable = con.GetSchema("Tables");
IList<string> allTableNames = schemaTable.AsEnumerable()
.Where(r => r.Field<string>("TABLE_TYPE") == "BASE TABLE")
.Select(r => r.Field<string>("TABLE_NAME"))
.ToList();
}
Now you have a List<string> with all table names which you can access via indexer or in a loop or create a comma separated list with string.Join:
string tNames = string.Join(",", allTableNames);
Console.Write("all tables in the given database: " + tNames);
You can use this :
string tableName ="" ; // Variable to stroe the table names
string connectionString = ""; //Your connectionstring
// get records from the table
string commandString =""; //Your query
// create the data set command object
// and the DataSet
SqlDataAdapter DataAdapter =new SqlDataAdapter(commandString, connectionString);
DataSet DataSet = new DataSet( );
// fill the DataSet object
DataAdapter.Fill(DataSet, "Customers");
// Get the one table from the DataSet
DataTable dataTable = DataSet.Tables[0];
// for each row in the table, display the info
foreach (DataRow dataRow in dataTable.Rows)
{
tableName = dataRow[0].tostring();
//...
}
if you want to save the result for future user or a different session then you can use any of the following to methods
first one
use the "insert" query to save the result one by one in the a different table that you would create specially for saving the data
you can put the insert command/statement directly into the for loop
second method
use the xml to store the value very simple and memory friendly
I Have modified #Doctor code to use ArrayList to store number of table name in single variables.
ArrayList alTableName = new ArrayList(); // Variable to stroe the table names
string connectionString = ""; //Your connectionstring
// get records from the table
string commandString =""; //Your query
// create the data set command object
// and the DataSet
SqlDataAdapter DataAdapter =new SqlDataAdapter(commandString, connectionString);
DataSet DataSet = new DataSet( );
// fill the DataSet object
DataAdapter.Fill(DataSet, "Customers");
// Get the one table from the DataSet
DataTable dataTable = DataSet.Tables[0];
// for each row in the table, display the info
foreach (DataRow dataRow in dataTable.Rows)
{
alTableName.Add(dataRow[0].tostring());
//...
}

How to iterate through a DataTable

I need to iterate through a DataTable. I have an column there named ImagePath.
When I am using DataReader I do it this way:
SqlDataReader dr = null;
dr = cmd.ExecuteReader();
while (dr.Read())
{
TextBox1.Text = dr["ImagePath"].ToString();
}
How can I achieve the same thing using DataTable?
DataTable dt = new DataTable();
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
adapter.Fill(dt);
foreach(DataRow row in dt.Rows)
{
TextBox1.Text = row["ImagePath"].ToString();
}
...assumes the connection is open and the command is set up properly. I also didn't check the syntax, but it should give you the idea.
foreach (DataRow row in myDataTable.Rows)
{
Console.WriteLine(row["ImagePath"]);
}
I am writing this from memory.
Hope this gives you enough hint to understand the object model.
DataTable -> DataRowCollection -> DataRow (which one can use & look for column contents for that row, either using columnName or ordinal).
-> = contains.
You can also use linq extensions for DataSets:
var imagePaths = dt.AsEnumerble().Select(r => r.Field<string>("ImagePath");
foreach(string imgPath in imagePaths)
{
TextBox1.Text = imgPath;
}
There are already nice solution has been given. The below code can help others to query over datatable and get the value of each row of the datatable for the ImagePath column.
for (int i = 0; i < dataTable.Rows.Count; i++)
{
var theUrl = dataTable.Rows[i]["ImagePath"].ToString();
}
The above examples are quite helpful. But, if we want to check if a particular row is having a particular value or not. If yes then delete and break and in case of no value found straight throw error. Below code works:
foreach (DataRow row in dtData.Rows)
{
if (row["Column_name"].ToString() == txtBox.Text)
{
// Getting the sequence number from the textbox.
string strName1 = txtRowDeletion.Text;
// Creating the SqlCommand object to access the stored procedure
// used to get the data for the grid.
string strDeleteData = "Sp_name";
SqlCommand cmdDeleteData = new SqlCommand(strDeleteData, conn);
cmdDeleteData.CommandType = System.Data.CommandType.StoredProcedure;
// Running the query.
conn.Open();
cmdDeleteData.ExecuteNonQuery();
conn.Close();
GetData();
dtData = (DataTable)Session["GetData"];
BindGrid(dtData);
lblMsgForDeletion.Text = "The row successfully deleted !!" + txtRowDeletion.Text;
txtRowDeletion.Text = "";
break;
}
else
{
lblMsgForDeletion.Text = "The row is not present ";
}
}
foreach(DataGridViewRow row in dataGridView1){ var a = row.Cells[4].Value.ToString(); }

Categories