繁体   English   中英

使用C#在oracle服务器的表结构中的sql server migration studio中创建新表

[英]Create a new table in sql server migration studio with the table structure of oracle server using C#

我正在尝试创建一个设置,以便将表从Oracle动态地移动到SQL,并且该过程中的步骤之一要求我在SQL中创建Oracle中表的副本,但无法弄清楚如何利用Oracle表模式以在SQL中创建表以下是我用于设置模式但不知道如何转换的代码:

string oradb = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=w80426.DANSKENET.NET)(PORT=1521))"
              +"(CONNECT_DATA=(SERVICE_NAME=FRSYS)));"
              +"User Id = "+ inst +"; Password = "+ inst +"; ";
OracleConnection conn = new OracleConnection(oradb);  // C#
conn.Open();
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
DataTable dtTables = conn.GetSchema("Columns", new string[] { "LDM_FIA", "RECS_TYPE_1000", null });
int columnIndex = 2;
int columnIndex1 = 4;
int columnIndex2 = 5;
string forQuery ="";
int i = 1;
foreach (DataRow row in dtTables.Rows)
{
  if (i < dtTables.Rows.Count)
  {
   forQuery = forQuery + row[columnIndex].ToString() + " " + row[columnIndex1].ToString()
   + "(" + row[columnIndex2].ToString() + ") NULL,";
  }
  else {
         forQuery = forQuery + row[columnIndex].ToString() + " " + row[columnIndex1].ToString()
                     + "(" + row[columnIndex2].ToString() + ") NULL";
       }
            i++;
   }

多年前,我写了一个帮助器类,以帮助基于.net DataTable对象创建和填充SQL表。 下面的SqlTableManager类可能可以帮助您。

using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Data;
using System.Text.RegularExpressions;

namespace App.Sql.TableManagement
{

    /// <summary>
    /// Struct stores the schema information for a sql server table column
    /// </summary>
    public struct SqlTableColumnSchema
    {
        public string ColumnName;
        public string DataType;
        public int MaximumLength;
    }

    /// <summary>
    /// Class is responsible for synchronizing a SQL Server table with a .net DataTable.
    /// </summary>
    public class SqlTableManager
    {
        private DataTable m_TableSchema;
        private string m_SqlConnectionString;
        private string m_SqlTableName;

        private Dictionary<string, SqlTableColumnSchema> m_SqlTableColumns = new Dictionary<string, SqlTableColumnSchema>();

        /// <summary>
        /// Class contructor
        /// </summary>
        /// <param name="schemaFile">The xml file that contains the table schema</param>
        /// <param name="sqlConnectionString">Connection string to the destination database</param>
        /// <param name="sqlTableName">The name of the destination table if this value is null then the table in xml file will be used.</param>
        public SqlTableManager(DataTable table, string sqlConnectionString)
        {
            m_SqlConnectionString = sqlConnectionString;
            m_SqlTableName = table.TableName.Replace("dbo.", "");
            m_SqlTableColumns = new Dictionary<string, SqlTableColumnSchema>();

            m_TableSchema = table;
            GetSqlTableColumns();
        }

        /// <summary>
        /// Bulk load current datatable to SQL Server.
        /// </summary>
        public void UploadTableToSql()
        {
            using (SqlBulkCopy bulkCopy = new SqlBulkCopy(m_SqlConnectionString))
            {
                bulkCopy.DestinationTableName = m_SqlTableName;

                try
                {
                    // Write from the source to the destination.
                    bulkCopy.WriteToServer(m_TableSchema);
                }
                catch (Exception exception)
                {
                    string errorMessage = "Failed to bulk load table to SQL.";

                    throw new ApplicationException(errorMessage, exception);
                }
            }

        }

        /// <summary>
        /// Method creates destination table if table does not exists, otherwise method will alter destination table to match schema of current data table.
        /// </summary>
        public void SyncTableSchemas()
        {
            bool tableExists = DestinationTableExists();

            if (!tableExists)
            {
                CreateSqlTable();
            }
            else
            {
                // Compare sql table schema against sql server table schema
                UpdateTableSchema();
                GetSqlTableColumns();
            }
        }

