mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 09:15:27 +08:00 
			
		
		
		
	oracle CodeFirst 进行中
This commit is contained in:
		
							
								
								
									
										220
									
								
								FreeSql.Tests/Oracle/OracleCodeFirstTest.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										220
									
								
								FreeSql.Tests/Oracle/OracleCodeFirstTest.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,220 @@
 | 
				
			|||||||
 | 
					using FreeSql.DataAnnotations;
 | 
				
			||||||
 | 
					using Newtonsoft.Json;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using Xunit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace FreeSql.Tests.Oracle {
 | 
				
			||||||
 | 
						public class OracleCodeFirstTest {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[Fact]
 | 
				
			||||||
 | 
							public void AddField() {
 | 
				
			||||||
 | 
								var sql = g.oracle.CodeFirst.GetComparisonDDLStatements<TopicAddField>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var id = g.oracle.Insert<TopicAddField>().AppendData(new TopicAddField { }).ExecuteIdentity();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								//var inserted = g.oracle.Insert<TopicAddField>().AppendData(new TopicAddField { }).ExecuteInserted();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[Table(Name = "TopicAddField", OldName = "xxxtb.TopicAddField")]
 | 
				
			||||||
 | 
							public class TopicAddField {
 | 
				
			||||||
 | 
								[Column(IsIdentity = true)]
 | 
				
			||||||
 | 
								public int Id { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								public string name { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								[Column(DbType = "varchar2(200 char) not null", OldName = "title")]
 | 
				
			||||||
 | 
								public string title2 { get; set; } = "10";
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[Fact]
 | 
				
			||||||
 | 
							public void GetComparisonDDLStatements() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var sql = g.oracle.CodeFirst.GetComparisonDDLStatements<TableAllType>();
 | 
				
			||||||
 | 
								if (string.IsNullOrEmpty(sql) == false) {
 | 
				
			||||||
 | 
									Assert.Equal(@"CREATE TABLE IF NOT EXISTS `cccddd`.`tb_alltype` ( 
 | 
				
			||||||
 | 
					  `Id` INT(11) NOT NULL AUTO_INCREMENT, 
 | 
				
			||||||
 | 
					  `testFieldBool` BIT(1) NOT NULL, 
 | 
				
			||||||
 | 
					  `testFieldSByte` TINYINT(3) NOT NULL, 
 | 
				
			||||||
 | 
					  `testFieldShort` SMALLINT(6) NOT NULL, 
 | 
				
			||||||
 | 
					  `testFieldInt` INT(11) NOT NULL, 
 | 
				
			||||||
 | 
					  `testFieldLong` BIGINT(20) NOT NULL, 
 | 
				
			||||||
 | 
					  `testFieldByte` TINYINT(3) UNSIGNED NOT NULL, 
 | 
				
			||||||
 | 
					  `testFieldUShort` SMALLINT(5) UNSIGNED NOT NULL, 
 | 
				
			||||||
 | 
					  `testFieldUInt` INT(10) UNSIGNED NOT NULL, 
 | 
				
			||||||
 | 
					  `testFieldULong` BIGINT(20) UNSIGNED NOT NULL, 
 | 
				
			||||||
 | 
					  `testFieldDouble` DOUBLE NOT NULL, 
 | 
				
			||||||
 | 
					  `testFieldFloat` FLOAT NOT NULL, 
 | 
				
			||||||
 | 
					  `testFieldDecimal` DECIMAL(10,2) NOT NULL, 
 | 
				
			||||||
 | 
					  `testFieldTimeSpan` TIME NOT NULL, 
 | 
				
			||||||
 | 
					  `testFieldDateTime` DATETIME NOT NULL, 
 | 
				
			||||||
 | 
					  `testFieldBytes` VARBINARY(255), 
 | 
				
			||||||
 | 
					  `testFieldString` VARCHAR(255), 
 | 
				
			||||||
 | 
					  `testFieldGuid` VARCHAR(36), 
 | 
				
			||||||
 | 
					  `testFieldBoolNullable` BIT(1), 
 | 
				
			||||||
 | 
					  `testFieldSByteNullable` TINYINT(3), 
 | 
				
			||||||
 | 
					  `testFieldShortNullable` SMALLINT(6), 
 | 
				
			||||||
 | 
					  `testFieldIntNullable` INT(11), 
 | 
				
			||||||
 | 
					  `testFielLongNullable` BIGINT(20), 
 | 
				
			||||||
 | 
					  `testFieldByteNullable` TINYINT(3) UNSIGNED, 
 | 
				
			||||||
 | 
					  `testFieldUShortNullable` SMALLINT(5) UNSIGNED, 
 | 
				
			||||||
 | 
					  `testFieldUIntNullable` INT(10) UNSIGNED, 
 | 
				
			||||||
 | 
					  `testFieldULongNullable` BIGINT(20) UNSIGNED, 
 | 
				
			||||||
 | 
					  `testFieldDoubleNullable` DOUBLE, 
 | 
				
			||||||
 | 
					  `testFieldFloatNullable` FLOAT, 
 | 
				
			||||||
 | 
					  `testFieldDecimalNullable` DECIMAL(10,2), 
 | 
				
			||||||
 | 
					  `testFieldTimeSpanNullable` TIME, 
 | 
				
			||||||
 | 
					  `testFieldDateTimeNullable` DATETIME, 
 | 
				
			||||||
 | 
					  `testFieldGuidNullable` VARCHAR(36), 
 | 
				
			||||||
 | 
					  `testFieldPoint` POINT, 
 | 
				
			||||||
 | 
					  `testFieldLineString` LINESTRING, 
 | 
				
			||||||
 | 
					  `testFieldPolygon` POLYGON, 
 | 
				
			||||||
 | 
					  `testFieldMultiPoint` MULTIPOINT, 
 | 
				
			||||||
 | 
					  `testFieldMultiLineString` MULTILINESTRING, 
 | 
				
			||||||
 | 
					  `testFieldMultiPolygon` MULTIPOLYGON, 
 | 
				
			||||||
 | 
					  `testFieldEnum1` ENUM('E1','E2','E3') NOT NULL, 
 | 
				
			||||||
 | 
					  `testFieldEnum1Nullable` ENUM('E1','E2','E3'), 
 | 
				
			||||||
 | 
					  `testFieldEnum2` SET('F1','F2','F3') NOT NULL, 
 | 
				
			||||||
 | 
					  `testFieldEnum2Nullable` SET('F1','F2','F3'), 
 | 
				
			||||||
 | 
					  PRIMARY KEY (`Id`)
 | 
				
			||||||
 | 
					) Engine=InnoDB CHARACTER SET utf8;
 | 
				
			||||||
 | 
					", sql);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								//sql = g.oracle.CodeFirst.GetComparisonDDLStatements<Tb_alltype>();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							IInsert<TableAllType> insert => g.oracle.Insert<TableAllType>();
 | 
				
			||||||
 | 
							ISelect<TableAllType> select => g.oracle.Select<TableAllType>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[Fact]
 | 
				
			||||||
 | 
							public void CurdAllField() {
 | 
				
			||||||
 | 
								var item = new TableAllType { };
 | 
				
			||||||
 | 
								item.Id = (int)insert.AppendData(item).ExecuteIdentity();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var newitem = select.Where(a => a.Id == item.Id).ToOne();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var item2 = new TableAllType {
 | 
				
			||||||
 | 
									testFieldBool = true,
 | 
				
			||||||
 | 
									testFieldBoolNullable = true,
 | 
				
			||||||
 | 
									testFieldByte = 255,
 | 
				
			||||||
 | 
									testFieldByteNullable = 127,
 | 
				
			||||||
 | 
									testFieldBytes = Encoding.UTF8.GetBytes("<22><><EFBFBD><EFBFBD><EFBFBD>й<EFBFBD><D0B9><EFBFBD>"),
 | 
				
			||||||
 | 
									testFieldDateTime = DateTime.Now,
 | 
				
			||||||
 | 
									testFieldDateTimeNullable = DateTime.Now.AddHours(-1),
 | 
				
			||||||
 | 
									testFieldDecimal = 99.99M,
 | 
				
			||||||
 | 
									testFieldDecimalNullable = 99.98M,
 | 
				
			||||||
 | 
									testFieldDouble = 999.99,
 | 
				
			||||||
 | 
									testFieldDoubleNullable = 999.98,
 | 
				
			||||||
 | 
									testFieldEnum1 = TableAllTypeEnumType1.e5,
 | 
				
			||||||
 | 
									testFieldEnum1Nullable = TableAllTypeEnumType1.e3,
 | 
				
			||||||
 | 
									testFieldEnum2 = TableAllTypeEnumType2.f2,
 | 
				
			||||||
 | 
									testFieldEnum2Nullable = TableAllTypeEnumType2.f3,
 | 
				
			||||||
 | 
									testFieldFloat = 19.99F,
 | 
				
			||||||
 | 
									testFieldFloatNullable = 19.98F,
 | 
				
			||||||
 | 
									testFieldGuid = Guid.NewGuid(),
 | 
				
			||||||
 | 
									testFieldGuidNullable = Guid.NewGuid(),
 | 
				
			||||||
 | 
									testFieldInt = int.MaxValue,
 | 
				
			||||||
 | 
									testFieldIntNullable = int.MinValue,
 | 
				
			||||||
 | 
									testFieldLineString = new MygisLineString(new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10) }),
 | 
				
			||||||
 | 
									testFieldLong = long.MaxValue,
 | 
				
			||||||
 | 
									testFieldMultiLineString = new MygisMultiLineString(new[] {
 | 
				
			||||||
 | 
										new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10) },
 | 
				
			||||||
 | 
										new[] { new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 100) } }),
 | 
				
			||||||
 | 
									testFieldMultiPoint = new MygisMultiPoint(new[] { new MygisCoordinate2D(11, 11), new MygisCoordinate2D(51, 11) }),
 | 
				
			||||||
 | 
									testFieldMultiPolygon = new MygisMultiPolygon(new[] {
 | 
				
			||||||
 | 
										new MygisPolygon(new[] {
 | 
				
			||||||
 | 
											new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) },
 | 
				
			||||||
 | 
											new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) },
 | 
				
			||||||
 | 
											new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) },
 | 
				
			||||||
 | 
											new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) } }),
 | 
				
			||||||
 | 
										new MygisPolygon(new[] {
 | 
				
			||||||
 | 
											new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) },
 | 
				
			||||||
 | 
											new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) },
 | 
				
			||||||
 | 
											new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) },
 | 
				
			||||||
 | 
											new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) } }) }),
 | 
				
			||||||
 | 
									testFieldPoint = new MygisPoint(99, 99),
 | 
				
			||||||
 | 
									testFieldPolygon = new MygisPolygon(new[] {
 | 
				
			||||||
 | 
										new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) },
 | 
				
			||||||
 | 
											new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) },
 | 
				
			||||||
 | 
											new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) },
 | 
				
			||||||
 | 
											new[] { new MygisCoordinate2D(10, 10), new MygisCoordinate2D(50, 10), new MygisCoordinate2D(10, 50), new MygisCoordinate2D(10, 10) } }),
 | 
				
			||||||
 | 
									testFieldSByte = 100,
 | 
				
			||||||
 | 
									testFieldSByteNullable = 99,
 | 
				
			||||||
 | 
									testFieldShort = short.MaxValue,
 | 
				
			||||||
 | 
									testFieldShortNullable = short.MinValue,
 | 
				
			||||||
 | 
									testFieldString = "<22><><EFBFBD><EFBFBD><EFBFBD>й<EFBFBD><D0B9><EFBFBD>string",
 | 
				
			||||||
 | 
									testFieldTimeSpan = TimeSpan.FromSeconds(999),
 | 
				
			||||||
 | 
									testFieldTimeSpanNullable = TimeSpan.FromSeconds(60),
 | 
				
			||||||
 | 
									testFieldUInt = uint.MaxValue,
 | 
				
			||||||
 | 
									testFieldUIntNullable = uint.MinValue,
 | 
				
			||||||
 | 
									testFieldULong = ulong.MaxValue,
 | 
				
			||||||
 | 
									testFieldULongNullable = ulong.MinValue,
 | 
				
			||||||
 | 
									testFieldUShort = ushort.MaxValue,
 | 
				
			||||||
 | 
									testFieldUShortNullable = ushort.MinValue,
 | 
				
			||||||
 | 
									testFielLongNullable = long.MinValue
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
								item2.Id = (int)insert.AppendData(item2).ExecuteIdentity();
 | 
				
			||||||
 | 
								var newitem2 = select.Where(a => a.Id == item2.Id).ToOne();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var items = select.ToList();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[Table(Name = "tb_alltype")]
 | 
				
			||||||
 | 
							class TableAllType {
 | 
				
			||||||
 | 
								[Column(IsIdentity = true, IsPrimary = true)]
 | 
				
			||||||
 | 
								public int Id { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								public bool testFieldBool { get; set; }
 | 
				
			||||||
 | 
								public sbyte testFieldSByte { get; set; }
 | 
				
			||||||
 | 
								public short testFieldShort { get; set; }
 | 
				
			||||||
 | 
								public int testFieldInt { get; set; }
 | 
				
			||||||
 | 
								public long testFieldLong { get; set; }
 | 
				
			||||||
 | 
								public byte testFieldByte { get; set; }
 | 
				
			||||||
 | 
								public ushort testFieldUShort { get; set; }
 | 
				
			||||||
 | 
								public uint testFieldUInt { get; set; }
 | 
				
			||||||
 | 
								public ulong testFieldULong { get; set; }
 | 
				
			||||||
 | 
								public double testFieldDouble { get; set; }
 | 
				
			||||||
 | 
								public float testFieldFloat { get; set; }
 | 
				
			||||||
 | 
								public decimal testFieldDecimal { get; set; }
 | 
				
			||||||
 | 
								public TimeSpan testFieldTimeSpan { get; set; }
 | 
				
			||||||
 | 
								public DateTime testFieldDateTime { get; set; }
 | 
				
			||||||
 | 
								public byte[] testFieldBytes { get; set; }
 | 
				
			||||||
 | 
								public string testFieldString { get; set; }
 | 
				
			||||||
 | 
								public Guid testFieldGuid { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								public bool? testFieldBoolNullable { get; set; }
 | 
				
			||||||
 | 
								public sbyte? testFieldSByteNullable { get; set; }
 | 
				
			||||||
 | 
								public short? testFieldShortNullable { get; set; }
 | 
				
			||||||
 | 
								public int? testFieldIntNullable { get; set; }
 | 
				
			||||||
 | 
								public long? testFielLongNullable { get; set; }
 | 
				
			||||||
 | 
								public byte? testFieldByteNullable { get; set; }
 | 
				
			||||||
 | 
								public ushort? testFieldUShortNullable { get; set; }
 | 
				
			||||||
 | 
								public uint? testFieldUIntNullable { get; set; }
 | 
				
			||||||
 | 
								public ulong? testFieldULongNullable { get; set; }
 | 
				
			||||||
 | 
								public double? testFieldDoubleNullable { get; set; }
 | 
				
			||||||
 | 
								public float? testFieldFloatNullable { get; set; }
 | 
				
			||||||
 | 
								public decimal? testFieldDecimalNullable { get; set; }
 | 
				
			||||||
 | 
								public TimeSpan? testFieldTimeSpanNullable { get; set; }
 | 
				
			||||||
 | 
								public DateTime? testFieldDateTimeNullable { get; set; }
 | 
				
			||||||
 | 
								public Guid? testFieldGuidNullable { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								public MygisPoint testFieldPoint { get; set; }
 | 
				
			||||||
 | 
								public MygisLineString testFieldLineString { get; set; }
 | 
				
			||||||
 | 
								public MygisPolygon testFieldPolygon { get; set; }
 | 
				
			||||||
 | 
								public MygisMultiPoint testFieldMultiPoint { get; set; }
 | 
				
			||||||
 | 
								public MygisMultiLineString testFieldMultiLineString { get; set; }
 | 
				
			||||||
 | 
								public MygisMultiPolygon testFieldMultiPolygon { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								public TableAllTypeEnumType1 testFieldEnum1 { get; set; }
 | 
				
			||||||
 | 
								public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; }
 | 
				
			||||||
 | 
								public TableAllTypeEnumType2 testFieldEnum2 { get; set; }
 | 
				
			||||||
 | 
								public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; }
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public enum TableAllTypeEnumType1 { e1, e2, e3, e5 }
 | 
				
			||||||
 | 
							[Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 }
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -28,4 +28,9 @@ public class g {
 | 
				
			|||||||
		.UseAutoSyncStructure(true)
 | 
							.UseAutoSyncStructure(true)
 | 
				
			||||||
		.UseSyncStructureToLower(true)
 | 
							.UseSyncStructureToLower(true)
 | 
				
			||||||
		.Build();
 | 
							.Build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public static IFreeSql oracle = new FreeSql.FreeSqlBuilder()
 | 
				
			||||||
 | 
							.UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=10")
 | 
				
			||||||
 | 
							.UseAutoSyncStructure(true)
 | 
				
			||||||
 | 
							.Build();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -92,7 +92,7 @@ namespace FreeSql {
 | 
				
			|||||||
				case DataType.MySql: ret = new MySql.MySqlProvider(_cache, _logger, _masterConnectionString, _slaveConnectionString); break;
 | 
									case DataType.MySql: ret = new MySql.MySqlProvider(_cache, _logger, _masterConnectionString, _slaveConnectionString); break;
 | 
				
			||||||
				case DataType.SqlServer: ret = new SqlServer.SqlServerProvider(_cache, _logger, _masterConnectionString, _slaveConnectionString); break;
 | 
									case DataType.SqlServer: ret = new SqlServer.SqlServerProvider(_cache, _logger, _masterConnectionString, _slaveConnectionString); break;
 | 
				
			||||||
				case DataType.PostgreSQL: ret = new PostgreSQL.PostgreSQLProvider(_cache, _logger, _masterConnectionString, _slaveConnectionString); break;
 | 
									case DataType.PostgreSQL: ret = new PostgreSQL.PostgreSQLProvider(_cache, _logger, _masterConnectionString, _slaveConnectionString); break;
 | 
				
			||||||
				//case DataType.Oracle: ret = new Oracle.OracleProvider(_cache, _logger, _masterConnectionString, _slaveConnectionString); break;
 | 
									case DataType.Oracle: ret = new Oracle.OracleProvider(_cache, _logger, _masterConnectionString, _slaveConnectionString); break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (ret != null) {
 | 
								if (ret != null) {
 | 
				
			||||||
				ret.CodeFirst.IsAutoSyncStructure = _isAutoSyncStructure;
 | 
									ret.CodeFirst.IsAutoSyncStructure = _isAutoSyncStructure;
 | 
				
			||||||
@@ -105,5 +105,5 @@ namespace FreeSql {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public enum DataType { MySql, SqlServer, PostgreSQL, /*Oracle*/ }
 | 
						public enum DataType { MySql, SqlServer, PostgreSQL, Oracle }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -56,10 +56,18 @@ namespace FreeSql.Internal {
 | 
				
			|||||||
				if (colattr.DbType?.Contains("NOT NULL") == true) colattr.IsNullable = false;
 | 
									if (colattr.DbType?.Contains("NOT NULL") == true) colattr.IsNullable = false;
 | 
				
			||||||
				if (string.IsNullOrEmpty(colattr.Name)) colattr.Name = p.Name;
 | 
									if (string.IsNullOrEmpty(colattr.Name)) colattr.Name = p.Name;
 | 
				
			||||||
				if (common.CodeFirst.IsSyncStructureToLower) colattr.Name = colattr.Name.ToLower();
 | 
									if (common.CodeFirst.IsSyncStructureToLower) colattr.Name = colattr.Name.ToLower();
 | 
				
			||||||
				
 | 
					
 | 
				
			||||||
				if ((colattr.IsNullable == false || colattr.IsIdentity || colattr.IsPrimary) && colattr.DbType.Contains("NOT NULL") == false) colattr.DbType += " NOT NULL";
 | 
									if ((colattr.IsNullable == false || colattr.IsIdentity || colattr.IsPrimary) && colattr.DbType.Contains("NOT NULL") == false) {
 | 
				
			||||||
 | 
										colattr.IsNullable = false;
 | 
				
			||||||
 | 
										colattr.DbType += " NOT NULL";
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				if (colattr.IsNullable == true && colattr.DbType.Contains("NOT NULL")) colattr.DbType = colattr.DbType.Replace("NOT NULL", "");
 | 
									if (colattr.IsNullable == true && colattr.DbType.Contains("NOT NULL")) colattr.DbType = colattr.DbType.Replace("NOT NULL", "");
 | 
				
			||||||
				colattr.DbType = Regex.Replace(colattr.DbType, @"\([^\)]+\)", m => Regex.Replace(m.Groups[0].Value, @"\s", ""));
 | 
									colattr.DbType = Regex.Replace(colattr.DbType, @"\([^\)]+\)", m => {
 | 
				
			||||||
 | 
										var tmpLt = Regex.Replace(m.Groups[0].Value, @"\s", "");
 | 
				
			||||||
 | 
										if (tmpLt.Contains("CHAR")) tmpLt = tmpLt.Replace("CHAR", " CHAR");
 | 
				
			||||||
 | 
										if (tmpLt.Contains("BYTE")) tmpLt = tmpLt.Replace("BYTE", " BYTE");
 | 
				
			||||||
 | 
										return tmpLt;
 | 
				
			||||||
 | 
									});
 | 
				
			||||||
				colattr.DbDefautValue = trytb.Properties[p.Name].GetValue(Activator.CreateInstance(trytb.Type));
 | 
									colattr.DbDefautValue = trytb.Properties[p.Name].GetValue(Activator.CreateInstance(trytb.Type));
 | 
				
			||||||
				if (colattr.DbDefautValue == null) colattr.DbDefautValue = tp?.defaultValue;
 | 
									if (colattr.DbDefautValue == null) colattr.DbDefautValue = tp?.defaultValue;
 | 
				
			||||||
				if (colattr.IsNullable == false && colattr.DbDefautValue == null) {
 | 
									if (colattr.IsNullable == false && colattr.DbDefautValue == null) {
 | 
				
			||||||
@@ -77,7 +85,11 @@ namespace FreeSql.Internal {
 | 
				
			|||||||
				trytb.ColumnsByCs.Add(p.Name, col);
 | 
									trytb.ColumnsByCs.Add(p.Name, col);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary).ToArray();
 | 
								trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary).ToArray();
 | 
				
			||||||
			if (trytb.Primarys.Any() == false) trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsIdentity).ToArray();
 | 
								if (trytb.Primarys.Any() == false) {
 | 
				
			||||||
 | 
									trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsIdentity).ToArray();
 | 
				
			||||||
 | 
									foreach(var col in trytb.Primarys)
 | 
				
			||||||
 | 
										col.Attribute.IsPrimary = true;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			_cacheGetTableByEntity.TryAdd(entity.FullName, trytb);
 | 
								_cacheGetTableByEntity.TryAdd(entity.FullName, trytb);
 | 
				
			||||||
			return trytb;
 | 
								return trytb;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -49,7 +49,7 @@ namespace FreeSql.MySql {
 | 
				
			|||||||
				{ typeof(byte[]).FullName,  (MySqlDbType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) },
 | 
									{ typeof(byte[]).FullName,  (MySqlDbType.VarBinary, "varbinary", "varbinary(255)", false, null, new byte[0]) },
 | 
				
			||||||
				{ typeof(string).FullName,  (MySqlDbType.VarChar, "varchar", "varchar(255)", false, null, "") },
 | 
									{ typeof(string).FullName,  (MySqlDbType.VarChar, "varchar", "varchar(255)", false, null, "") },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				{ typeof(Guid).FullName,  (MySqlDbType.VarChar, "char", "char(36)", false, false, Guid.Empty) },{ typeof(Guid?).FullName,  (MySqlDbType.VarChar, "char", "char(36)", false, true, null) },
 | 
									{ typeof(Guid).FullName,  (MySqlDbType.VarChar, "char", "char(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName,  (MySqlDbType.VarChar, "char", "char(36)", false, true, null) },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				{ typeof(MygisPoint).FullName,  (MySqlDbType.Geometry, "point", "point", false, null, new MygisPoint(0, 0)) },
 | 
									{ typeof(MygisPoint).FullName,  (MySqlDbType.Geometry, "point", "point", false, null, new MygisPoint(0, 0)) },
 | 
				
			||||||
				{ typeof(MygisLineString).FullName,  (MySqlDbType.Geometry, "linestring", "linestring", false, null, new MygisLineString(new[]{new MygisCoordinate2D(),new MygisCoordinate2D()})) },
 | 
									{ typeof(MygisLineString).FullName,  (MySqlDbType.Geometry, "linestring", "linestring", false, null, new MygisLineString(new[]{new MygisCoordinate2D(),new MygisCoordinate2D()})) },
 | 
				
			||||||
@@ -229,9 +229,9 @@ where a.table_schema in ({0}) and a.table_name in ({1})".FormatMySql(tboldname ?
 | 
				
			|||||||
								//insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})";
 | 
													//insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})";
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
							if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable)
 | 
												if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable)
 | 
				
			||||||
								insertvalue = $"ifnull({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''")})";
 | 
													insertvalue = $"ifnull({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)})";
 | 
				
			||||||
						} else if (tbcol.Attribute.IsNullable == false)
 | 
											} else if (tbcol.Attribute.IsNullable == false)
 | 
				
			||||||
							insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''");
 | 
												insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue);
 | 
				
			||||||
						sb.Append(insertvalue).Append(", ");
 | 
											sb.Append(insertvalue).Append(", ");
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n");
 | 
										sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
using FreeSql.Internal;
 | 
					using FreeSql.Internal;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Data;
 | 
					using System.Data;
 | 
				
			||||||
using System.Text;
 | 
					using System.Text;
 | 
				
			||||||
@@ -12,34 +13,10 @@ namespace FreeSql.Oracle.Curd {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public override List<T1> ExecuteDeleted() {
 | 
							public override List<T1> ExecuteDeleted() {
 | 
				
			||||||
			var sql = this.ToSql();
 | 
								throw new NotImplementedException();
 | 
				
			||||||
			if (string.IsNullOrEmpty(sql)) return new List<T1>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			var sb = new StringBuilder();
 | 
					 | 
				
			||||||
			sb.Append(sql).Append(" RETURNING ");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			var colidx = 0;
 | 
					 | 
				
			||||||
			foreach (var col in _table.Columns.Values) {
 | 
					 | 
				
			||||||
				if (colidx > 0) sb.Append(", ");
 | 
					 | 
				
			||||||
				sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
 | 
					 | 
				
			||||||
				++colidx;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return _orm.Ado.Query<T1>(CommandType.Text, sb.ToString(), _params.ToArray());
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		async public override Task<List<T1>> ExecuteDeletedAsync() {
 | 
							public override Task<List<T1>> ExecuteDeletedAsync() {
 | 
				
			||||||
			var sql = this.ToSql();
 | 
								throw new NotImplementedException();
 | 
				
			||||||
			if (string.IsNullOrEmpty(sql)) return new List<T1>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			var sb = new StringBuilder();
 | 
					 | 
				
			||||||
			sb.Append(sql).Append(" RETURNING ");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			var colidx = 0;
 | 
					 | 
				
			||||||
			foreach (var col in _table.Columns.Values) {
 | 
					 | 
				
			||||||
				if (colidx > 0) sb.Append(", ");
 | 
					 | 
				
			||||||
				sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
 | 
					 | 
				
			||||||
				++colidx;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return await _orm.Ado.QueryAsync<T1>(CommandType.Text, sb.ToString(), _params.ToArray());
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,7 @@
 | 
				
			|||||||
using FreeSql.Internal;
 | 
					using FreeSql.Internal;
 | 
				
			||||||
 | 
					using FreeSql.Internal.Model;
 | 
				
			||||||
 | 
					using Oracle.ManagedDataAccess.Client;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Data;
 | 
					using System.Data;
 | 
				
			||||||
using System.Data.Common;
 | 
					using System.Data.Common;
 | 
				
			||||||
@@ -18,29 +21,35 @@ namespace FreeSql.Oracle.Curd {
 | 
				
			|||||||
			var sb = new StringBuilder();
 | 
								var sb = new StringBuilder();
 | 
				
			||||||
			sb.Append("INSERT INTO ").Append(_commonUtils.QuoteSqlName(_table.DbName)).Append("(");
 | 
								sb.Append("INSERT INTO ").Append(_commonUtils.QuoteSqlName(_table.DbName)).Append("(");
 | 
				
			||||||
			var colidx = 0;
 | 
								var colidx = 0;
 | 
				
			||||||
 | 
								var colidxAndIdent = 0;
 | 
				
			||||||
			foreach (var col in _table.Columns.Values)
 | 
								foreach (var col in _table.Columns.Values)
 | 
				
			||||||
				if (_ignore.ContainsKey(col.Attribute.Name) == false) {
 | 
									if (_ignore.ContainsKey(col.Attribute.Name) == false) {
 | 
				
			||||||
					if (colidx > 0) sb.Append(", ");
 | 
										if (colidxAndIdent > 0) sb.Append(", ");
 | 
				
			||||||
					sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name));
 | 
										sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name));
 | 
				
			||||||
					++colidx;
 | 
										if (col.Attribute.IsIdentity == false) ++colidx;
 | 
				
			||||||
 | 
										++colidxAndIdent;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			sb.Append(") VALUES");
 | 
								sb.Append(") VALUES");
 | 
				
			||||||
 | 
								_identCol = null;
 | 
				
			||||||
			_params = new DbParameter[colidx * _source.Count];
 | 
								_params = new DbParameter[colidx * _source.Count];
 | 
				
			||||||
			var didx = 0;
 | 
								var didx = 0;
 | 
				
			||||||
			foreach (var d in _source) {
 | 
								foreach (var d in _source) {
 | 
				
			||||||
				if (didx > 0) sb.Append(", ");
 | 
									if (didx > 0) sb.Append(", ");
 | 
				
			||||||
				sb.Append("(");
 | 
									sb.Append("(");
 | 
				
			||||||
				var colidx2 = 0;
 | 
									var colidx2 = 0;
 | 
				
			||||||
 | 
									var colidx2AndIdent = 0;
 | 
				
			||||||
				foreach (var col in _table.Columns.Values)
 | 
									foreach (var col in _table.Columns.Values)
 | 
				
			||||||
					if (_ignore.ContainsKey(col.Attribute.Name) == false) {
 | 
										if (_ignore.ContainsKey(col.Attribute.Name) == false) {
 | 
				
			||||||
						if (colidx2 > 0) sb.Append(", ");
 | 
											if (colidx2AndIdent > 0) sb.Append(", ");
 | 
				
			||||||
						if (col.Attribute.IsIdentity) {
 | 
											if (col.Attribute.IsIdentity) {
 | 
				
			||||||
							sb.Append(_commonUtils.QuoteSqlName($"{Utils.GetCsName(_table.DbName)}_seq_{col.Attribute.Name}")).Append(".nextval");
 | 
												sb.Append(_commonUtils.QuoteSqlName($"{Utils.GetCsName(_table.DbName)}_seq_{col.Attribute.Name}")).Append(".nextval");
 | 
				
			||||||
 | 
												_identCol = col;
 | 
				
			||||||
						} else {
 | 
											} else {
 | 
				
			||||||
							sb.Append(_commonUtils.QuoteWriteParamter(col.CsType, $"{_commonUtils.QuoteParamterName(col.CsName)}{didx}"));
 | 
												sb.Append(_commonUtils.QuoteWriteParamter(col.CsType, $"{_commonUtils.QuoteParamterName(col.CsName)}{didx}"));
 | 
				
			||||||
							_params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}{didx}", col.CsType, _table.Properties.TryGetValue(col.CsName, out var tryp) ? tryp.GetValue(d) : null);
 | 
												_params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}{didx}", col.CsType, _table.Properties.TryGetValue(col.CsName, out var tryp) ? tryp.GetValue(d) : null);
 | 
				
			||||||
 | 
												++colidx2;
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						++colidx2;
 | 
											++colidx2AndIdent;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				sb.Append(")");
 | 
									sb.Append(")");
 | 
				
			||||||
				++didx;
 | 
									++didx;
 | 
				
			||||||
@@ -48,58 +57,83 @@ namespace FreeSql.Oracle.Curd {
 | 
				
			|||||||
			return sb.ToString();
 | 
								return sb.ToString();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ColumnInfo _identCol;
 | 
				
			||||||
		public override long ExecuteIdentity() {
 | 
							public override long ExecuteIdentity() {
 | 
				
			||||||
			var sql = this.ToSql();
 | 
								var sql = this.ToSql();
 | 
				
			||||||
			if (string.IsNullOrEmpty(sql)) return 0;
 | 
								if (string.IsNullOrEmpty(sql)) return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity);
 | 
								if (_identCol == null) {
 | 
				
			||||||
			if (identCols.Any() == false) {
 | 
					 | 
				
			||||||
				_orm.Ado.ExecuteNonQuery(CommandType.Text, sql, _params);
 | 
									_orm.Ado.ExecuteNonQuery(CommandType.Text, sql, _params);
 | 
				
			||||||
				return 0;
 | 
									return 0;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)), _params)), out var trylng) ? trylng : 0;
 | 
								var identColName = _commonUtils.QuoteSqlName(_identCol.Attribute.Name);
 | 
				
			||||||
 | 
								var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol.CsType, 0) as OracleParameter;
 | 
				
			||||||
 | 
								identParam.Direction = ParameterDirection.Output;
 | 
				
			||||||
 | 
								_orm.Ado.ExecuteNonQuery(CommandType.Text, $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}", _params.Concat(new[] { identParam }).ToArray());
 | 
				
			||||||
 | 
								return long.TryParse(string.Concat(identParam.Value), out var trylng) ? trylng : 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		async public override Task<long> ExecuteIdentityAsync() {
 | 
							async public override Task<long> ExecuteIdentityAsync() {
 | 
				
			||||||
			var sql = this.ToSql();
 | 
								var sql = this.ToSql();
 | 
				
			||||||
			if (string.IsNullOrEmpty(sql)) return 0;
 | 
								if (string.IsNullOrEmpty(sql)) return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity);
 | 
								if (_identCol == null) {
 | 
				
			||||||
			if (identCols.Any() == false) {
 | 
					 | 
				
			||||||
				await _orm.Ado.ExecuteNonQueryAsync(CommandType.Text, sql, _params);
 | 
									await _orm.Ado.ExecuteNonQueryAsync(CommandType.Text, sql, _params);
 | 
				
			||||||
				return 0;
 | 
									return 0;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(CommandType.Text, string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)), _params)), out var trylng) ? trylng : 0;
 | 
								var identColName = _commonUtils.QuoteSqlName(_identCol.Attribute.Name);
 | 
				
			||||||
 | 
								var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol.CsType, 0) as OracleParameter;
 | 
				
			||||||
 | 
								identParam.Direction = ParameterDirection.Output;
 | 
				
			||||||
 | 
								await _orm.Ado.ExecuteNonQueryAsync(CommandType.Text, $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}", _params.Concat(new[] { identParam }).ToArray());
 | 
				
			||||||
 | 
								return long.TryParse(string.Concat(identParam.Value), out var trylng) ? trylng : 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public override List<T1> ExecuteInserted() {
 | 
							public override List<T1> ExecuteInserted() {
 | 
				
			||||||
 | 
								throw new NotImplementedException();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var sql = this.ToSql();
 | 
								var sql = this.ToSql();
 | 
				
			||||||
			if (string.IsNullOrEmpty(sql)) return new List<T1>();
 | 
								if (string.IsNullOrEmpty(sql)) return new List<T1>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var sb = new StringBuilder();
 | 
								var sb = new StringBuilder();
 | 
				
			||||||
			sb.Append(sql).Append(" RETURNING ");
 | 
								sb.Append(@"declare
 | 
				
			||||||
 | 
					type v_tp_rec is record(");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var colidx = 0;
 | 
								var colidx = 0;
 | 
				
			||||||
			foreach (var col in _table.Columns.Values) {
 | 
								foreach (var col in _table.Columns.Values) {
 | 
				
			||||||
				if (colidx > 0) sb.Append(", ");
 | 
									if (colidx > 0) sb.Append(", ");
 | 
				
			||||||
				sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
 | 
									sb.Append(_commonUtils.QuoteSqlName(col.CsName)).Append(" ").Append(_commonUtils.QuoteSqlName(_table.DbName)).Append(".").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append("%type");
 | 
				
			||||||
				++colidx;
 | 
									++colidx;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								sb.Append(@");
 | 
				
			||||||
 | 
					type v_tp_tab is table of v_tp_rec;
 | 
				
			||||||
 | 
					v_tab v_tp_tab;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								sb.Append(sql).Append(" RETURNING ");
 | 
				
			||||||
 | 
								colidx = 0;
 | 
				
			||||||
 | 
								foreach (var col in _table.Columns.Values) {
 | 
				
			||||||
 | 
									if (colidx > 0) sb.Append(", ");
 | 
				
			||||||
 | 
									sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name)));
 | 
				
			||||||
 | 
									++colidx;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								sb.Append(@"bulk collect into v_tab;
 | 
				
			||||||
 | 
					for i in 1..v_tab.count loop
 | 
				
			||||||
 | 
						dbms_output.put_line(");
 | 
				
			||||||
 | 
								//v_tab(i).empno||'-'||v_tab(i).ename
 | 
				
			||||||
 | 
								colidx = 0;
 | 
				
			||||||
 | 
								foreach (var col in _table.Columns.Values) {
 | 
				
			||||||
 | 
									if (colidx > 0) sb.Append("||'-'||");
 | 
				
			||||||
 | 
									sb.Append("v_tab(i).").Append(_commonUtils.QuoteSqlName(col.CsName));
 | 
				
			||||||
 | 
									++colidx;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								sb.Append(@");
 | 
				
			||||||
 | 
					end loop;
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
			return _orm.Ado.Query<T1>(CommandType.Text, sb.ToString(), _params);
 | 
								return _orm.Ado.Query<T1>(CommandType.Text, sb.ToString(), _params);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		async public override Task<List<T1>> ExecuteInsertedAsync() {
 | 
							public override Task<List<T1>> ExecuteInsertedAsync() {
 | 
				
			||||||
			var sql = this.ToSql();
 | 
								throw new NotImplementedException();
 | 
				
			||||||
			if (string.IsNullOrEmpty(sql)) return new List<T1>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			var sb = new StringBuilder();
 | 
					 | 
				
			||||||
			sb.Append(sql).Append(" RETURNING ");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			var colidx = 0;
 | 
					 | 
				
			||||||
			foreach (var col in _table.Columns.Values) {
 | 
					 | 
				
			||||||
				if (colidx > 0) sb.Append(", ");
 | 
					 | 
				
			||||||
				sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
 | 
					 | 
				
			||||||
				++colidx;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return await _orm.Ado.QueryAsync<T1>(CommandType.Text, sb.ToString(), _params);
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
using FreeSql.Internal;
 | 
					using FreeSql.Internal;
 | 
				
			||||||
using FreeSql.Internal.Model;
 | 
					using FreeSql.Internal.Model;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Data;
 | 
					using System.Data;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
@@ -15,34 +16,10 @@ namespace FreeSql.Oracle.Curd {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public override List<T1> ExecuteUpdated() {
 | 
							public override List<T1> ExecuteUpdated() {
 | 
				
			||||||
			var sql = this.ToSql();
 | 
								throw new NotImplementedException();
 | 
				
			||||||
			if (string.IsNullOrEmpty(sql)) return new List<T1>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			var sb = new StringBuilder();
 | 
					 | 
				
			||||||
			sb.Append(sql).Append(" RETURNING ");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			var colidx = 0;
 | 
					 | 
				
			||||||
			foreach (var col in _table.Columns.Values) {
 | 
					 | 
				
			||||||
				if (colidx > 0) sb.Append(", ");
 | 
					 | 
				
			||||||
				sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
 | 
					 | 
				
			||||||
				++colidx;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return _orm.Ado.Query<T1>(CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray());
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		async public override Task<List<T1>> ExecuteUpdatedAsync() {
 | 
							public override Task<List<T1>> ExecuteUpdatedAsync() {
 | 
				
			||||||
			var sql = this.ToSql();
 | 
								throw new NotImplementedException();
 | 
				
			||||||
			if (string.IsNullOrEmpty(sql)) return new List<T1>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			var sb = new StringBuilder();
 | 
					 | 
				
			||||||
			sb.Append(sql).Append(" RETURNING ");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			var colidx = 0;
 | 
					 | 
				
			||||||
			foreach (var col in _table.Columns.Values) {
 | 
					 | 
				
			||||||
				if (colidx > 0) sb.Append(", ");
 | 
					 | 
				
			||||||
				sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
 | 
					 | 
				
			||||||
				++colidx;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return await _orm.Ado.QueryAsync<T1>(CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray());
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) {
 | 
							protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,8 +14,13 @@ namespace FreeSql.Oracle {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		internal Action availableHandler;
 | 
							internal Action availableHandler;
 | 
				
			||||||
		internal Action unavailableHandler;
 | 
							internal Action unavailableHandler;
 | 
				
			||||||
 | 
							internal string UserId { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public OracleConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) {
 | 
							public OracleConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null) {
 | 
				
			||||||
 | 
								var userIdMatch = Regex.Match(connectionString, @"User\s+Id\s*=\s*([^;]+)", RegexOptions.IgnoreCase);
 | 
				
			||||||
 | 
								if (userIdMatch.Success == false) throw new Exception(@"从 ConnectionString 中无法匹配 User\s+Id\s+=([^;]+)");
 | 
				
			||||||
 | 
								this.UserId = userIdMatch.Groups[1].Value.Trim().ToUpper();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var policy = new OracleConnectionPoolPolicy {
 | 
								var policy = new OracleConnectionPoolPolicy {
 | 
				
			||||||
				_pool = this,
 | 
									_pool = this,
 | 
				
			||||||
				Name = name
 | 
									Name = name
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -45,12 +45,12 @@ namespace FreeSql.Oracle {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				{ typeof(TimeSpan).FullName,  (OracleDbType.IntervalDS, "interval day to second","interval day(2) to second(6) NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName,  (OracleDbType.IntervalDS, "interval day to second", "interval day(2) to second(6) NULL",false, true, null) },
 | 
									{ typeof(TimeSpan).FullName,  (OracleDbType.IntervalDS, "interval day to second","interval day(2) to second(6) NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName,  (OracleDbType.IntervalDS, "interval day to second", "interval day(2) to second(6) NULL",false, true, null) },
 | 
				
			||||||
				{ typeof(DateTime).FullName,  (OracleDbType.TimeStamp, "timestamp", "timestamp(6) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName,  (OracleDbType.TimeStamp, "timestamp", "timestamp(6) NULL", false, true, null) },
 | 
									{ typeof(DateTime).FullName,  (OracleDbType.TimeStamp, "timestamp", "timestamp(6) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName,  (OracleDbType.TimeStamp, "timestamp", "timestamp(6) NULL", false, true, null) },
 | 
				
			||||||
				{ typeof(DateTimeOffset).FullName,  (OracleDbType.TimeStampLTZ, "timestamp with local time zone", "timestamp(6) with local time zone NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName,  (OracleDbType.TimeStamp, "timestamp with local time zone", "timestamp(6) with local time zone NULL", false, true, null) },
 | 
									{ typeof(DateTimeOffset).FullName,  (OracleDbType.TimeStampLTZ, "timestamp with local time zone", "timestamp(6) with local time zone NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTimeOffset?).FullName,  (OracleDbType.TimeStampLTZ, "timestamp with local time zone", "timestamp(6) with local time zone NULL", false, true, null) },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				{ typeof(byte[]).FullName,  (OracleDbType.Blob, "blog", "blog(4000) NULL", false, null, new byte[0]) },
 | 
									{ typeof(byte[]).FullName,  (OracleDbType.Blob, "blog", "blog(4000) NULL", false, null, new byte[0]) },
 | 
				
			||||||
				{ typeof(string).FullName,  (OracleDbType.NVarchar2, "nvarchar2", "nvarchar2(255) NULL", false, null, "") },
 | 
									{ typeof(string).FullName,  (OracleDbType.NVarchar2, "nvarchar2", "nvarchar2(255) NULL", false, null, "") },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				{ typeof(Guid).FullName,  (OracleDbType.Char, "char", "char(36 BYTE)", false, false, Guid.Empty) },{ typeof(Guid?).FullName,  (OracleDbType.Char, "char", "char(36 BYTE) NULL", false, true, null) },
 | 
									{ typeof(Guid).FullName,  (OracleDbType.Char, "char", "char(36 BYTE) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName,  (OracleDbType.Char, "char", "char(36 BYTE) NULL", false, true, null) },
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) {
 | 
							public (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type) {
 | 
				
			||||||
@@ -75,77 +75,60 @@ namespace FreeSql.Oracle {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		public string GetComparisonDDLStatements<TEntity>() => this.GetComparisonDDLStatements(typeof(TEntity));
 | 
							public string GetComparisonDDLStatements<TEntity>() => this.GetComparisonDDLStatements(typeof(TEntity));
 | 
				
			||||||
		public string GetComparisonDDLStatements(params Type[] entityTypes) {
 | 
							public string GetComparisonDDLStatements(params Type[] entityTypes) {
 | 
				
			||||||
			var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5));
 | 
								var userId = (_orm.Ado.MasterPool as OracleConnectionPool).UserId;
 | 
				
			||||||
			var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列
 | 
								var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var database = conn.Value.Database;
 | 
					 | 
				
			||||||
			Func<string, string, object> ExecuteScalar = (db, sql) => {
 | 
					 | 
				
			||||||
				if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(db);
 | 
					 | 
				
			||||||
				try {
 | 
					 | 
				
			||||||
					using (var cmd = conn.Value.CreateCommand()) {
 | 
					 | 
				
			||||||
						cmd.CommandText = sql;
 | 
					 | 
				
			||||||
						cmd.CommandType = CommandType.Text;
 | 
					 | 
				
			||||||
						return cmd.ExecuteScalar();
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				} finally {
 | 
					 | 
				
			||||||
					if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(database);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			};
 | 
					 | 
				
			||||||
			var sb = new StringBuilder();
 | 
								var sb = new StringBuilder();
 | 
				
			||||||
			try {
 | 
								var sbDeclare = new StringBuilder();
 | 
				
			||||||
				foreach (var entityType in entityTypes) {
 | 
								foreach (var entityType in entityTypes) {
 | 
				
			||||||
					if (sb.Length > 0) sb.Append("\r\n");
 | 
									if (sb.Length > 0) sb.Append("\r\n");
 | 
				
			||||||
					var tb = _commonUtils.GetTableByEntity(entityType);
 | 
									var tb = _commonUtils.GetTableByEntity(entityType);
 | 
				
			||||||
					var tbname = tb.DbName.Split(new[] { '.' }, 2);
 | 
									var tbname = tb.DbName.Split(new[] { '.' }, 2);
 | 
				
			||||||
					if (tbname?.Length == 1) tbname = new[] { database, tbname[0] };
 | 
									if (tbname?.Length == 1) tbname = new[] { userId, tbname[0] };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名
 | 
									var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名
 | 
				
			||||||
					if (tboldname?.Length == 1) tboldname = new[] { database, tboldname[0] };
 | 
									if (tboldname?.Length == 1) tboldname = new[] { userId, tboldname[0] };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if (string.Compare(tbname[0], database, true) != 0 && ExecuteScalar(database, " select 1 from sys.dba_users where username={0}".FormatOracleSQL(tbname[0])) == null) //创建数据库
 | 
									if (string.Compare(tbname[0], userId) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, " select 1 from sys.dba_users where username={0}".FormatOracleSQL(tbname[0])) == null) //创建数据库
 | 
				
			||||||
						throw new NotImplementedException($"Oracle CodeFirst 不支持代码创建 tablespace 与 schemas {tbname[0]}");
 | 
										throw new NotImplementedException($"Oracle CodeFirst 不支持代码创建 tablespace 与 schemas {tbname[0]}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					var sbalter = new StringBuilder();
 | 
									var sbalter = new StringBuilder();
 | 
				
			||||||
					var istmpatler = false; //创建临时表,导入数据,删除旧表,修改
 | 
									var istmpatler = false; //创建临时表,导入数据,删除旧表,修改
 | 
				
			||||||
					if (ExecuteScalar(tbname[0], " select 1 from all_tab_comments where owner={0} and table_name={1}".FormatOracleSQL(tbname)) == null) { //表不存在
 | 
									if (_orm.Ado.ExecuteScalar(CommandType.Text, " select 1 from all_tab_comments where owner={0} and table_name={1}".FormatOracleSQL(tbname)) == null) { //表不存在
 | 
				
			||||||
						if (tboldname != null) {
 | 
										if (tboldname != null) {
 | 
				
			||||||
							if (ExecuteScalar(tboldname[0], " select 1 from all_tab_comments where owner={0} and table_name={1}".FormatOracleSQL(tboldname)) == null)
 | 
											if (_orm.Ado.ExecuteScalar(CommandType.Text, " select 1 from all_tab_comments where owner={0} and table_name={1}".FormatOracleSQL(tboldname)) == null)
 | 
				
			||||||
								//模式或表不存在
 | 
												//模式或表不存在
 | 
				
			||||||
								tboldname = null;
 | 
												tboldname = null;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										if (tboldname == null) {
 | 
				
			||||||
 | 
											//创建表
 | 
				
			||||||
 | 
											sb.Append("execute immediate 'CREATE TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" (");
 | 
				
			||||||
 | 
											foreach (var tbcol in tb.Columns.Values) {
 | 
				
			||||||
 | 
												sb.Append(" \r\n  ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(",");
 | 
				
			||||||
 | 
												if (tbcol.Attribute.IsIdentity) seqcols.Add((tbcol, tbname, true));
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						if (tboldname == null) {
 | 
											if (tb.Primarys.Any() == false)
 | 
				
			||||||
							//创建表
 | 
												sb.Remove(sb.Length - 1, 1);
 | 
				
			||||||
							sb.Append("CREATE TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" (");
 | 
					 | 
				
			||||||
							foreach (var tbcol in tb.Columns.Values) {
 | 
					 | 
				
			||||||
								sb.Append(" \r\n  ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(",");
 | 
					 | 
				
			||||||
								if (tbcol.Attribute.IsIdentity) seqcols.Add((tbcol, tbname, true));
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							if (tb.Primarys.Any() == false)
 | 
					 | 
				
			||||||
								sb.Remove(sb.Length - 1, 1);
 | 
					 | 
				
			||||||
							else {
 | 
					 | 
				
			||||||
								sb.Append(" \r\n  CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pk PRIMARY KEY (");
 | 
					 | 
				
			||||||
								foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
 | 
					 | 
				
			||||||
								sb.Remove(sb.Length - 2, 2).Append(")");
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							sb.Append("\r\n) LOGGING \r\nNOCOMPRESS \r\nNOCACHE\r\n;\r\n");
 | 
					 | 
				
			||||||
							continue;
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
						//如果新表,旧表在一个模式下,直接修改表名
 | 
					 | 
				
			||||||
						if (string.Compare(tbname[0], tboldname[0], true) == 0)
 | 
					 | 
				
			||||||
							sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(";\r\n");
 | 
					 | 
				
			||||||
						else {
 | 
											else {
 | 
				
			||||||
							//如果新表,旧表不在一起,创建新表,导入数据,删除旧表
 | 
												sb.Append(" \r\n  CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pk1 PRIMARY KEY (");
 | 
				
			||||||
							istmpatler = true;
 | 
												foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
 | 
				
			||||||
 | 
												sb.Remove(sb.Length - 2, 2).Append(")");
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					} else
 | 
											sb.Append("\r\n) \r\nLOGGING \r\nNOCOMPRESS \r\nNOCACHE\r\n';\r\n");
 | 
				
			||||||
						tboldname = null; //如果新表已经存在,不走改表名逻辑
 | 
											continue;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										//如果新表,旧表在一个模式下,直接修改表名
 | 
				
			||||||
 | 
										if (string.Compare(tbname[0], tboldname[0], true) == 0)
 | 
				
			||||||
 | 
											sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append("';\r\n");
 | 
				
			||||||
 | 
										else {
 | 
				
			||||||
 | 
											//如果新表,旧表不在一起,创建新表,导入数据,删除旧表
 | 
				
			||||||
 | 
											istmpatler = true;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									} else
 | 
				
			||||||
 | 
										tboldname = null; //如果新表已经存在,不走改表名逻辑
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					//对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段
 | 
									//对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段
 | 
				
			||||||
					var addcols = new Dictionary<string, ColumnInfo>(StringComparer.CurrentCultureIgnoreCase);
 | 
									var sql = $@"
 | 
				
			||||||
					foreach (var tbcol in tb.Columns) addcols.Add(tbcol.Value.Attribute.Name, tbcol.Value);
 | 
					 | 
				
			||||||
					var surplus = new Dictionary<string, bool>(StringComparer.CurrentCultureIgnoreCase);
 | 
					 | 
				
			||||||
					var dbcols = new List<DbColumnInfo>();
 | 
					 | 
				
			||||||
					var sql = $@"
 | 
					 | 
				
			||||||
select 
 | 
					select 
 | 
				
			||||||
column_name,
 | 
					column_name,
 | 
				
			||||||
data_type,
 | 
					data_type,
 | 
				
			||||||
@@ -154,127 +137,136 @@ data_precision,
 | 
				
			|||||||
data_scale,
 | 
					data_scale,
 | 
				
			||||||
char_used,
 | 
					char_used,
 | 
				
			||||||
case when nullable = 'Y' then 1 else 0 end,
 | 
					case when nullable = 'Y' then 1 else 0 end,
 | 
				
			||||||
nvl((select 1 from user_sequences where sequence_name='{Utils.GetCsName(string.Join(".", tboldname ?? tbname))}_seq_'||all_tab_columns.column_name), 0)
 | 
					nvl((select 1 from user_sequences where sequence_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||all_tab_columns.column_name), 0)
 | 
				
			||||||
from all_tab_columns
 | 
					from all_tab_columns
 | 
				
			||||||
where owner={{0}} and table_name={{1}}".FormatOracleSQL(tboldname ?? tbname);
 | 
					where owner={{0}} and table_name={{1}}".FormatOracleSQL(tboldname ?? tbname);
 | 
				
			||||||
					var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
 | 
									var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
 | 
				
			||||||
					var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => {
 | 
									var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => {
 | 
				
			||||||
						var sqlType = string.Concat(a[1]);
 | 
										var sqlType = string.Concat(a[1]);
 | 
				
			||||||
						var data_length = long.Parse(string.Concat(a[2]));
 | 
										var data_length = long.Parse(string.Concat(a[2]));
 | 
				
			||||||
						long.TryParse(string.Concat(a[3]), out var data_precision);
 | 
										long.TryParse(string.Concat(a[3]), out var data_precision);
 | 
				
			||||||
						long.TryParse(string.Concat(a[4]), out var data_scale);
 | 
										long.TryParse(string.Concat(a[4]), out var data_scale);
 | 
				
			||||||
						var char_used = string.Concat(a[5]);
 | 
										var char_used = string.Concat(a[5]);
 | 
				
			||||||
						if (Regex.IsMatch(sqlType, @"INTERVAL DAY\(\d+\) TO SECOND\(\d+\)", RegexOptions.IgnoreCase)) {
 | 
										switch(sqlType.ToUpper()) {
 | 
				
			||||||
						} else if (Regex.IsMatch(sqlType, @"INTERVAL YEAR\(\d+\) TO MONTH", RegexOptions.IgnoreCase)) {
 | 
											case "CHAR": data_length /= char_used.ToLower() == "c" ? 4 : 2; break;
 | 
				
			||||||
						} else if (sqlType.StartsWith("TIMESTAMP", StringComparison.CurrentCultureIgnoreCase)) {
 | 
										}
 | 
				
			||||||
						} else if (char_used.ToLower() == "c") {
 | 
										if (Regex.IsMatch(sqlType, @"INTERVAL DAY\(\d+\) TO SECOND\(\d+\)", RegexOptions.IgnoreCase)) {
 | 
				
			||||||
							sqlType += $"({data_length} CHAR)";
 | 
										} else if (Regex.IsMatch(sqlType, @"INTERVAL YEAR\(\d+\) TO MONTH", RegexOptions.IgnoreCase)) {
 | 
				
			||||||
						} else if (char_used.ToLower() == "b") {
 | 
										} else if (sqlType.StartsWith("TIMESTAMP", StringComparison.CurrentCultureIgnoreCase)) {
 | 
				
			||||||
							sqlType += $"({data_length} BYTE)";
 | 
										} else if (char_used.ToLower() == "c")
 | 
				
			||||||
						} else if (sqlType.ToLower() == "float") {
 | 
											sqlType += sqlType.StartsWith("N") ? $"({data_length / 2})" : $"({data_length / 4} CHAR)";
 | 
				
			||||||
							sqlType += $"({data_precision})";
 | 
										else if (char_used.ToLower() == "b")
 | 
				
			||||||
						} else if (data_precision > 0 && data_scale > 0) {
 | 
											sqlType += $"({data_length} BYTE)";
 | 
				
			||||||
							sqlType += $"({data_precision},{data_scale})";
 | 
										else if (sqlType.ToLower() == "float")
 | 
				
			||||||
						} else {
 | 
											sqlType += $"({data_precision})";
 | 
				
			||||||
							sqlType += $"({data_length})";
 | 
										else if (data_precision > 0 && data_scale > 0)
 | 
				
			||||||
						}
 | 
											sqlType += $"({data_precision},{data_scale})";
 | 
				
			||||||
						return new {
 | 
										else if (data_precision > 0)
 | 
				
			||||||
							column = string.Concat(a[0]),
 | 
											sqlType += $"({data_precision})";
 | 
				
			||||||
							sqlType,
 | 
										else
 | 
				
			||||||
							is_nullable = string.Concat(a[6]) == "1",
 | 
											sqlType += $"({data_length})";
 | 
				
			||||||
							is_identity = string.Concat(a[7]) == "1"
 | 
										return new {
 | 
				
			||||||
						};
 | 
											column = string.Concat(a[0]),
 | 
				
			||||||
					}, StringComparer.CurrentCultureIgnoreCase);
 | 
											sqlType,
 | 
				
			||||||
 | 
											is_nullable = string.Concat(a[6]) == "1",
 | 
				
			||||||
 | 
											is_identity = string.Concat(a[7]) == "1"
 | 
				
			||||||
 | 
										};
 | 
				
			||||||
 | 
									}, StringComparer.CurrentCultureIgnoreCase);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if (istmpatler == false) {
 | 
									if (istmpatler == false) {
 | 
				
			||||||
						foreach (var tbcol in tb.Columns.Values) {
 | 
					 | 
				
			||||||
							if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) ||
 | 
					 | 
				
			||||||
							string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) {
 | 
					 | 
				
			||||||
								if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false)
 | 
					 | 
				
			||||||
									sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY (").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.DbType).Append(");\r\n");
 | 
					 | 
				
			||||||
								if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) {
 | 
					 | 
				
			||||||
									if (tbcol.Attribute.IsNullable == false)
 | 
					 | 
				
			||||||
										sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(_commonUtils.FormatSql(" = {0}", tbcol.Attribute.DbDefautValue)).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" IS NULL;\r\n");
 | 
					 | 
				
			||||||
									sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable ? "" : "NOT").Append(" NULL;\r\n");
 | 
					 | 
				
			||||||
								}
 | 
					 | 
				
			||||||
								if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity)
 | 
					 | 
				
			||||||
									seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity));
 | 
					 | 
				
			||||||
								if (tbstructcol.column == tbcol.Attribute.OldName)
 | 
					 | 
				
			||||||
									//修改列名
 | 
					 | 
				
			||||||
									sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.OldName)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(";\r\n");
 | 
					 | 
				
			||||||
								continue;
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							//添加列
 | 
					 | 
				
			||||||
							sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType.Split(' ').First()).Append(";\r\n");
 | 
					 | 
				
			||||||
							sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(_commonUtils.FormatSql(" = {0};\r\n", tbcol.Attribute.DbDefautValue));
 | 
					 | 
				
			||||||
							if (tbcol.Attribute.IsNullable == false) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" NOT NULL;\r\n");
 | 
					 | 
				
			||||||
							if (tbcol.Attribute.IsIdentity) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity));
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					if (istmpatler == false) {
 | 
					 | 
				
			||||||
						sb.Append(sbalter);
 | 
					 | 
				
			||||||
						continue;
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					//创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名
 | 
					 | 
				
			||||||
					var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}");
 | 
					 | 
				
			||||||
					var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}");
 | 
					 | 
				
			||||||
					//创建临时表
 | 
					 | 
				
			||||||
					sb.Append("CREATE TABLE ").Append(tmptablename).Append(" (");
 | 
					 | 
				
			||||||
					foreach (var tbcol in tb.Columns.Values) {
 | 
										foreach (var tbcol in tb.Columns.Values) {
 | 
				
			||||||
						sb.Append(" \r\n  ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(",");
 | 
											var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"NOT\s+NULL", "NULL");
 | 
				
			||||||
						if (tbcol.Attribute.IsIdentity) seqcols.Add((tbcol, tbname, true));
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					if (tb.Primarys.Any() == false)
 | 
					 | 
				
			||||||
						sb.Remove(sb.Length - 1, 1);
 | 
					 | 
				
			||||||
					else {
 | 
					 | 
				
			||||||
						sb.Append(" \r\n  CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pk PRIMARY KEY (");
 | 
					 | 
				
			||||||
						foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
 | 
					 | 
				
			||||||
						sb.Remove(sb.Length - 2, 2).Append(")");
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					sb.Append("\r\n) LOGGING \r\nNOCOMPRESS \r\nNOCACHE\r\n;\r\n");
 | 
					 | 
				
			||||||
					sb.Append("INSERT INTO ").Append(tmptablename).Append(" (");
 | 
					 | 
				
			||||||
					foreach (var tbcol in tb.Columns.Values)
 | 
					 | 
				
			||||||
						sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
 | 
					 | 
				
			||||||
					sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT ");
 | 
					 | 
				
			||||||
					foreach (var tbcol in tb.Columns.Values) {
 | 
					 | 
				
			||||||
						var insertvalue = "NULL";
 | 
					 | 
				
			||||||
						if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) ||
 | 
											if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) ||
 | 
				
			||||||
							string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) {
 | 
											string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) {
 | 
				
			||||||
							insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column);
 | 
												if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false)
 | 
				
			||||||
							if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) {
 | 
													istmpatler = true;
 | 
				
			||||||
								//insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})";
 | 
													//sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY (").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n");
 | 
				
			||||||
 | 
												if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) {
 | 
				
			||||||
 | 
													if (tbcol.Attribute.IsNullable == false)
 | 
				
			||||||
 | 
														sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(_commonUtils.FormatSql(" = {0}", tbcol.Attribute.DbDefautValue).Replace("'", "''")).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL';\r\n");
 | 
				
			||||||
 | 
													sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable ? "" : "NOT").Append(" NULL';\r\n");
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
							if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable)
 | 
												if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity)
 | 
				
			||||||
								insertvalue = $"nvl({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''")})";
 | 
													seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity));
 | 
				
			||||||
						} else if (tbcol.Attribute.IsNullable == false)
 | 
												if (tbstructcol.column == tbcol.Attribute.OldName)
 | 
				
			||||||
							insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''");
 | 
													//修改列名
 | 
				
			||||||
						sb.Append(insertvalue).Append(", ");
 | 
													sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.OldName)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append("';\r\n");
 | 
				
			||||||
					}
 | 
												continue;
 | 
				
			||||||
					sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n");
 | 
											}
 | 
				
			||||||
					sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n");
 | 
											//添加列
 | 
				
			||||||
					sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(";\r\n");
 | 
											sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD (").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n");
 | 
				
			||||||
				}
 | 
											if (tbcol.Attribute.IsNullable == false) {
 | 
				
			||||||
				foreach (var seqcol in seqcols) {
 | 
												sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(_commonUtils.FormatSql(" = {0}';\r\n", tbcol.Attribute.DbDefautValue).Replace("'", "''"));
 | 
				
			||||||
					var tbname = seqcol.Item2;
 | 
												sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" NOT NULL';\r\n");
 | 
				
			||||||
					var seqname = Utils.GetCsName($"{tbname[0]}.{tbname[1]}_seq_{seqcol.Item1.Attribute.Name}");
 | 
											}
 | 
				
			||||||
					var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}");
 | 
											if (tbcol.Attribute.IsIdentity) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity));
 | 
				
			||||||
					var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name);
 | 
					 | 
				
			||||||
					sb.Append("DROP SEQUENCE ").Append(seqname).Append(";\r\n");
 | 
					 | 
				
			||||||
					if (seqcol.Item3) {
 | 
					 | 
				
			||||||
						var startWith = _orm.Ado.ExecuteScalar(CommandType.Text, $" select nvl({colname2},0) from {tbname2}");
 | 
					 | 
				
			||||||
						sb.Append("CREATE SEQUENCE ").Append(seqname).Append(" start with ").Append(startWith).Append(";\r\n");
 | 
					 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				return sb.Length == 0 ? null : sb.ToString();
 | 
									if (istmpatler == false) {
 | 
				
			||||||
			} finally {
 | 
										sb.Append(sbalter);
 | 
				
			||||||
				try {
 | 
										continue;
 | 
				
			||||||
					conn.Value.ChangeDatabase(database);
 | 
									}
 | 
				
			||||||
					_orm.Ado.MasterPool.Return(conn);
 | 
									var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, @"select constraint_name from user_constraints where owner={0} and table_name={1} and constraint_type='P'".FormatPostgreSQL(tbname))?.ToString();
 | 
				
			||||||
				} catch {
 | 
									if (string.IsNullOrEmpty(oldpk) == false)
 | 
				
			||||||
					_orm.Ado.MasterPool.Return(conn, true);
 | 
										sb.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(oldpk).Append("';\r\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									//创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名
 | 
				
			||||||
 | 
									var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}");
 | 
				
			||||||
 | 
									var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}");
 | 
				
			||||||
 | 
									//创建临时表
 | 
				
			||||||
 | 
									sb.Append("execute immediate 'CREATE TABLE ").Append(tmptablename).Append(" (");
 | 
				
			||||||
 | 
									foreach (var tbcol in tb.Columns.Values) {
 | 
				
			||||||
 | 
										sb.Append(" \r\n  ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(",");
 | 
				
			||||||
 | 
										if (tbcol.Attribute.IsIdentity) seqcols.Add((tbcol, tbname, true));
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if (tb.Primarys.Any() == false)
 | 
				
			||||||
 | 
										sb.Remove(sb.Length - 1, 1);
 | 
				
			||||||
 | 
									else {
 | 
				
			||||||
 | 
										sb.Append(" \r\n  CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pk2 PRIMARY KEY (");
 | 
				
			||||||
 | 
										foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
 | 
				
			||||||
 | 
										sb.Remove(sb.Length - 2, 2).Append(")");
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									sb.Append("\r\n) LOGGING \r\nNOCOMPRESS \r\nNOCACHE\r\n';\r\n");
 | 
				
			||||||
 | 
									sb.Append("execute immediate 'INSERT INTO ").Append(tmptablename).Append(" (");
 | 
				
			||||||
 | 
									foreach (var tbcol in tb.Columns.Values)
 | 
				
			||||||
 | 
										sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
 | 
				
			||||||
 | 
									sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT ");
 | 
				
			||||||
 | 
									foreach (var tbcol in tb.Columns.Values) {
 | 
				
			||||||
 | 
										var insertvalue = "NULL";
 | 
				
			||||||
 | 
										if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) ||
 | 
				
			||||||
 | 
											string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) {
 | 
				
			||||||
 | 
											insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column);
 | 
				
			||||||
 | 
											if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) {
 | 
				
			||||||
 | 
												var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"(NOT\s+)?NULL", "");
 | 
				
			||||||
 | 
												insertvalue = $"cast({insertvalue} as {dbtypeNoneNotNull})";
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable)
 | 
				
			||||||
 | 
												insertvalue = $"nvl({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)})";
 | 
				
			||||||
 | 
										} else if (tbcol.Attribute.IsNullable == false)
 | 
				
			||||||
 | 
											insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue);
 | 
				
			||||||
 | 
										sb.Append(insertvalue.Replace("'", "''")).Append(", ");
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append("';\r\n");
 | 
				
			||||||
 | 
									sb.Append("execute immediate 'DROP TABLE ").Append(tablename).Append("';\r\n");
 | 
				
			||||||
 | 
									sb.Append("execute immediate 'ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append("';\r\n");
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								foreach (var seqcol in seqcols) {
 | 
				
			||||||
 | 
									var tbname = seqcol.Item2;
 | 
				
			||||||
 | 
									var seqname = Utils.GetCsName($"{tbname[1]}_seq_{seqcol.Item1.Attribute.Name}");
 | 
				
			||||||
 | 
									var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}");
 | 
				
			||||||
 | 
									var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name);
 | 
				
			||||||
 | 
									sbDeclare.Append("declare ").Append(seqname).Append("_exists NUMBER; \r\n");
 | 
				
			||||||
 | 
									sb.Append(seqname).Append("_exists := 0; \r\n")
 | 
				
			||||||
 | 
										.Append(" select count(1) into ").Append(seqname).Append("_exists from user_sequences where sequence_name={0}; \r\n".FormatOracleSQL(seqname))
 | 
				
			||||||
 | 
										.Append("if ").Append(seqname).Append("_exists > 0 then \r\n")
 | 
				
			||||||
 | 
										.Append("  execute immediate 'DROP SEQUENCE ").Append(_commonUtils.QuoteSqlName(seqname)).Append("';\r\n")
 | 
				
			||||||
 | 
										.Append("end if; \r\n");
 | 
				
			||||||
 | 
									if (seqcol.Item3) {
 | 
				
			||||||
 | 
										var startWith = _orm.Ado.ExecuteScalar(CommandType.Text, $" select nvl(max({colname2})+1,1) from {tbname2}");
 | 
				
			||||||
 | 
										sb.Append("execute immediate 'CREATE SEQUENCE ").Append(_commonUtils.QuoteSqlName(seqname)).Append(" start with ").Append(startWith).Append("';\r\n");
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								return sb.Length == 0 ? null : sb.Insert(0, "BEGIN \r\n").Insert(0, sbDeclare.ToString()).Append("END;").ToString();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ConcurrentDictionary<string, bool> dicSyced = new ConcurrentDictionary<string, bool>();
 | 
							ConcurrentDictionary<string, bool> dicSyced = new ConcurrentDictionary<string, bool>();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,7 @@ namespace FreeSql.Oracle {
 | 
				
			|||||||
		internal override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value) {
 | 
							internal override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value) {
 | 
				
			||||||
			if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}";
 | 
								if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}";
 | 
				
			||||||
			else if (_orm.CodeFirst.IsSyncStructureToLower) parameterName = parameterName.ToLower();
 | 
								else if (_orm.CodeFirst.IsSyncStructureToLower) parameterName = parameterName.ToLower();
 | 
				
			||||||
			var ret = new OracleParameter { ParameterName = $"@{parameterName}", Value = value };
 | 
								var ret = new OracleParameter { ParameterName = $":{parameterName}", Value = value };
 | 
				
			||||||
			var tp = _orm.CodeFirst.GetDbInfo(type)?.type;
 | 
								var tp = _orm.CodeFirst.GetDbInfo(type)?.type;
 | 
				
			||||||
			if (tp != null) {
 | 
								if (tp != null) {
 | 
				
			||||||
				ret.OracleDbType = (OracleDbType)tp.Value;
 | 
									ret.OracleDbType = (OracleDbType)tp.Value;
 | 
				
			||||||
@@ -26,8 +26,8 @@ namespace FreeSql.Oracle {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		internal override DbParameter[] GetDbParamtersByObject(string sql, object obj) =>
 | 
							internal override DbParameter[] GetDbParamtersByObject(string sql, object obj) =>
 | 
				
			||||||
			Utils.GetDbParamtersByObject<OracleParameter>(sql, obj, "@", (name, type, value) => {
 | 
								Utils.GetDbParamtersByObject<OracleParameter>(sql, obj, ":", (name, type, value) => {
 | 
				
			||||||
				var ret = new OracleParameter { ParameterName = $"@{name}", Value = value };
 | 
									var ret = new OracleParameter { ParameterName = $":{name}", Value = value };
 | 
				
			||||||
				var tp = _orm.CodeFirst.GetDbInfo(type)?.type;
 | 
									var tp = _orm.CodeFirst.GetDbInfo(type)?.type;
 | 
				
			||||||
				if (tp != null) {
 | 
									if (tp != null) {
 | 
				
			||||||
					ret.OracleDbType = (OracleDbType)tp.Value;
 | 
										ret.OracleDbType = (OracleDbType)tp.Value;
 | 
				
			||||||
@@ -37,7 +37,7 @@ namespace FreeSql.Oracle {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		internal override string FormatSql(string sql, params object[] args) => sql?.FormatOracleSQL(args);
 | 
							internal override string FormatSql(string sql, params object[] args) => sql?.FormatOracleSQL(args);
 | 
				
			||||||
		internal override string QuoteSqlName(string name) => $"\"{name.Trim('"').Replace(".", "\".\"")}\"";
 | 
							internal override string QuoteSqlName(string name) => $"\"{name.Trim('"').Replace(".", "\".\"")}\"";
 | 
				
			||||||
		internal override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}";
 | 
							internal override string QuoteParamterName(string name) => $":{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}";
 | 
				
			||||||
		internal override string IsNull(string sql, object value) => $"nvl({sql}, {value})";
 | 
							internal override string IsNull(string sql, object value) => $"nvl({sql}, {value})";
 | 
				
			||||||
		internal override string StringConcat(string left, string right, Type leftType, Type rightType) => $"{left} || {right}";
 | 
							internal override string StringConcat(string left, string right, Type leftType, Type rightType) => $"{left} || {right}";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -241,6 +241,14 @@ where ns.nspname = {0} and c.relname = {1}".FormatPostgreSQL(tboldname ?? tbname
 | 
				
			|||||||
					sb.Append(sbalter);
 | 
										sb.Append(sbalter);
 | 
				
			||||||
					continue;
 | 
										continue;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
									var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, @"select pg_constraint.conname as pk_name from pg_constraint
 | 
				
			||||||
 | 
					inner join pg_class on pg_constraint.conrelid = pg_class.oid
 | 
				
			||||||
 | 
					inner join pg_namespace on pg_namespace.oid = pg_class.relnamespace
 | 
				
			||||||
 | 
					where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contype='p'
 | 
				
			||||||
 | 
					".FormatPostgreSQL(tbname))?.ToString();
 | 
				
			||||||
 | 
									if (string.IsNullOrEmpty(oldpk) == false)
 | 
				
			||||||
 | 
										sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(oldpk).Append(";\r\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				//创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名
 | 
									//创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名
 | 
				
			||||||
				var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}");
 | 
									var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}");
 | 
				
			||||||
				var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}");
 | 
									var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}");
 | 
				
			||||||
@@ -270,9 +278,9 @@ where ns.nspname = {0} and c.relname = {1}".FormatPostgreSQL(tboldname ?? tbname
 | 
				
			|||||||
						if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false)
 | 
											if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false)
 | 
				
			||||||
							insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})";
 | 
												insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})";
 | 
				
			||||||
						if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable)
 | 
											if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable)
 | 
				
			||||||
							insertvalue = $"coalesce({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''")})";
 | 
												insertvalue = $"coalesce({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)})";
 | 
				
			||||||
					} else if (tbcol.Attribute.IsNullable == false)
 | 
										} else if (tbcol.Attribute.IsNullable == false)
 | 
				
			||||||
						insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''");
 | 
											insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue);
 | 
				
			||||||
					sb.Append(insertvalue).Append(", ");
 | 
										sb.Append(insertvalue).Append(", ");
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n");
 | 
									sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -239,9 +239,9 @@ use " + database, tboldname ?? tbname);
 | 
				
			|||||||
							if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false)
 | 
												if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false)
 | 
				
			||||||
								insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})";
 | 
													insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})";
 | 
				
			||||||
							if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable)
 | 
												if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable)
 | 
				
			||||||
								insertvalue = $"isnull({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''")})";
 | 
													insertvalue = $"isnull({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue)})";
 | 
				
			||||||
						} else if (tbcol.Attribute.IsNullable == false)
 | 
											} else if (tbcol.Attribute.IsNullable == false)
 | 
				
			||||||
							insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''");
 | 
												insertvalue = _commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue);
 | 
				
			||||||
						sb.Append(insertvalue).Append(", ");
 | 
											sb.Append(insertvalue).Append(", ");
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(" WITH (HOLDLOCK TABLOCKX)');\r\n");
 | 
										sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(" WITH (HOLDLOCK TABLOCKX)');\r\n");
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user