Get MS Access table creation script in C#? - c#

Is is possible to get Ms Access Table script using C# ?
Although there is a tool that does this.
I was thinking if there is any automatic way to get the script of table .
Till now I am using
using (IDataReader reader = command.ExecuteReader(CommandBehavior.KeyInfo))
{
ret = reader.GetSchemaTable();
}
to get the schema of the table
Can we get creation script of access datatable in C# ?
Thank you All

You can create the script using the schema information, looping through columns getting the properties etc. Below is just adding column and datatype, but should be extended if the table is more intricate.
DataTable dt = reader.GetSchemaTable();
string query;
List<string> list = new List<string>();
foreach (DataRow columns in dt.Rows)
{
foreach (DataColumn properties in dt.Columns)
{
list.Add(properties.ColumnName + " " + properties.DataType);
}
}
query = string.Join(",", list);
Then build your string for the execute query.
Create Table [TableName] (
[append string here]
)

Related

Json Insert in Google BigQuery using cdata ado.net data providers

I am developing a console application in c#, to insert a set of records to the Google BigQuery tables. For insertion and selecting data am using cdata ado.net data providers. When inserting data with a for loop, it will insert the data but takes a long time to insert when the data range is over 100 000 rows.
So I decided to insert a json file containing rows of data in json format instead of executing a set of string query.
But I didn’t get a single idea how to do that and where to start? Is there any other way to implement the same in C#-->BigQuery?
private static DataTable GetDataTableTest(string Query)
{
DataTable dt = null;
SqlDm SqlDM = new SqlDm(ConfigurationManager.ConnectionStrings["SQLData"].ToString());
SqlDM.StoredProcedureName = Query;
dt = SqlDM.ExecuteDataTable();
SqlDM = null;
return dt;
}
private static void ADDToBigQueryTest()
{
string FileToInsert = "select Top 10 * from SalesTable";
string InsertQuery = string.Empty;
DataTable dt = GetDataTable(FileToInsert);
if (dt != null && dt.Rows.Count > 0)
{
StringBuilder sbQuery = new StringBuilder();
for (int i = 0; i < dt.Rows.Count; i++)
{
sbQuery.AppendLine(dt.Rows[i][1].ToString());
}
InsertQuery = sbQuery.ToString();
}
using (GoogleBigQueryConnection BigCon = new GoogleBigQueryConnection(ConfigurationManager.ConnectionStrings["BigQuery"].ToString()))
{
GoogleBigQueryCommand BigCmd = new GoogleBigQueryCommand(InsertQuery, BigCon);
BigCmd.ExecuteNonQuery();
}
Console.WriteLine("\n Inserted To BigQuery");
}
The CData ADO.NET Provider for Google BigQuery supports INSERT INTO SELECT statements, which you can use to bulk insert data using a single request.
You do this by inserting rows into a local temporary table, then make your INSERT INTO SELECT call:
INSERT INTO publicdata:samples.github_nested#TEMP (repository.name, MyCustomField__c) VALUES ('New publicdata:samples.github_nested', '9000');
INSERT INTO publicdata:samples.github_nested#TEMP (repository.name, MyCustomField__c) VALUES ('New publicdata:samples.github_nested 2', '9001');
INSERT INTO publicdata:samples.github_nested#TEMP (repository.name, MyCustomField__c) VALUES ('New publicdata:samples.github_nested 3', '9002');
then execute:
INSERT INTO publicdata:samples.github_nested (repository.name, MyCustomField__c) SELECT repository.name, MyCustomField__c FROM publicdata:samples.github_nested#TEMP
Ref: http://cdn.cdata.com/help/DBA/ado/pg_insertselect.htm

The name 'colType' does not exist in the current context