        private void UpdateTableSchema()
        {
            List<SqlTableColumnSchema> missingColumns = GetMissingColumns();

            if (missingColumns.Count > 0)
            {
                string alterTableQuery = string.Format("ALTER TABLE [{0}] ", m_SqlTableName); //ADD [fredA] VARCHAR(20) NULL, [fredB] INT NULL;";

                bool isFirstColumn = true;

                string addColumnQuery = "";

                foreach (SqlTableColumnSchema missingColumn in missingColumns)
                {


                    if (isFirstColumn)
                    {
                        addColumnQuery += string.Format("ADD [{0}] {1} NULL", missingColumn.ColumnName, missingColumn.DataType);
                    }
                    else
                    {
                        addColumnQuery += string.Format(", [{0}] {1} NULL", missingColumn.ColumnName, missingColumn.DataType);
                    }

                    isFirstColumn = false;
                }

                alterTableQuery += addColumnQuery + ";";

                using (SqlConnection connection = new SqlConnection(m_SqlConnectionString))
                {
                    using (SqlCommand command = new SqlCommand())
                    {
                        command.Connection = connection;
                        command.CommandType = CommandType.Text;
                        command.CommandText = alterTableQuery;

                        try
                        {
                            connection.Open();

                            command.ExecuteNonQuery();
                        }
                        catch (Exception exception)
                        {
                            string errorMessage = "Failed to update destination table schema. Please ensure that schema file is valid.";

                            throw new ApplicationException(errorMessage, exception);
                        }
                    }
                }
            }

        }

        public List<SqlTableColumnSchema> GetMissingColumns()
        {
            List<SqlTableColumnSchema> missingColumns = new List<SqlTableColumnSchema>();

            foreach (DataColumn column in m_TableSchema.Columns)
            {
                string columnName = column.ColumnName;

                bool columnExistsInTable = m_SqlTableColumns.ContainsKey(columnName);

                if (!columnExistsInTable)
                {
                    SqlTableColumnSchema newColumnSchema = new SqlTableColumnSchema();
                    newColumnSchema.ColumnName = columnName;
                    newColumnSchema.DataType = SQLGetType(column);
                    newColumnSchema.MaximumLength = 0;
                }
            }

            return missingColumns;
        }

        /// <summary>
        /// Method is used to determine if the destination table already exists.
        /// </summary>
        /// <returns></returns>
        private bool DestinationTableExists()
        {
            int objectCount = 0;
            string tableName = m_SqlTableName;
            bool tableExist = false;

            string sql = "SELECT count(*) as IsExists FROM dbo.sysobjects where id = object_id('[dbo].[" + tableName + "]')";

            using (SqlConnection connection = new SqlConnection(m_SqlConnectionString))
            {
                SqlCommand cmd = new SqlCommand(sql, connection);

                try
                {
                    connection.Open();


                    objectCount = (Int32)cmd.ExecuteScalar();
                }
                catch (Exception exception)
                {
                    string errorMessage = "Failed to verify if destination table exists. Please verify that sql user account has the necessary permissions to perform this action.";

                    throw new ApplicationException(errorMessage, exception);
                }
            }

            if (objectCount > 0)
                tableExist = true;
            else
                tableExist = false;

            return tableExist;

        }

