Click here to Skip to main content
15,914,642 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
in Oracle Database ,there are two tables kpi_lookup and kpi_lookup_detail,then kpi_lookup_detail has a foreign constraint key "kpi_lookup_id" to check in kpi_look.
the two table in both table are like this below:

KPI_LOOKUP

id,columnheader
1,country;month;amount

KPI_LOOKUP_DETAIL
kpi_lookup_id,content
1,CN;2014-01;1000
1,CN;2014-02;2000
1,CN;2014-03;3000
and I want to use a DataSet object,the data like below:
country,month,amount
CN,2014-01,1000
CN,2014-02,2000
CN,2014-02,3000

and there are some points I need to say, in KPI_LOOKUP, the columnheader is not fixed length, that is to say ,the data in table is possible such as "1, country; month; amcount" and there is also another possible "1, country; month; quarter; quantity; amount" and so on .
and kpi_lookup_detail,the content data is also like this.
who can help me to this in C#,thanks everyone.
Posted
Updated 8-Sep-14 17:43pm
v2
Comments
Sinisa Hajnal 9-Sep-14 5:10am    
Split your multiple column field into separate columns! If you have to parse the data every time you'll create yourself lots of problems later with testing, with forgetting to parse, with getting it wrong, especially if you later want to change some datafields.

The easiest way is to use a DataAdapter

Here is a MSDN page with some good examples.
Populating a DataSet from a DataAdapter[^]

As pointed out in Solution 2, having multiple fields in one column is bad database design.
You also need to normalize your tables.
See these links for more information about Database Normalization:

Wikipedia: Database normalization[^]
Normalization Tutorial[^]
The Database Normalization Process[^]
 
Share this answer
 
v2
Comments
Wendelius 9-Sep-14 0:30am    
Good answer
George Jonsson 9-Sep-14 0:49am    
Thanks.
I found those links useful myself.
Gihan Liyanage 9-Sep-14 1:38am    
5ed..
As said in the previous answer, using DataAdapter would be an easy way to fill a data table. In order to get started you can download ODP.NET from http://www.oracle.com/technetwork/topics/dotnet/index-085163.html[^]

ODP.NET contains the necessary classes to use managed client Oracle client from C#. For example you would use these classes for the task:
- OracleConnection[^]
- OracleCommand[^]
- OracleDataAdapter[^]

However, before jumping into implementation, I would suggest you reconsidering the design of the tables.
KPI_LOOKUP, the columnheader is not fixed length, that is to say ,the data in table is possible such as "1,country;month;amcount" and there is also another possible "1,country;month;quarter;quantity;amount" and so on .
and kpi_lookup_detail,the content data is also like this.

In my opinion this design is going to cause you extra work in the future. Instead of using variable amount of information in a single, delimited column, I would use a separate table. Now this table would have one row per each header (the ones you now have in a separated list). The values then would reference rows in this table.
 
Share this answer
 
Comments
George Jonsson 8-Sep-14 23:45pm    
OMQ, I didn't see that the column contained multiple fields.
Wendelius 9-Sep-14 0:29am    
Yes, I almost omitted it also. :)
xinxin0629 9-Sep-14 5:02am    
you can see my solution for a reference, welcome some remarks or comments
yes ,the technical things are based on the OracleConnection,OracleCommand,OracleDataAdapter,
but here I don't care the detailed technical things,here is my Solution about how to construct the DataSet,
and welcome everyone can give some comments


1. to get the columnheader split by ';' ,then store the column header to an string array
2. because the foreign key constraint, we can get the corresponding data,after that, split by ';'
3. give a loop in data content row using the variable from 1 to content.rows.count;
4. construct DataRow variable then insert the variable into DataSet
5. return the DataSet

C#
public DataSet constructionDataSet(int kpi_lookup_id)
{
    DataSet customDs = new DataSet("kpi_lookup");
    DataTable customDt = customDs.Tables.Add("kpi");

    string strColumnHeader = this.getColumnHeader(kpi_lookup_id);
    string[] strListArray = this.getArrayViaString(strColumnHeader);
    int ii = 0;
    foreach (string m in strListArray)
    {
        customDt.Columns.Add(m, typeof(string));
        ii = ii + 1;
    }
    DataSet ds = this.GetKPIContent(kpi_lookup_id);
    foreach (DataRow dr in ds.Tables[0].Rows)  //Tables[0] actually is the customDt
    {
        string[] contentArray = dr.ItemArray[0].ToString().Split(';');
        DataRow newCustomersRow = customDs.Tables["kpi"].NewRow();
        for (int j = 0; j < contentArray.Length; j++)
        {
            newCustomersRow[j] = contentArray[j];
        }
   
        customDt.Rows.Add(newCustomersRow);
    }

    return customDs;
}

======================================================================================

three function events are below:
C#
public string getColumnHeader(int kpi_lookup_id)
{
    string strSql = @"select 'ID'||columnheader  AS columnheader 
                         from kpi_lookup where id = " + kpi_lookup_id;
    string strColumnHeader;
    OracleConnection conn = this.DBCon();
    conn.Open();
    OracleDataAdapter oda = new OracleDataAdapter(strSql, conn);
    DataSet ds = new DataSet();
    oda.Fill(ds);
    strColumnHeader = ds.Tables[0].Rows[0][0].ToString();
    ds.Dispose();
    return strColumnHeader;
}

public string[] getArrayViaString(string columnHeader)
{
    string[] strArrayColumnHeaderList = columnHeader.Split(';');
    return strArrayColumnHeaderList;
}

public DataSet GetKPIContent(string sqlText)
{
    OracleConnection conn = DBCon();
    conn.Open();
    OracleDataAdapter oda = new OracleDataAdapter(sqlText, conn);
    DataSet ds = new DataSet();
    oda.Fill(ds);
    conn.Close();
    return ds;
}

public DataSet GetKPIContent(int kpi_lookup_id)
{
    string strSql = "select id||content as content from
                       kpi_lookup_detail where kpi_lookup_id ="+kpi_lookup_id +" order by id";
    DataSet ds = this.GetKPIContent(strSql);
    return ds;
}
 
Share this answer
 
v2
Comments
Sinisa Hajnal 9-Sep-14 5:11am    
Don't encourage him, this is bad database design and shouldn't be used.
Just look at the amount of code you wrote instead of having single Get, Fill and use.

OK, I missed that you answered yourself xinxin (you just got 1 from me). No, don't do it this way. There is a reason database holds separate fields in the tables and why there are multiple tables instead of single table with single column. By your logic, you could have one table with two fields, ID and content and then work in your code to parse everything - but why would you do that when you could use the time working on your app functionality?
Wendelius 9-Sep-14 5:12am    
The answer is from the same person as the question
Wendelius 9-Sep-14 5:13am    
As said, IMO this design introduces unnecessary complexity. You would be better off using relational modeling for all data.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900