I am attempting to loop through a dataset's rows and columns in search for a match between the dataset's name column -- and the ColumnName from a DataReader object.
I have a new table called RECORDS which is empty at program startup. I also have a pre-populated table called ColumnPositions with a sub-set of column names found in the RECORDS table. This routine is intended to show a subset of all the available columns -- as a default display style.
My code works...except for the line of code that gets the dr["type"] value. I get the error:
The name 'colType' does not exist in the current context.
As you can clearly see, my string variables are declared outside the WHILE and FOREACH loops. The line statement colName = works just fine. But colType fails everytime. If I do a statement check in the Intermediate Window in VS2010 for ? dr["type"]" I get the result integer. But when I check ? colType, I get the above noted error message.
The intellisense for the DataRow object dr reveals an array of 6 items. Index 1 in the array maps to name. Index 2 maps to type. When I check the value of ? dr[2] in the Intermediate Window, the same result comes back integer. This is correct. But whenever this value is assigned to colType, VS2010 complains.
I'm no newbie to C# so I did a lot of testing and Googling before posting here. I'm hoping that this is a matter of me not seeing the forest through the trees.
Here's my code:
// get table information for RECORDS
SQLiteCommand tableInfo = new SQLiteCommand("PRAGMA table_info(Records)", m_cnCaseFile);
SQLiteDataAdapter adapter = new SQLiteDataAdapter(tableInfo);
DataSet ds = new DataSet();
adapter.Fill(ds);
DataTable dt = ds.Tables[0];
SQLiteCommand cmd = new SQLiteCommand("SELECT * FROM ColumnPositions WHERE ColumnStyle_ID = " + styleID + " ORDER BY ColumnPosition_ID ASC", m_cnCaseFile);
SQLiteDataReader colReader = cmd.ExecuteReader();
string colName = "";
string colType = "";
if (dt != null && colReader.HasRows)
{
while (colReader.Read())
{
foreach(DataRow dr in dt.Rows)
{
colType = Convert.ToString(dr["type"]);
colName = dr["name"].ToString();
if (colReader["ColumnName"].ToString() == colName)
{
DataGridViewColumn dgvCol = new DataGridViewColumn();
}
}
}
}
dt.Dispose();
colReader.Close();
Instead of using "dr["name"].ToString();", it is better to use "Convert.ToString(dr["name"]);"
Try using the array position instead of the column name:
colType = Convert.ToString(dr[1]);
and
colName = dr[0].ToString();
You probably don't need this, but here is the documentation for values returned by the SQLite PRAGMA table_info() command. LINK

Using GetSchemaTable() to retrieve only column names

Is it possible to use GetSchemaTable() to retrieve only column names?
I have been trying to retrieve Column names (only) using this method, is it possible.
DataTable table = myReader.GetSchemaTable();
foreach (DataRow myField in table.Rows)
{
foreach (DataColumn myProperty in table.Columns)
{
fileconnectiongrid.Rows.Add(myProperty.ColumnName + " = "
+ myField[myProperty].ToString());
}
}
This code retrieves a lot of table data unwanted, I only need a list containing
column names!:
You need to use ExecuteReader(CommandBehavior.SchemaOnly)):
DataTable schema = null;
using (var con = new SqlConnection(connection))
{
using (var schemaCommand = new SqlCommand("SELECT * FROM table", con))
{
con.Open();
using (var reader = schemaCommand.ExecuteReader(CommandBehavior.SchemaOnly))
{
schema = reader.GetSchemaTable();
}
}
}
SchemaOnly:
The query returns column information only. When using SchemaOnly, the
.NET Framework Data Provider for SQL Server precedes the statement
being executed with SET FMTONLY ON.
The column name is in the first column of every row. I don't think that it's possible to omit the other column informations like ColumnOrdinal,ColumnSize,NumericPrecision and so on since you cannot use reader.GetString but only reader.GetSchemaTable in this case.
But your loop is incorrect if you only want the column names:
foreach (DataRow col in schema.Rows)
{
Console.WriteLine("ColumnName={0}", col.Field<String>("ColumnName"));
}
Change your code to below if all you want is to display the column names. Your original code was trying to not only display column names, but also trying to display the actual data values as well.
DataTable table = myReader.GetSchemaTable();
foreach (DataRow myField in table.Rows)
{
foreach (DataColumn myProperty in table.Columns)
{
fileconnectiongrid.Rows.Add(myProperty.ToString());
}
}
This will give you all column names, you can place them in a string[] and do with them what you like.
foreach(var columnName in DataTable.Columns)
{
Console.WriteLine(columnName);
}
//Retrieve column schema into a DataTable.
schemaTable = reader.GetSchemaTable();
int index = schemaTable.Columns.IndexOf("ColumnName");
DataColumn columnName = schemaTable.Columns[index];
//For each field in the table...
foreach (DataRow myField in schemaTable.Rows)
{
String columnNameValue = myField[columnName].ToString();
Console.WriteLine("ColumnName " + columnNameValue);
}
I use same technics to add MAX-STRING-LENGTH constraint on custom TextBox in my VB.Net program.
I use a SQL SELECT command to get 4 column's values
SELECT code_pays
,nom
,code_pays_short
,default_devise
FROM pays
ORDER BY nom
I use the result returned by an IDataReader object to fill a DataGridView.
And finally, I display each row's field in a Panel that contains 4 TextBox.
To avoid that SQL UPDATE command used to save some record's changes done in TextBox return error message due to column value too long, I have added a property in custom Textbox to inform directly user that value's size is overlapped.
Here is my Form
Here is VB.Net code used to initialize MaxStringLength properties
Private Sub PushColumnConstraints(dr As IDataReader)
Dim tb As DataTable = dr.GetSchemaTable()
Dim nColIndex As Integer = -1
For Each col As DataColumn In tb.Columns
If col.ColumnName = "ColumnSize" Then
nColIndex = col.Ordinal
Exit For
End If
Next
If nColIndex < 0 Then
oT.ThrowException("[ColumnSize] columns's index not found !")
Exit Sub
End If
txtCodePays.MaxStringLength = tb.Rows(0).Item(nColIndex)
txtPays.MaxStringLength = tb.Rows(1).Item(nColIndex)
txtShortCodePays.MaxStringLength = tb.Rows(2).Item(nColIndex)
txtDefaultDevise.MaxStringLength = tb.Rows(3).Item(nColIndex)
End Sub
In For loop, program search index of field contained in ColumnSize column's value.
MaxStringLength property is assigned using following syntax
tb.Rows(%TEXT-BOX-INDEX%).Item(nColIndex)
.Rows(%TEXT-BOX-INDEX%) is used to identify column's metadata in SQL SELECT !
.Item(nColIndex) is used to get a specific column's metadata value
Item(n) can return a String or an Integer but VB.Net do implicit conversion when necessary.
This line of code can also be written shortly
tb.Rows(%TEXT-BOX-INDEX%)(nColIndex)
tb(%TEXT-BOX-INDEX%)(nColIndex)
but it is not readable !
Caution: MaxStringLength is a custom property. It is not part of normal TextBox.
In print screen above, you can see that program indicates to user that length is too big for Code Pays (3 lettres) TextBox.
Error's message is displayed in StatusBar at bottom of Form.
This information is displayed before clicking on SAVE button that generates an SQL UPDATE command.
Code used that call PushColumnConstraints method is following
Public Sub FillPanel()
SQL =
<sql-select>
SELECT code_pays
,nom
,code_pays_short
,default_devise
FROM pays
ORDER BY nom
</sql-select>
Dim cmd As New NpgsqlCommand(SQL, cn)
Dim dr As NpgsqlDataReader
Try
dr = cmd.ExecuteReader()
Catch ex As Exception
ThrowException(ex)
End Try
Call PushColumnConstraints(dr)