        /// <summary>
        /// Method retrives the columns of the destination sql table
        /// </summary>
        /// <returns></returns>
        private void GetSqlTableColumns()
        {
            string tableName = m_SqlTableName;
            string sql = string.Format("select COLUMN_NAME as ColumnName ,DATA_TYPE as DataType, CHARACTER_MAXIMUM_LENGTH as MaximumLength FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = N'{0}'", tableName);

            using (SqlConnection connection = new SqlConnection(m_SqlConnectionString))
            {
                using (SqlCommand command = new SqlCommand(sql, connection))
                {

                    try
                    {
                        connection.Open();

                        using (SqlDataReader reader = command.ExecuteReader())
                        {
                            while (reader.Read())
                            {
                                int columnNameOrdinal = reader.GetOrdinal("ColumnName");
                                int dataTypeOrdinal = reader.GetOrdinal("DataType");
                                int maximumLengthOrdinal = reader.GetOrdinal("MaximumLength");

                                string columnName = reader.GetString(columnNameOrdinal);
                                string columnDataType = reader.GetString(dataTypeOrdinal);

                                int columnLength = 0;
                                bool maxLengthColumnIsNull = reader.IsDBNull(maximumLengthOrdinal);

                                if (!maxLengthColumnIsNull) columnLength = reader.GetInt32(maximumLengthOrdinal);

                                bool columnAlreadyAdded = m_SqlTableColumns.ContainsKey(columnName);

                                if (!columnAlreadyAdded)
                                {
                                    SqlTableColumnSchema columnSchema = new SqlTableColumnSchema();
                                    columnSchema.ColumnName = columnName;
                                    columnSchema.DataType = columnDataType;
                                    columnSchema.MaximumLength = columnLength;

                                    m_SqlTableColumns.Add(columnName, columnSchema);
                                }

                            }
                        }
                    }
                    catch (Exception exception)
                    {
                        string errorMessage = "Failed to retrieve if destination table’s columns. Please verify that sql user account has the necessary permissions to perform this action.";

                        throw new ApplicationException(errorMessage, exception);
                    }
                }
            }

        }

        /// <summary>
        /// Method will attempt to create a new sql table based of the DataTable schema object.
        /// </summary>
        private void CreateSqlTable()
        {
            string tableName = m_SqlTableName;
            DataTable table = m_TableSchema;

            string sql = GenerateSqlScriptCreateTable(tableName, table);


            using (SqlConnection connection = new SqlConnection(m_SqlConnectionString))
            {
                connection.Open();

                try
                {
                    // Create the sql table
                    using (SqlCommand createTableCommand = new SqlCommand(sql, connection))
                    {
                        createTableCommand.ExecuteNonQuery();
                    }
                }
                catch (Exception exception)
                {
                    string exceptionMessage = string.Format("CreateFromDataTable(): Failed to create sql table '{0}'", tableName);
                    throw new ApplicationException(exceptionMessage, exception);
                }

                // Add column indexes and description
                foreach (DataColumn field in table.Columns)
                {
                    string scriptAddColumnDescription = GenerateSqlScriptAddDescriptions(tableName, field);

                    if (scriptAddColumnDescription != "")
                    {
                        using (SqlCommand addColumnDescriptionCommand = new SqlCommand(scriptAddColumnDescription, connection))
                        {
                            addColumnDescriptionCommand.ExecuteNonQuery();
                        }
                    }
                }
            }
        }



        /// <summary>
        /// Helper method to 'CreateFromDataTable'. Method will generate scripts to create the main body of destination table.
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="table"></param>
        /// <returns></returns>
        private string GenerateSqlScriptCreateTable(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;
        }

        /// <summary>
        /// Methods returns a valid sql string representation of an input data type.
        /// </summary>
        /// <param name="type"></param>
        /// <param name="columnSize"></param>
        /// <param name="numericPrecision"></param>
        /// <param name="numericScale"></param>
        /// <returns></returns>
        private string SQLGetType(object type, int columnSize, int numericPrecision, int numericScale)
        {
            switch (type.ToString())
            {
                case "System.String":
                    return "NVARCHAR(" + ((columnSize == -1) ? "255" : (columnSize > 8000) ? "MAX" : columnSize.ToString()) + ")";

                case "System.Decimal":
                    if (numericScale > 0)
                        return "FLOAT";
                    else if (numericPrecision > 10)
                        return "BIGINT";
                    else
                        return "INT";

                case "System.Double":
                case "System.Single":
                    return "FLOAT";

                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.");
            }
        }

