Export informácie o stĺpcoch tabuľky do súboru

Publikoval Michal Kočí dňa 29.8.2004 o 23:06 v kategórii .Net

Cez víkend som si lámal hlavu, ako si vyexportovať základné informácie o mojej ľubovoľnej tabuľke v MS SQL servery. Nakoniec mi pri tom pomoholo google a msdn. Ako vždy. No a nedá mi nepodeliť sa o to so svetom, kedže je to úplne jednoduché a nepochybujem, že to zopár ľudí už tiež potrebovalo. Ja som potreboval vyexportovať názov stĺpca, jeho typ (alebo názov typu v SQL servery, alebo jeho ekvivalent vo visual studiu), pri reťazcoch dĺžku, či je stĺpec primárnym klúčom a či stĺpec akceptuje hodnotu NULL. Export mi stačí do csv súboru, alebo do súboru kde sú hodnoty oddelené tabulátorom. Avšak keď sa dáta vydolujú, nie je samozrejme problém (teda, nemal by byť :)) ich exportovať do XML, či do Excelu...

Vytvoril som si teda metódu ExportColumnsInfoToCsv ktorá sa spojí s databázou, načíta informácie o tabuľke a zapíše ich do textového súboru. Celé to funguje v nasledovných krokoch:

Spojíme sa s databázou, nepoužívam Windows autentifikáciu, ale SQL účet, na spojenie použijeme SqlConnection a keďže informáciu nám bude získavať SqlDataReader, tak si hneď pripravíme aj SqlCommand:

String csBase = "server={0};database={1};user id={2};password={3};";
String connectionString = String.Format(csBase, sqlServer, databaseName, 
userId, userPassword);
String selectCommand = String.Format("SELECT * FROM {0}", tableName);

SqlConnection sqlConn = new SqlConnection(connectionString);
SqlCommand sqlCmd = new SqlCommand(selectCommand, sqlConn);

Ďalej potrebujeme SqlDataReader, ktorý nám vráti metóda ExecuteReader objektu typu SqlCommand. Metódu ExecuteReader voláme s parametrom CommandBehaviour.KeyInfo, ktorý nám zabezpečí, že sa nám vráti informácia o stĺpcoch a primárnom kľúči. Samotnú informáciu o stĺpcoch tabuľky získame metódou GetSchemaTable objektu typu SqlDataReader, ktorý nám vráti objekt typu DataTable. Táto tabuľka obsahuje práve jeden riadok pre každý stĺpec tabuľky o ktorej zisťujeme informácie a v tomto riadku nám v každom stĺpci vracia istý typ informácie. Poďme teda získať obejkt typu DataTable s ktorým budeme ďalej pracovať:

sqlConn.Open();
SqlDataReader sqlDR = sqlCmd.ExecuteReader(CommandBehavior.KeyInfo);
DataTable dtSchema = sqlDR.GetSchemaTable();

Samozrejme, že z hlavy asi netušíme, ake informácie nám poskytuje vrátená tabuľka, takže si môžeme jej informácie vypísať alebo do súboru, alebo na konzolu tak, že spravíme vonkajší cyklus, ktorý nám zbehne pre každý riadok tabuľky so schémou a vnútorný cyklus, ktorý nám v danom riadku zbehne pre každý stĺpec. Vypíšeme si názov stĺpca a jaho hodnotu. Ja si túto informáciu zapisuje do súboru, vytvorím si objekt typu FileStream a nad ním objekty typu StreamWriter, ktorý poskytuje metódu WriteLine, ktorá elegantne zapisuje do súboru. Toto bude dočasný krok, keď už budeme poznať názvy stĺpcov, ktoré obsahujú nami požadované informácie, kód na výpis všetkých informácií z metódy odstránime (alebo ho vykomentujeme):

FileStream fsOut = new FileStream(fileName, FileMode.Create);
StreamWriter swOut = new StreamWriter(fsOut);

foreach(DataRow dr in dtSchema.Rows)
{
	foreach(DataColumn dc in dtSchema.Columns)
	{
		swOut.WriteLine(dc.ColumnName + "\t" + dr[dc].ToString());
	}
	swOut.WriteLine(String.Empty);
}

No a na konci samozrejme zatvoríme všetky používané zdroje metodou Close. V tomto kóde som neodchytával ani vynímky, ani iným spôsobom som neošetroval možný výskyt chýb. Je to z pohodlnosti. V kóde, ktorý by išiel do seriózneho programu samozrejme ošetrenie vynímiek použiť treba. Takže uzatvorme všetky zdroje:

swOut.Close();
sqlDR.Close();
sqlConn.Close();

A to je všetko. Skoro všetko. Ešte si treba zmodifikovať časť, ktorá do súboru zapisuje informáciu o tabuľke, každý si samozrejme zapíše presne to, čo potrebuje. U mňa táto časť vyzerá nasledovne:

swOut.WriteLine("Nazv stlpca\tPrimarny Kluc\tIdentita\t" +
	"Moze obsahovat NULL\tDatovy typ\tVelkost");

foreach(DataRow dr in dtSchema.Rows)
{
	StringBuilder sbLine =  new StringBuilder();

	sbLine.Append(dr["ColumnName"].ToString());
	sbLine.Append("\t");
	sbLine.Append((Boolean) dr["IsKey"] == true ? 
		"PK" : String.Empty);
	sbLine.Append("\t");
	sbLine.Append((Boolean) dr["IsIdentity"] == true ? 
		"ID" : String.Empty);
	sbLine.Append("\t");
	sbLine.Append((Boolean) dr["AllowDBNull"] == true ? 
		"NULL" : "NOT NULL");
	sbLine.Append("\t");
	sbLine.Append(dr["DataType"].ToString());
	sbLine.Append("\t");
	sbLine.Append(dr["ColumnSize"].ToString());

	swOut.WriteLine(sbLine.ToString());
}

Čo ma mrzí je, že dátová tabuľka neobsahuje informáciu o popise stĺpca (Description v programe SQL Manager). Táto sa však dá získať alebo uloženou funkciou alebo priamo načítaním zo systémovej tabuľky, takže až budem súrne potrebovať aj túto informáciu, tak nebude problém si ju dotiahnuť. Avšak keby sa táto informácia vracala priamo v našej DataTable, bolo by to rýchlejšie a jednoduchšie. No nič, nabudúce popíšem, ako upraviť v tomto článku uvedenú metódu, aby doťahovala aj popis stĺpca.

Mohlo by ťa tiež zaujímať

Páčil sa ti príspevok?

Zdieľaj príspevok alebo si ho odlož na neskôr

Sleduj ma

Ak nechceš premeškať príspevky ako je tento, sleduj ma na Twitteri, alebo ak máš RSS čítačku, môžeš sledovať môj RSS kanál.