ADO.NET Columns names

I'm trying to get the column names using the code below but it returns a weird stuff... It returns a lot of "properties" (including the column name), all I want is a list of the columns names in the resultset. Am I doing something wrong ?
reader = cmd.ExecuteReader(CommandBehavior.SchemaOnly);
DataTable schema = reader.GetSchemaTable();
DataRow myField = schema.Rows[0];
//For each property of the field...
foreach (DataColumn myProperty in schema.Columns)
{
host.WriteLine("##--> " + myProperty.ColumnName + " = " + myField[myProperty].ToString());
}
Thanks in advance people :)
Miloud B.
reader = cmd.ExecuteReader(CommandBehavior.SchemaOnly);
DataTable schema = reader.GetSchemaTable();
//For each property of the field...
foreach (DataRow row in schema.Rows)
{
host.WriteLine("##--> " + row["ColumnName"]);
}
Note: I am writing this code without IDE. Please be kind.

Remove duplicate column values from a datatable without using LINQ

Consider my datatable,
Id Name MobNo
1 ac 9566643707
2 bc 9944556612
3 cc 9566643707
How to remove the row 3 which contains duplicate MobNo column value in c# without using LINQ. I have seen similar questions on SO but all the answers uses LINQ.
The following method did what i want....
public DataTable RemoveDuplicateRows(DataTable dTable, string colName)
{
Hashtable hTable = new Hashtable();
ArrayList duplicateList = new ArrayList();
//Add list of all the unique item value to hashtable, which stores combination of key, value pair.
//And add duplicate item value in arraylist.
foreach (DataRow drow in dTable.Rows)
{
if (hTable.Contains(drow[colName]))
duplicateList.Add(drow);
else
hTable.Add(drow[colName], string.Empty);
}
//Removing a list of duplicate items from datatable.
foreach (DataRow dRow in duplicateList)
dTable.Rows.Remove(dRow);
//Datatable which contains unique records will be return as output.
return dTable;
}
As you are reading your CSV file ( a bit of pseudo code, but you get the picture ):
List<String> uniqueMobiles = new List<String>();
String[] fileLines = readYourFile();
for (String line in fileLines) {
DataRow row = parseLine(line);
if (uniqueMobiles.Contains(row["MobNum"])
{
continue;
}
uniqueMobiles.Add(row["MobNum"]);
yourDataTable.Rows.Add(row);
}
This will only load the records with unique mobiles into your data table.
This is the simplest way .
**
var uniqueContacts = dt.AsEnumerable()
.GroupBy(x=>x.Field<string>("Email"))
.Select(g=>g.First());
**
I found it in this thread
LINQ to remove duplicate rows from a datatable based on the value of a specific row
what actually was for me that I return it as datatable
DataTable uniqueContacts = dt.AsEnumerable()
.GroupBy(x=>x.Field<string>("Email"))
.Select(g=>g.First()).CopyToDataTable();
You might want to look up the inner workings on DISTINCT before running this on your sharp DB (be sure to back up!), but if it works as I think it does (grabbing the first value) you should be able to use (something very similar to) the following SQL:
DELETE FROM YourTable WHERE Id NOT IN (SELECT DISTINCT Id, MobNo FROM YourTable);
You can use "IEqualityComparer" in C#

Categories

Resources