在C#中将DataTable转换为SQL的CREATE TABLE + INSERT脚本

我需要从DataTable生成一个TSQL脚本以及其中的DATA。 它不是一个插入物。 除此之外,我还需要创建表(相同的数据结构)

所以:我有一个填充数据的DataTable。 我想要TSQL脚本创建此DataTable的结构以及SQL SERVER中的数据(CREATE TABLE + INSERT)

提前感谢您特别感谢John Saunders帮我纠正这个问题。

首先,我将使用此对象来构建您的CREATE TABLE命令。

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data.SqlClient; using System.Data; namespace Toolkit { public class SqlTableCreator { #region Instance Variables private SqlConnection _connection; public SqlConnection Connection { get { return _connection; } set { _connection = value; } } private SqlTransaction _transaction; public SqlTransaction Transaction { get { return _transaction; } set { _transaction = value; } } private string _tableName; public string DestinationTableName { get { return _tableName; } set { _tableName = value; } } #endregion #region Constructor public SqlTableCreator() { } public SqlTableCreator(SqlConnection connection) : this(connection, null) { } public SqlTableCreator(SqlConnection connection, SqlTransaction transaction) { _connection = connection; _transaction = transaction; } #endregion #region Instance Methods public object Create(DataTable schema) { return Create(schema, null); } public object Create(DataTable schema, int numKeys) { int[] primaryKeys = new int[numKeys]; for (int i = 0; i < numKeys; i++) { primaryKeys[i] = i; } return Create(schema, primaryKeys); } public object Create(DataTable schema, int[] primaryKeys) { string sql = GetCreateSQL(_tableName, schema, primaryKeys); SqlCommand cmd; if (_transaction != null && _transaction.Connection != null) cmd = new SqlCommand(sql, _connection, _transaction); else cmd = new SqlCommand(sql, _connection); return cmd.ExecuteNonQuery(); } public object CreateFromDataTable(DataTable table) { string sql = GetCreateFromDataTableSQL(_tableName, table); SqlCommand cmd; if (_transaction != null && _transaction.Connection != null) cmd = new SqlCommand(sql, _connection, _transaction); else cmd = new SqlCommand(sql, _connection); return cmd.ExecuteNonQuery(); } #endregion #region Static Methods public static string GetCreateSQL(string tableName, DataTable schema, int[] primaryKeys) { string sql = "CREATE TABLE [" + tableName + "] (\n"; // columns foreach (DataRow column in schema.Rows) { if (!(schema.Columns.Contains("IsHidden") && (bool)column["IsHidden"])) { sql += "\t[" + column["ColumnName"].ToString() + "] " + SQLGetType(column); if (schema.Columns.Contains("AllowDBNull") && (bool)column["AllowDBNull"] == false) sql += " NOT NULL"; sql += ",\n"; } } sql = sql.TrimEnd(new char[] { ',', '\n' }) + "\n"; // primary keys string pk = ", CONSTRAINT PK_" + tableName + " PRIMARY KEY CLUSTERED ("; bool hasKeys = (primaryKeys != null && primaryKeys.Length > 0); if (hasKeys) { // user defined keys foreach (int key in primaryKeys) { pk += schema.Rows[key]["ColumnName"].ToString() + ", "; } } else { // check schema for keys string keys = string.Join(", ", GetPrimaryKeys(schema)); pk += keys; hasKeys = keys.Length > 0; } pk = pk.TrimEnd(new char[] { ',', ' ', '\n' }) + ")\n"; if (hasKeys) sql += pk; sql += ")"; return sql; } public static string GetCreateFromDataTableSQL(string tableName, DataTable table) { string sql = "CREATE TABLE [" + tableName + "] (\n"; // columns foreach (DataColumn column in table.Columns) { sql += "[" + column.ColumnName + "] " + SQLGetType(column) + ",\n"; } sql = sql.TrimEnd(new char[] { ',', '\n' }) + "\n"; // primary keys if (table.PrimaryKey.Length > 0) { sql += "CONSTRAINT [PK_" + tableName + "] PRIMARY KEY CLUSTERED ("; foreach (DataColumn column in table.PrimaryKey) { sql += "[" + column.ColumnName + "],"; } sql = sql.TrimEnd(new char[] { ',' }) + "))\n"; } //if not ends with ")" if ((table.PrimaryKey.Length == 0) && (!sql.EndsWith(")"))) { sql += ")"; } return sql; } public static string[] GetPrimaryKeys(DataTable schema) { List keys = new List(); foreach (DataRow column in schema.Rows) { if (schema.Columns.Contains("IsKey") && (bool)column["IsKey"]) keys.Add(column["ColumnName"].ToString()); } return keys.ToArray(); } // Return T-SQL data type definition, based on schema definition for a column public static string SQLGetType(object type, int columnSize, int numericPrecision, int numericScale) { switch (type.ToString()) { case "System.String": return "VARCHAR(" + ((columnSize == -1) ? "255" : (columnSize > 8000) ? "MAX" : columnSize.ToString() ) + ")"; case "System.Decimal": if (numericScale > 0) return "REAL"; else if (numericPrecision > 10) return "BIGINT"; else return "INT"; case "System.Double": case "System.Single": return "REAL"; case "System.Int64": return "BIGINT"; case "System.Int16": case "System.Int32": return "INT"; case "System.DateTime": return "DATETIME"; case "System.Boolean": return "BIT"; case "System.Byte": return "TINYINT"; case "System.Guid": return "UNIQUEIDENTIFIER"; default: throw new Exception(type.ToString() + " not implemented."); } } // Overload based on row from schema table public static string SQLGetType(DataRow schemaRow) { return SQLGetType(schemaRow["DataType"], int.Parse(schemaRow["ColumnSize"].ToString()), int.Parse(schemaRow["NumericPrecision"].ToString()), int.Parse(schemaRow["NumericScale"].ToString())); } // Overload based on DataColumn from DataTable type public static string SQLGetType(DataColumn column) { return SQLGetType(column.DataType, column.MaxLength, 10, 2); } #endregion } } 

然后我会使用SQL BulkCopy而不是单独的INSERT语句。

 public static void BulkInsertDataTable(string connectionString, string tableName, DataTable table) { using (SqlConnection connection = new SqlConnection(connectionString)) { SqlBulkCopy bulkCopy = new SqlBulkCopy ( connection, SqlBulkCopyOptions.TableLock | SqlBulkCopyOptions.FireTriggers | SqlBulkCopyOptions.UseInternalTransaction, null ); bulkCopy.DestinationTableName = tableName; connection.Open(); bulkCopy.WriteToServer(table); connection.Close(); } } 
 public void createsqltable(DataTable dt,string tablename) { string strconnection = ""; string table = ""; table += "IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[" + tablename + "]') AND type in (N'U'))"; table += "BEGIN "; table += "create table " + tablename + ""; table += "("; for (int i = 0; i < dt.Columns.Count; i++) { if (i != dt.Columns.Count-1) table += dt.Columns[i].ColumnName + " " + "varchar(max)" + ","; else table += dt.Columns[i].ColumnName + " " + "varchar(max)"; } table += ") "; table += "END"; InsertQuery(table,strconnection); CopyData(strconnection, dt, tablename); } public void InsertQuery(string qry,string connection) { SqlConnection _connection = new SqlConnection(connection); SqlCommand cmd = new SqlCommand(); cmd.CommandType = CommandType.Text; cmd.CommandText = qry; cmd.Connection = _connection; _connection.Open(); cmd.ExecuteNonQuery(); _connection.Close(); } public static void CopyData(string connStr, DataTable dt, string tablename) { using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connStr, SqlBulkCopyOptions.TableLock)) { bulkCopy.DestinationTableName = tablename; bulkCopy.WriteToServer(dt); } } 

看一下:以编程方式生成SQL INSERT命令

本质上,代码循环遍历DataTable.Columns集合以生成INSERT语句的列列表。 然后循环遍历DataTable的值以使用值创建参数。

如果要从表中创建insert脚本,请使用我创建的工具。 这将根据给定的条件在多个表上创建Insert脚本:

 IF NOT EXISTS (Select 1 from Table1 WHERE Col1='Col1' AND Col2='Col2') INSERT INTO Table1 (Col1,Col2,Col3,Col4) VALUES (1,'abc',null,'2012-01-01') 

链接如下: http : //www.codeproject.com/Tips/330864/Generate-Insert-script-to-extract-data