|
using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using System.IO;
using System.Data;
using System.Data.Common;
namespace ScriptDB4SVN
{
public static class DataScripter
{
//private string _connectionString;
//public string ConnectionString
//{
// get { return _connectionString; }
// set { _connectionString = value; }
//}
//private string _tables;
//public string Tables
//{
// get { return _tables; }
// set { _tables = value; }
//}
public static bool ScriptData(string connectionString, string[] tables, string outputPath)
{
SqlConnection conn = new SqlConnection(connectionString);
conn.Open();
DataTable pkSchema = conn.GetSchema("IndexColumns");
foreach (string table in tables)
{
// Get the contents of the table
Console.WriteLine("Scripting data for table [" + table + "]..");
SqlCommand command = conn.CreateCommand();
// Find out what columns belong to the table
List<string> sortColumns = new List<string>();
string selection = string.Format("table_name='{0}' AND index_name like 'PK_%'", table);
DataRow[] pkColumns = pkSchema.Select(selection, "ordinal_position");
if (pkColumns.Length > 0)
{
foreach (DataRow pkColumn in pkColumns)
sortColumns.Add("[" + pkColumn["column_name"].ToString() + "]");
}
else
{
sortColumns.Add("1");
}
string orderBy = string.Join(",", sortColumns.ToArray());
command.CommandText = string.Format("SELECT * FROM {0} ORDER BY {1}", table, orderBy);
SqlDataReader dr = command.ExecuteReader();
string fields = "";
string sqlStatements = "";
// Only continue if there is at least 1 row in the returned data
if (dr.HasRows)
{
// Get table columns
for (int fieldnr = 0; fieldnr < dr.FieldCount; fieldnr++)
{
fields += dr.GetName(fieldnr) + ",";
}
fields = fields.TrimEnd(',');
sqlStatements = string.Format("-- Data scripted for table {0} with columns: {1}\n", table, fields);
//dr.Close();
//// Now fetch all table contents, order by all columns to always get the same order
//command.CommandText = string.Format("SELECT * FROM {0} ORDER BY {1}", table, fields);
//dr = command.ExecuteReader();
// Set XACT_ABORT on so that the transaction will be rolled back when an error occurs
sqlStatements += "SET XACT_ABORT ON\n";
// Begin transaction
sqlStatements += "BEGIN TRANSACTION\n\n";
// Delete existing data
sqlStatements += string.Format("DELETE FROM {0}\n\n", table);
// Enable optional identity values to be inserted
sqlStatements += string.Format("IF exists(SELECT OBJECT_NAME(id) FROM syscolumns WHERE OBJECT_NAME(id)='{0}' AND (status & 128) = 128) BEGIN\n\tSET IDENTITY_INSERT {0} ON\nEND\n\n", table);
//// INSERT INTO statement
//sqlStatements += string.Format("INSERT INTO {0} ({1})\n", table, fields);
// Loop through all rows
while (dr.Read())
{
string values = "";
string formattedValue = "";
// Loop through all columns
for (int fieldnr = 0; fieldnr < dr.FieldCount; fieldnr++)
{
object someValue = dr.GetValue(fieldnr);
switch (someValue.GetType().Name)
{
case "String": formattedValue = "N'" + ((string)someValue).Replace("'", "''") + "'"; break;
case "DateTime": formattedValue = "'" + ((DateTime)someValue).ToString("yyyy/MM/dd HH:mm:ss") + "'"; break;
case "DBNull": formattedValue = "NULL"; break;
case "Boolean": formattedValue = (bool)someValue ? "1" : "0"; break;
case "Guid": formattedValue = "'" + ((Guid)someValue).ToString() + "'"; break;
case "Decimal":
case "Float":
case "Double":
case "Single":
formattedValue = someValue.ToString().Replace(',', '.');
break;
default: formattedValue = someValue.ToString(); break;
}
values += formattedValue + ",";
}
values = values.TrimEnd(',');
// Create INSERT statement
string insertStatementFormat = "INSERT INTO {0} ({1})\n\tVALUES ({2})\n";
sqlStatements += string.Format(insertStatementFormat, table, fields, values);
//string insertStatementFormat = "SELECT {0} UNION\n";
//sqlStatements += string.Format(insertStatementFormat, values);
}
//// Cut off the last UNION statement
//if (sqlStatements.EndsWith("UNION\n"))
//{
// sqlStatements = sqlStatements.Substring(0, sqlStatements.Length - "UNION\n".Length) + "\n";
//}
// Disable identity inserts again
sqlStatements += string.Format("\nIF exists(SELECT OBJECT_NAME(id) FROM syscolumns WHERE OBJECT_NAME(id)='{0}' AND (status & 128) = 128) BEGIN\n\tSET IDENTITY_INSERT {0} OFF\nEND\n\n", table);
// Commit the transaction
sqlStatements += "COMMIT TRANSACTION\n";
// Turn XACT_ABORT off again
sqlStatements += "SET XACT_ABORT OFF\n";
}
dr.Close();
// Save insert statements to file
Directory.CreateDirectory(outputPath);
string filename = outputPath + "\\" + table + ".sql";
StreamWriter sw = File.CreateText(filename);
sw.Write(sqlStatements);
sw.Close();
}
conn.Close();
return true;
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
27 years old. Alive and kicking!