        /// <summary>
        /// Overload based on DataColumn from DataTable type
        /// </summary>
        /// <param name="column"></param>
        /// <returns></returns>
        private string SQLGetType(DataColumn column)
        {
            return SQLGetType(column.DataType, column.MaxLength, 10, 2);
        }


        /// <summary>
        /// Helper method to 'CreateFromDataTable'. Method will generate scripts to create descriptions for the destination table's columns.
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="column"></param>
        /// <returns></returns>
        private string GenerateSqlScriptAddDescriptions(string tableName, DataColumn column)
        {
            string sqlScript = "";

            string description = GetFieldDescriptionFromExtendedProperties(column);

            if (description != "")
            {
                string fieldName = column.ColumnName;
                string fieldNameClean = fieldName.Replace(' ', '_');
                fieldNameClean = CleanString(fieldNameClean);

                string template = @"EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'{2}' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'{0}', @level2type=N'COLUMN',@level2name=N'{1}'";

                sqlScript = string.Format(template, tableName, fieldName, description);
            }

            return sqlScript;
        }


        /// <summary>
        /// Helper method used to get the description of the 'Ampla' the data column.
        /// </summary>
        /// <param name="column">The column in the schema data table to get the field description for</param>
        /// <returns></returns>
        private string GetFieldDescriptionFromExtendedProperties(DataColumn column)
        {
            string description = "";

            bool columnHasFieldDescription = column.ExtendedProperties.Contains("Description");
            if (columnHasFieldDescription)
            {
                description = column.ExtendedProperties["Description"].ToString();
            }

            return description;
        }

        /// <summary>
        /// Helper method used to clean strings from any invalid values.
        /// </summary>
        /// <param name="inputString"></param>
        /// <returns></returns>
        private string CleanString(string inputString)
        {
            // Replace invalid characters with empty strings. 
            try
            {
                return Regex.Replace(inputString, @"[^\w]", "", RegexOptions.None);
            }
            // If we timeout when replacing invalid characters,  
            // we should return Empty. 
            catch
            {
                return String.Empty;
            }
        }

        /// <summary>
        /// Determine if column name is valid. The column has to exist in both the SQL Table and Schema file.
        /// </summary>
        /// <param name="columnName"></param>
        /// <returns></returns>
        public bool ColumnIsValid(string columnName)
        {
            bool columnExistInSchema = m_TableSchema.Columns.Contains(columnName);
            bool columnExistInDestinationTable = m_SqlTableColumns.ContainsKey(columnName);

            return (columnExistInSchema && columnExistInDestinationTable);
        }

        /// <summary>
        /// Get the data type of the column in question
        /// </summary>
        /// <param name="columnName"></param>
        /// <returns></returns>
        public Type GetColumnType(string columnName)
        {
            return m_TableSchema.Columns[columnName].DataType;
        }
    }
}

这个想法是,您可以简单地使用Oracle中的数据填充DataTable。 然后,SqlTableManager类可以从DataTable对象创建SQL表,如果选择这样做,则将源数据批量加载到新创建的表中。 上面的类可以如下使用:

        OracleConnection conn = new OracleConnection("Your Oracle Connection string");

        Conn.Open;

        DataSet dataSet = new DataSet();

        OracleCommand cmd = new OracleCommand("your select table query");

        cmd.CommandType = CommandType.Text;

        cmd.Connection = conn;

        using (OracleDataAdapter dataAdapter = new OracleDataAdapter())
        {
            dataAdapter.SelectCommand = cmd;
            dataAdapter.Fill(dataSet);
        }


        foreach (DataTable table in dataSet.Tables)
        {

            SqlTableManager tableManager = new SqlTableManager(table, "Your SQL Server Connection string");
            tableManager.SyncTableSchemas(); // Create or update the SQL Server table.
            tableManager.UploadTableToSql(); // Bulk load DataTable into the newly created table.
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM