ZhiYeJianKang_PeiXun/cyqdata-master/SQL/SqlCreateForSchema.cs

500 lines
22 KiB
C#
Raw Normal View History

2025-02-20 15:41:53 +08:00
using System;
using System.Collections.Generic;
using System.Text;
using CYQ.Data.Table;
using System.Data;
using CYQ.Data.Tool;
namespace CYQ.Data.SQL
{
/// <summary>
/// SQL <20><EFBFBD><E1B9B9><EFBFBD><EFBFBD>
/// </summary>
internal class SqlCreateForSchema
{
#region <EFBFBD><EFBFBD>ȡCreateTable<EFBFBD><EFBFBD><EFBFBD><EFBFBD>SQL<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>еı<D0B5><C4B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
internal static string GetTableDescriptionSql(string tableName, MCellStruct mcs, DataBaseType dalType, bool isAdd)
{
switch (dalType)
{
case DataBaseType.MsSql:
string spName = isAdd ? "sp_addextendedproperty" : "sp_updateextendedproperty";
return string.Format("exec {3} N'MS_Description', N'{0}', N'user', N'dbo', N'table', N'{1}', N'column', N'{2}'", mcs.Description, tableName, mcs.ColumnName, spName);
case DataBaseType.Oracle:
case DataBaseType.PostgreSQL:
case DataBaseType.DB2:
case DataBaseType.MySql:
case DataBaseType.FireBird:
case DataBaseType.DaMeng:
case DataBaseType.KingBaseES:
return string.Format("comment on column {0}.{1} is '{2}'", SqlFormat.Keyword(tableName, dalType), SqlFormat.Keyword(mcs.ColumnName, dalType), mcs.Description);
}
return string.Empty;
}
/// <summary>
/// <20><>ȡָ<C8A1><D6B8><EFBFBD>ı<EFBFBD><C4B1>ܹ<EFBFBD><DCB9><EFBFBD><EFBFBD>ɵ<EFBFBD>SQL(Create Table)<29><>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
internal static string CreateTableDescriptionSql(string tableName, MDataColumn columns, DataBaseType dalType)
{
string result = string.Empty;
string tbDescription = columns.Description.Replace("'", "''");
switch (dalType)
{
case DataBaseType.MsSql:
case DataBaseType.Oracle:
case DataBaseType.PostgreSQL:
case DataBaseType.MySql:
case DataBaseType.DB2:
case DataBaseType.FireBird:
case DataBaseType.DaMeng:
case DataBaseType.KingBaseES:
StringBuilder sb = new StringBuilder();
foreach (MCellStruct mcs in columns)
{
if (!string.IsNullOrEmpty(mcs.Description))
{
if (dalType == DataBaseType.MsSql)
{
sb.AppendFormat("exec sp_addextendedproperty N'MS_Description', N'{0}', N'user', N'dbo', N'table', N'{1}', N'column', N'{2}';\r\n", mcs.Description, tableName, mcs.ColumnName);
}
//else if (dalType == DataBaseType.Oracle || dalType == DataBaseType.DB2 || dalType == DataBaseType.FireBird || dalType == DataBaseType.DaMeng)
//{
// sb.AppendFormat("comment on column {0}.{1} is '{2}';\r\n", tableName.ToUpper(), mcs.ColumnName.ToUpper(), mcs.Description.Replace("'", "''"));
//}
else// if (dalType == DataBaseType.PostgreSQL)
{
sb.AppendFormat("comment on column {0}.{1} is '{2}';\r\n",
SqlFormat.Keyword(tableName, dalType), SqlFormat.Keyword(mcs.ColumnName, dalType), mcs.Description.Replace("'", "''"));
}
}
}
if (dalType == DataBaseType.MsSql)//<2F><><EFBFBD>ӱ<EFBFBD><D3B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
sb.AppendFormat("exec sp_addextendedproperty N'MS_Description', N'{0}', N'user', N'dbo', N'table', N'{1}';\r\n", tbDescription, tableName);
}
else if (dalType == DataBaseType.MySql)
{
sb.AppendFormat("alter table {0} comment = '{1}';\r\n", SqlFormat.Keyword(tableName, dalType), tbDescription);
}
//else// if (dalType == DataBaseType.Oracle || dalType == DataBaseType.DB2 || dalType == DataBaseType.FireBird || dalType == DataBaseType.DaMeng)
//{
// sb.AppendFormat("comment on table {0} is '{1}';\r\n",
// tableName.ToUpper(), tbDescription);
//}
else// if (dalType == DataBaseType.PostgreSQL)
{
sb.AppendFormat("comment on table {0} is '{1}';\r\n",
SqlFormat.Keyword(tableName, dalType), tbDescription);
}
result = sb.ToString().TrimEnd(';');
break;
}
return result;
}
/// <summary>
/// <20><>ȡָ<C8A1><D6B8><EFBFBD>ı<EFBFBD><C4B1>ܹ<EFBFBD><DCB9><EFBFBD><EFBFBD>ɵ<EFBFBD>SQL(Create Table)<29><><EFBFBD><EFBFBD>
/// </summary>
internal static string CreateTableSql(string tableName, MDataColumn columns, DataBaseType dalType, string version)
{
//<2F><>Ҫ<EFBFBD><D2AA>д<EFBFBD>ı<EFBFBD><C4B1><EFBFBD>
//if (dalType == DataBaseType.FireBird || dalType == DataBaseType.DaMeng)
//{
// tableName = tableName.ToUpper();
//}
switch (dalType)
{
case DataBaseType.Txt:
case DataBaseType.Xml:
return columns.ToJson(true);
default:
string createSql = string.Empty;
createSql = "CREATE TABLE " + SqlFormat.Keyword(tableName, dalType) + " \n(";
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
List<MCellStruct> primaryKeyList = new List<MCellStruct>();
foreach (MCellStruct column in columns)
{
if (column.IsPrimaryKey)
{
primaryKeyList.Add(column);
}
}
foreach (MCellStruct column in columns)
{
createSql += "\n " + GetKey(column, dalType, ref primaryKeyList, version);
}
if (primaryKeyList.Count > 0)
{
createSql += GetUnionPrimaryKey(dalType, primaryKeyList);
}
createSql = createSql.TrimEnd(',') + " \n)";
// createSql += GetSuffix(dalType);
if (dalType == DataBaseType.MySql)
{
if (createSql.IndexOf("CURRENT_TIMESTAMP") != createSql.LastIndexOf("CURRENT_TIMESTAMP"))
{
createSql = createSql.Replace("Default CURRENT_TIMESTAMP", string.Empty);//mysql<71><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD>CURRENT_TIMESTAMP<4D><50>
}
}
primaryKeyList.Clear();
return createSql;
}
}
private static string GetKey(MCellStruct column, DataBaseType dalType, ref List<MCellStruct> primaryKeyList, string version)
{
string key = SqlFormat.Keyword(column.ColumnName, dalType);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//<2F><>Ҫ<EFBFBD><D2AA>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//if (dalType == DataBaseType.FireBird || dalType == DataBaseType.DaMeng)
//{
// key = key.ToUpper();
//}
DataGroupType group = DataType.GetGroup(column.SqlType);//<2F><><EFBFBD>ݿ<EFBFBD><DDBF><EFBFBD><EFBFBD>͡<EFBFBD>
bool isAutoOrPKey = column.IsPrimaryKey || column.IsAutoIncrement;//<2F>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD>
if (dalType != DataBaseType.Access || !isAutoOrPKey || !column.IsAutoIncrement)
{
SqlDbType sdt = column.SqlType;
if (sdt == SqlDbType.DateTime && dalType == DataBaseType.MySql && Convert.ToString(column.DefaultValue) == SqlValue.GetDate)
{
column.SqlType = SqlDbType.Timestamp;
}
key += " " + DataType.GetDataType(column, dalType, version);
column.SqlType = sdt;
}
if (isAutoOrPKey)
{
if (column.IsAutoIncrement)
{
if (primaryKeyList.Count == 0 || (!column.IsPrimaryKey && dalType == DataBaseType.MySql))//MySql <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
{
column.IsPrimaryKey = true;
primaryKeyList.Insert(0, column);
}
}
switch (dalType)
{
case DataBaseType.Access:
if (column.IsAutoIncrement)
{
key += " autoincrement(1,1)";
}
else// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
if (group == DataGroupType.Guid)//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>GUID
{
key += " default GenGUID()";
}
}
break;
case DataBaseType.MsSql:
if (column.IsAutoIncrement)
{
key += " IDENTITY(1,1)";
}
else
{
if (group == DataGroupType.Guid)//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>GUID
{
key += " Default (newid())";
}
}
break;
case DataBaseType.Oracle:
if (Convert.ToString(column.DefaultValue) == SqlValue.Guid)//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>GUID
{
key += " Default (SYS_GUID())";
}
break;
case DataBaseType.Sybase:
if (column.IsAutoIncrement)
{
key += " IDENTITY";
}
else
{
if (group == DataGroupType.Guid)//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>GUID
{
key += " Default (newid())";
}
}
break;
case DataBaseType.MySql:
if (column.IsAutoIncrement)
{
key += " AUTO_INCREMENT";
if (!column.IsPrimaryKey)
{
primaryKeyList.Add(column);
}
}
break;
case DataBaseType.SQLite://sqlite<74><65>AUTOINCREMENT<4E><54><EFBFBD><EFBFBD>д<EFBFBD><D0B4>primarykeyǰ,
if (column.IsAutoIncrement)
{
key += " PRIMARY KEY AUTOINCREMENT";
primaryKeyList.Clear();//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
break;
case DataBaseType.PostgreSQL:
if (column.IsAutoIncrement && key.EndsWith("int"))
{
key = key.Substring(0, key.Length - 3) + "serial";
}
break;
case DataBaseType.DB2:
if (column.IsAutoIncrement)
{
key += " GENERATED ALWAYS AS IDENTITY";
}
break;
case DataBaseType.FireBird:
if (column.IsAutoIncrement)
{
key += " GENERATED BY DEFAULT AS IDENTITY";
}
break;
case DataBaseType.DaMeng:
if (column.IsAutoIncrement)
{
key += " IDENTITY(1, 1)";
}
break;
case DataBaseType.KingBaseES:
if (column.IsAutoIncrement)
{
key += " AUTO_INCREMENT";
}
break;
}
key += " NOT NULL";
}
else
{
string defaultValue = string.Empty;
if (Convert.ToString(column.DefaultValue).Length > 0 && group != DataGroupType.Object)//Ĭ<><C4AC>ֵֻ<D6B5><D6BB><EFBFBD>ǻ<EFBFBD><C7BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD>
{
if (dalType == DataBaseType.MySql)
{
if ((group == DataGroupType.Text && (column.MaxSize < 1 || column.MaxSize > 8000)) || (group == DataGroupType.Date && key.Contains("datetime"))) //ֻ<>ܶ<EFBFBD>TIMESTAMP<4D><50><EFBFBD>͵ĸ<CDB5>Ĭ<EFBFBD><C4AC>ֵ<EFBFBD><D6B5>
{
goto er;
}
}
defaultValue = SqlFormat.FormatDefaultValue(dalType, column.DefaultValue, 1, column.SqlType);
if (!string.IsNullOrEmpty(defaultValue))
{
if (dalType == DataBaseType.MySql) { defaultValue = defaultValue.Trim('(', ')'); }
key += " Default " + defaultValue;
}
}
er:
if (dalType != DataBaseType.Access)
{
if (dalType == DataBaseType.Sybase && column.SqlType == SqlDbType.Bit)
{
if (string.IsNullOrEmpty(defaultValue))
{
key += " Default 0";
}
key += " NOT NULL";//Sybase bit <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΪNull
}
else
{
if (column.IsCanNull && (dalType == DataBaseType.DB2 || dalType == DataBaseType.FireBird || dalType == DataBaseType.DaMeng || dalType == DataBaseType.KingBaseES)) { }//db2,firebird <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>null,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Բ<EFBFBD><D4B2><EFBFBD>Ҫnull
else
{
key += column.IsCanNull ? " NULL" : " NOT NULL";
}
}
}
}
if (!string.IsNullOrEmpty(column.Description))
{
switch (dalType)
{
case DataBaseType.MySql:
key += string.Format(" COMMENT '{0}'", column.Description.Replace("'", "''"));
break;
}
}
return key + ",";
}
private static string GetUnionPrimaryKey(DataBaseType dalType, List<MCellStruct> primaryKeyList)
{
string suffix = "\n ";
suffix += "PRIMARY KEY (";
foreach (MCellStruct st in primaryKeyList)
{
string cName = SqlFormat.Keyword(st.ColumnName, dalType);
//switch (dalType)//<2F><>д
//{
// case DataBaseType.DaMeng:
// case DataBaseType.FireBird:
// cName = cName.ToUpper();
// break;
//}
suffix += cName + ",";
}
suffix = suffix.TrimEnd(',') + ")";
return suffix;
}
#endregion
#region <EFBFBD><EFBFBD>ȡAlterTable<EFBFBD><EFBFBD><EFBFBD><EFBFBD>SQL<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// <summary>
/// <20><>ȡָ<C8A1><D6B8><EFBFBD>ı<EFBFBD><C4B1>ܹ<EFBFBD><DCB9><EFBFBD><EFBFBD>ɵ<EFBFBD>SQL(Alter Table)<29><><EFBFBD><EFBFBD>
/// </summary>
public static List<string> AlterTableSql(string tableName, MDataColumn columns, string conn)
{
List<string> sql = new List<string>();
string version = null;
DataBaseType dalType;
using (DalBase helper = DalCreate.CreateDal(conn))
{
helper.ChangeDatabaseWithCheck(tableName);//<2F><><EFBFBD><EFBFBD>dbname.dbo.tablename<6D><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (!helper.TestConn(AllowConnLevel.Master))
{
helper.Dispose();
return sql;
}
dalType = helper.DataBaseType;
version = helper.Version;
}
MDataColumn dbColumn = TableSchema.GetColumns(tableName, conn);//<2F><>ȡ<EFBFBD><C8A1><EFBFBD>ݿ<EFBFBD><DDBF><EFBFBD><EFBFBD>нṹ
if (dbColumn == null || dbColumn.Count == 0) { return sql; }
//<2F><>ʼ<EFBFBD>Ƚ<EFBFBD><C8BD><EFBFBD>ͬ
List<MCellStruct> primaryKeyList = new List<MCellStruct>();
string tbName = SqlFormat.Keyword(tableName, dalType);
string alterTable = "alter table " + tbName;
foreach (MCellStruct ms in columns)//<2F><><EFBFBD><EFBFBD><EFBFBD>µĽṹ
{
string cName = SqlFormat.Keyword(ms.ColumnName, dalType);
if (ms.AlterOp != AlterOp.None)
{
bool isContains = dbColumn.Contains(ms.ColumnName);
AlterOp op = ms.AlterOp;
if ((op & AlterOp.Rename) != 0)
{
op = (AlterOp)(op - AlterOp.Rename);
#region MyRegion Rename
if (!string.IsNullOrEmpty(ms.OldName) && ms.OldName != ms.ColumnName && !isContains)
{
string oName = SqlFormat.Keyword(ms.OldName, dalType);
switch (dalType)
{
case DataBaseType.MsSql:
sql.Add("exec sp_rename '" + tbName + "." + oName + "', '" + ms.ColumnName + "', 'column'");
break;
case DataBaseType.Sybase:
sql.Add("exec sp_rename \"" + tableName + "." + ms.OldName + "\", " + ms.ColumnName);
break;
case DataBaseType.MySql:
sql.Add(alterTable + " change " + oName + " " + GetKey(ms, dalType, ref primaryKeyList, version).TrimEnd(','));
break;
case DataBaseType.Oracle:
sql.Add(alterTable + " rename column " + oName + " to " + cName);
break;
}
isContains = isContains || dbColumn.Contains(ms.OldName);
}
#endregion
}
if (op == AlterOp.Drop)
{
#region MyRegion
if (isContains)
{
switch (dalType)
{
case DataBaseType.MsSql:
case DataBaseType.Access:
case DataBaseType.MySql:
case DataBaseType.Oracle:
if (dalType == DataBaseType.MsSql)
{
sql.Add(@"declare @name varchar(50) select @name =b.name from sysobjects b join syscolumns a on b.id = a.cdefault
where a.id = object_id('" + tableName + "') and a.name ='" + ms.ColumnName + "'if(@name!='') begin EXEC('alter table " + tableName + " drop constraint '+ @name) end");
}
sql.Add(alterTable + " drop column " + cName);
break;
case DataBaseType.Sybase:
sql.Add(alterTable + " drop " + cName);
break;
}
}
#endregion
}
//else if (ms.AlterOp == AlterOp.Rename)
//{
//}
else if (op == AlterOp.AddOrModify)
{
//<2F><><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
if (isContains) // <20><><EFBFBD>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD>޸<EFBFBD>
{
string alterSql = SqlFormat.Keyword(ms.ColumnName, dalType) + " " + DataType.GetDataType(ms, dalType, version);
//<2F><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>ͬ
MCellStruct dbStruct = dbColumn[ms.ColumnName] ?? dbColumn[ms.OldName];
if (dbStruct.IsCanNull != ms.IsCanNull || dbStruct.SqlType != ms.SqlType || dbStruct.MaxSize != ms.MaxSize || dbStruct.Scale != ms.Scale)
{
string modify = "";
switch (dalType)
{
case DataBaseType.Oracle:
case DataBaseType.Sybase:
modify = " modify ";
break;
case DataBaseType.MySql:
modify = " change " + cName + " ";
break;
case DataBaseType.MsSql:
case DataBaseType.Access:
case DataBaseType.PostgreSQL:
modify = " alter column ";
break;
}
if (ms.IsCanNull != dbStruct.IsCanNull)
{
alterSql += (ms.IsCanNull ? " NULL" : " NOT NULL");
}
sql.Add(alterTable + modify + alterSql);
}
}
else //<2F><><EFBFBD>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
sql.Add(alterTable + " add " + GetKey(ms, dalType, ref primaryKeyList, version).TrimEnd(','));
if (!string.IsNullOrEmpty(ms.Description))
{
string description = SqlCreateForSchema.GetTableDescriptionSql(tableName, ms, dalType, true);
if (!string.IsNullOrEmpty(description))
{
sql.Add(description);
}
}
}
}
}
}
return sql;
}
#endregion
}
}