From 8d11993e6c9c3044e08631f56d3291ebb58b6b7a Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 18 Jul 2020 11:58:58 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E8=A1=A5=E5=85=85=20fsql.InsertOrUpdate=20?= =?UTF-8?q?IfExistsDoNothing=20=E6=95=B0=E6=8D=AE=E5=AD=98=E5=9C=A8?= =?UTF-8?q?=E6=97=B6=E4=B8=8D=E5=81=9A=E4=BB=BB=E4=BD=95=E4=BA=8B(?= =?UTF-8?q?=E4=B8=8D=E6=9B=B4=E6=96=B0)=20#330=20#316=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 - ...ySqlInsertOrUpdateIfExistsDoNothingTest.cs | 453 ++++++++++++++++++ ...DamengInsertOrUpdateIfExistsNothingTest.cs | 425 ++++++++++++++++ .../Dameng/Curd/DamengInsertOrUpdateTest.cs | 4 +- ...aseESInsertOrUpdateIfExistsDoNotingTest.cs | 266 ++++++++++ .../Curd/KingbaseESInsertOrUpdateTest.cs | 4 +- ...ySqlInsertOrUpdateIfExistsDoNothingTest.cs | 453 ++++++++++++++++++ ...acleInsertOrUpdateIfExistsDoNothingTest.cs | 425 ++++++++++++++++ .../Oracle/Curd/OracleInsertOrUpdateTest.cs | 4 +- ...reSQLInsertOrUpdateIfExistsDoNotingTest.cs | 266 ++++++++++ .../Curd/PostgreSQLInsertOrUpdateTest.cs | 4 +- ...rverInsertOrUpdateIfExistsDoNothingTest.cs | 422 ++++++++++++++++ .../Curd/SqlServerInsertOrUpdateTest.cs | 4 +- ...DamengInsertOrUpdateIfExistsNothingTest.cs | 425 ++++++++++++++++ .../Dameng/Curd/DamengInsertOrUpdateTest.cs | 4 +- ...ySqlInsertOrUpdateIfExistsDoNothingTest.cs | 453 ++++++++++++++++++ ...acleInsertOrUpdateIfExistsDoNothingTest.cs | 425 ++++++++++++++++ .../Oracle/Curd/OracleInsertOrUpdateTest.cs | 4 +- ...reSQLInsertOrUpdateIfExistsDoNotingTest.cs | 266 ++++++++++ .../Curd/PostgreSQLInsertOrUpdateTest.cs | 4 +- ...TongInsertOrUpdateIfExistsDoNothingTest.cs | 293 +++++++++++ .../Curd/ShenTongInsertOrUpdateTest.cs | 6 +- ...rverInsertOrUpdateIfExistsDoNothingTest.cs | 424 ++++++++++++++++ .../Curd/SqlServerInsertOrUpdateTest.cs | 4 +- ...liteInsertOrUpdateIfExistsDoNothingTest.cs | 453 ++++++++++++++++++ .../Sqlite/Curd/SqliteInsertOrUpdateTest.cs | 4 +- FreeSql/FreeSql.xml | 24 +- FreeSql/Interface/Curd/IInsertOrUpdate.cs | 7 + FreeSql/Interface/IFreeSql.cs | 17 +- .../CommonProvider/InsertOrUpdateProvider.cs | 7 + .../Internal/CommonProvider/InsertProvider.cs | 4 +- .../Curd/DamengInsertOrUpdate.cs | 2 +- .../Curd/MySqlInsertOrUpdate.cs | 18 +- .../Dameng/Curd/OdbcDamengInsertOrUpdate.cs | 2 +- .../Curd/OdbcKingbaseESInsertOrUpdate.cs | 2 +- .../MySql/Curd/OdbcMySqlInsertOrUpdate.cs | 19 +- .../Oracle/Curd/OdbcOracleInsertOrUpdate.cs | 2 +- .../Curd/OdbcPostgreSQLInsertOrUpdate.cs | 2 +- .../Curd/OdbcSqlServerInsertOrUpdate.cs | 2 +- .../Curd/OracleInsertOrUpdate.cs | 2 +- .../Curd/PostgreSQLInsertOrUpdate.cs | 2 +- .../Curd/ShenTongInsertOrUpdate.cs | 2 +- .../Curd/SqlServerInsertOrUpdate.cs | 2 +- .../Curd/SqliteInsertOrUpdate.cs | 31 +- 44 files changed, 5585 insertions(+), 73 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateIfExistsNothingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESInsertOrUpdateIfExistsDoNotingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateIfExistsDoNothingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateIfExistsDoNotingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateIfExistsDoNothingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateIfExistsNothingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateIfExistsDoNothingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateIfExistsDoNotingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertOrUpdateIfExistsDoNothingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateIfExistsDoNothingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateIfExistsDoNothingTest.cs diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 4854f49c..132d875e 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,13 +125,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -486,14 +479,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs new file mode 100644 index 00000000..078e59e2 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs @@ -0,0 +1,453 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MySqlConnector +{ + public class MySqlInsertOrUpdateIfExistsDoNothingTest + { + + IFreeSql fsql => g.mysql; + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '011' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '03' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '04' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '011' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '03' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '04' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('01'), ('02'), ('03'), ('04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('001'), ('002'), ('003'), ('004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '100001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '100002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '100003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '100004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1) + +; + +INSERT INTO `tbioudb022`(`name`) VALUES('00001'), ('00002'), ('00003'), ('00004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '011' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 2, '02', '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1) +UNION ALL + SELECT 2, '02', '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1) +UNION ALL + SELECT 3, '03', '03' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 3 AND a.`id2` = '03') + limit 0,1) +UNION ALL + SELECT 4, '04', '04' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 4 AND a.`id2` = '04') + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1) +UNION ALL + SELECT 2, '02', '002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1) +UNION ALL + SELECT 3, '03', '003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 3 AND a.`id2` = '03') + limit 0,1) +UNION ALL + SELECT 4, '04', '004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 4 AND a.`id2` = '04') + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '01', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '011', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 2, '02', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '01', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '02', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '03', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '04', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '001', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '002', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '003', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '004', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateIfExistsNothingTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateIfExistsNothingTest.cs new file mode 100644 index 00000000..1f65a142 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateIfExistsNothingTest.cs @@ -0,0 +1,425 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.Dameng +{ + public class DamengInsertOrUpdateIfExistsNothingTest + { + IFreeSql fsql => g.dameng; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN01"" t1 +USING (SELECT 1 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN01"" t1 +USING (SELECT 1 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN01"" t1 +USING (SELECT 2 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn01 { id = 1 }, new tbioudn01 { id = 2 }, new tbioudn01 { id = 3 }, new tbioudn01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN01"" t1 +USING (SELECT 1 as ID FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn01 { id = 1 }, new tbioudn01 { id = 2 }, new tbioudn01 { id = 3 }, new tbioudn01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN01"" t1 +USING (SELECT 1 as ID FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + } + class tbioudn01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN02"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN02"" t1 +USING (SELECT 1 as ID, '011' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN02"" t1 +USING (SELECT 2 as ID, '02' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn02 { id = 1, name = "01" }, new tbioudn02 { id = 2, name = "02" }, new tbioudn02 { id = 3, name = "03" }, new tbioudn02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN02"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn02 { id = 1, name = "001" }, new tbioudn02 { id = 2, name = "002" }, new tbioudn02 { id = 3, name = "003" }, new tbioudn02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN02"" t1 +USING (SELECT 1 as ID, '001' as NAME FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudn02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN022"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN022"" t1 +USING (SELECT 1 as ID, '011' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN022"" t1 +USING (SELECT 2 as ID, '02' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn022 { id = 1, name = "01" }, new tbioudn022 { id = 2, name = "02" }, new tbioudn022 { id = 3, name = "03" }, new tbioudn022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN022"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn022 { id = 1, name = "001" }, new tbioudn022 { id = 2, name = "002" }, new tbioudn022 { id = 3, name = "003" }, new tbioudn022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN022"" t1 +USING (SELECT 1 as ID, '001' as NAME FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDN022""(""NAME"") VALUES('01')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDN022""(""NAME"") VALUES('011')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDN022""(""NAME"") VALUES('02')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn022 { name = "01" }, new tbioudn022 { name = "02" }, new tbioudn022 { name = "03" }, new tbioudn022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOUDN022""(""NAME"") VALUES('01') +INTO ""TBIOUDN022""(""NAME"") VALUES('02') +INTO ""TBIOUDN022""(""NAME"") VALUES('03') +INTO ""TBIOUDN022""(""NAME"") VALUES('04') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn022 { name = "001" }, new tbioudn022 { name = "002" }, new tbioudn022 { name = "003" }, new tbioudn022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOUDN022""(""NAME"") VALUES('001') +INTO ""TBIOUDN022""(""NAME"") VALUES('002') +INTO ""TBIOUDN022""(""NAME"") VALUES('003') +INTO ""TBIOUDN022""(""NAME"") VALUES('004') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn022 { id = 1, name = "100001" }, new tbioudn022 { name = "00001" }, new tbioudn022 { id = 2, name = "100002" }, new tbioudn022 { name = "00002" }, new tbioudn022 { id = 3, name = "100003" }, new tbioudn022 { name = "00003" }, new tbioudn022 { id = 4, name = "100004" }, new tbioudn022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN022"" t1 +USING (SELECT 1 as ID, '100001' as NAME FROM dual +UNION ALL + SELECT 2, '100002' FROM dual +UNION ALL + SELECT 3, '100003' FROM dual +UNION ALL + SELECT 4, '100004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME) + +; + +INSERT ALL +INTO ""TBIOUDN022""(""NAME"") VALUES('00001') +INTO ""TBIOUDN022""(""NAME"") VALUES('00002') +INTO ""TBIOUDN022""(""NAME"") VALUES('00003') +INTO ""TBIOUDN022""(""NAME"") VALUES('00004') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbioudn022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn03 { id1 = 1, id2 = "02", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN03"" t1 +USING (SELECT 1 as ID1, '02' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN03"" t1 +USING (SELECT 2 as ID1, '02' as ID2, '02' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn03 { id1 = 1, id2 = "01", name = "01" }, new tbioudn03 { id1 = 2, id2 = "02", name = "02" }, new tbioudn03 { id1 = 3, id2 = "03", name = "03" }, new tbioudn03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02', '02' FROM dual +UNION ALL + SELECT 3, '03', '03' FROM dual +UNION ALL + SELECT 4, '04', '04' FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn03 { id1 = 1, id2 = "01", name = "001" }, new tbioudn03 { id1 = 2, id2 = "02", name = "002" }, new tbioudn03 { id1 = 3, id2 = "03", name = "003" }, new tbioudn03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '001' as NAME FROM dual +UNION ALL + SELECT 2, '02', '002' FROM dual +UNION ALL + SELECT 3, '03', '003' FROM dual +UNION ALL + SELECT 4, '04', '004' FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudn03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN04"" t1 +USING (SELECT 1 as ID, '011' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN04"" t1 +USING (SELECT 2 as ID, '02' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn04 { id = 1, name = "01" }, new tbioudn04 { id = 2, name = "02" }, new tbioudn04 { id = 3, name = "03" }, new tbioudn04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual +UNION ALL + SELECT 2, '02', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '03', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '04', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn04 { id = 1, name = "001" }, new tbioudn04 { id = 2, name = "002" }, new tbioudn04 { id = 3, name = "003" }, new tbioudn04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN04"" t1 +USING (SELECT 1 as ID, '001' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual +UNION ALL + SELECT 2, '002', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '003', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '004', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudn04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateTest.cs index 3901c553..5143f004 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/Curd/DamengInsertOrUpdateTest.cs @@ -313,10 +313,10 @@ WHEN NOT MATCHED THEN values (t2.ID1, t2.ID2, t2.NAME)", sql); iou.ExecuteAffrows(); - iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); sql = iou.ToSql(); Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 -USING (SELECT 1 as ID1, '02' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +USING (SELECT 1 as ID1, '01' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) WHEN MATCHED THEN update set ""NAME"" = t2.NAME WHEN NOT MATCHED THEN diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESInsertOrUpdateIfExistsDoNotingTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESInsertOrUpdateIfExistsDoNotingTest.cs new file mode 100644 index 00000000..740d3dbe --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESInsertOrUpdateIfExistsDoNotingTest.cs @@ -0,0 +1,266 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.KingbaseES +{ + public class KingbaseESInsertOrUpdateIfExistsDoNotingTest + { + IFreeSql fsql => g.kingbaseES; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB01""(""ID"") VALUES(1) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB01""(""ID"") VALUES(1) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB01""(""ID"") VALUES(2) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB01""(""ID"") VALUES(1), (2), (3), (4) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB01""(""ID"") VALUES(1), (2), (3), (4) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbioudb01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB02""(""ID"", ""NAME"") VALUES(1, '01') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB02""(""ID"", ""NAME"") VALUES(1, '011') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB02""(""ID"", ""NAME"") VALUES(2, '02') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB02""(""ID"", ""NAME"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB02""(""ID"", ""NAME"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""ID"", ""NAME"") VALUES(1, '01') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""ID"", ""NAME"") VALUES(1, '011') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""ID"", ""NAME"") VALUES(2, '02') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""ID"", ""NAME"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""ID"", ""NAME"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('01'), ('02'), ('03'), ('04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('001'), ('002'), ('003'), ('004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""ID"", ""NAME"") VALUES(1, '100001'), (2, '100002'), (3, '100003'), (4, '100004') +ON CONFLICT(""ID"") DO NOTHING + +; + +INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('00001'), ('00002'), ('00003'), ('00004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB03""(""ID1"", ""ID2"", ""NAME"") VALUES(1, '01', '01') +ON CONFLICT(""ID1"", ""ID2"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB03""(""ID1"", ""ID2"", ""NAME"") VALUES(1, '01', '011') +ON CONFLICT(""ID1"", ""ID2"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB03""(""ID1"", ""ID2"", ""NAME"") VALUES(2, '02', '02') +ON CONFLICT(""ID1"", ""ID2"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB03""(""ID1"", ""ID2"", ""NAME"") VALUES(1, '01', '01'), (2, '02', '02'), (3, '03', '03'), (4, '04', '04') +ON CONFLICT(""ID1"", ""ID2"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB03""(""ID1"", ""ID2"", ""NAME"") VALUES(1, '01', '001'), (2, '02', '002'), (3, '03', '003'), (4, '04', '004') +ON CONFLICT(""ID1"", ""ID2"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB04""(""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") VALUES(1, '01', 0, current_timestamp) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB04""(""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") VALUES(1, '011', 0, current_timestamp) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB04""(""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") VALUES(2, '02', 0, current_timestamp) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB04""(""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") VALUES(1, '01', 0, current_timestamp), (2, '02', 0, current_timestamp), (3, '03', 0, current_timestamp), (4, '04', 0, current_timestamp) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB04""(""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") VALUES(1, '001', 0, current_timestamp), (2, '002', 0, current_timestamp), (3, '003', 0, current_timestamp), (4, '004', 0, current_timestamp) +ON CONFLICT(""ID"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESInsertOrUpdateTest.cs index 4a1cff8f..971cfe25 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/Curd/KingbaseESInsertOrUpdateTest.cs @@ -107,9 +107,9 @@ ON CONFLICT(""ID1"", ""ID2"") DO UPDATE SET ""NAME"" = EXCLUDED.""NAME""", sql); Assert.Equal(1, iou.ExecuteAffrows()); - iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); sql = iou.ToSql(); - Assert.Equal(@"INSERT INTO ""TBIOU03""(""ID1"", ""ID2"", ""NAME"") VALUES(1, '02', '011') + Assert.Equal(@"INSERT INTO ""TBIOU03""(""ID1"", ""ID2"", ""NAME"") VALUES(1, '01', '011') ON CONFLICT(""ID1"", ""ID2"") DO UPDATE SET ""NAME"" = EXCLUDED.""NAME""", sql); Assert.Equal(1, iou.ExecuteAffrows()); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs new file mode 100644 index 00000000..2aa81af4 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs @@ -0,0 +1,453 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.MySql +{ + public class MySqlInsertOrUpdateIfExistsDoNothingTest + { + + IFreeSql fsql => g.mysql; + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '011' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '03' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '04' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '011' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '03' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '04' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('01'), ('02'), ('03'), ('04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('001'), ('002'), ('003'), ('004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '100001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '100002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '100003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '100004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1) + +; + +INSERT INTO `tbioudb022`(`name`) VALUES('00001'), ('00002'), ('00003'), ('00004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '011' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 2, '02', '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1) +UNION ALL + SELECT 2, '02', '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1) +UNION ALL + SELECT 3, '03', '03' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 3 AND a.`id2` = '03') + limit 0,1) +UNION ALL + SELECT 4, '04', '04' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 4 AND a.`id2` = '04') + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1) +UNION ALL + SELECT 2, '02', '002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1) +UNION ALL + SELECT 3, '03', '003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 3 AND a.`id2` = '03') + limit 0,1) +UNION ALL + SELECT 4, '04', '004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 4 AND a.`id2` = '04') + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '01', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '011', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 2, '02', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '01', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '02', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '03', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '04', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '001', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '002', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '003', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '004', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateIfExistsDoNothingTest.cs new file mode 100644 index 00000000..87c2cc30 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateIfExistsDoNothingTest.cs @@ -0,0 +1,425 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.Oracle +{ + public class OracleInsertOrUpdateIfExistsDoNothingTest + { + IFreeSql fsql => g.oracle; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 2 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ID FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ID FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + } + class tbioudb01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ID, '011' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 2 as ID, '02' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ID, '001' as NAME FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 1 as ID, '011' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 2 as ID, '02' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 1 as ID, '001' as NAME FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('01')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('011')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('02')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOUDB022""(""NAME"") VALUES('01') +INTO ""TBIOUDB022""(""NAME"") VALUES('02') +INTO ""TBIOUDB022""(""NAME"") VALUES('03') +INTO ""TBIOUDB022""(""NAME"") VALUES('04') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOUDB022""(""NAME"") VALUES('001') +INTO ""TBIOUDB022""(""NAME"") VALUES('002') +INTO ""TBIOUDB022""(""NAME"") VALUES('003') +INTO ""TBIOUDB022""(""NAME"") VALUES('004') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 1 as ID, '100001' as NAME FROM dual +UNION ALL + SELECT 2, '100002' FROM dual +UNION ALL + SELECT 3, '100003' FROM dual +UNION ALL + SELECT 4, '100004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME) + +; + +INSERT ALL +INTO ""TBIOUDB022""(""NAME"") VALUES('00001') +INTO ""TBIOUDB022""(""NAME"") VALUES('00002') +INTO ""TBIOUDB022""(""NAME"") VALUES('00003') +INTO ""TBIOUDB022""(""NAME"") VALUES('00004') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 2 as ID1, '02' as ID2, '02' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02', '02' FROM dual +UNION ALL + SELECT 3, '03', '03' FROM dual +UNION ALL + SELECT 4, '04', '04' FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '001' as NAME FROM dual +UNION ALL + SELECT 2, '02', '002' FROM dual +UNION ALL + SELECT 3, '03', '003' FROM dual +UNION ALL + SELECT 4, '04', '004' FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ID, '011' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 2 as ID, '02' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual +UNION ALL + SELECT 2, '02', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '03', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '04', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ID, '001' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual +UNION ALL + SELECT 2, '002', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '003', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '004', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateTest.cs index 8ed896b3..0081c3b1 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleInsertOrUpdateTest.cs @@ -314,10 +314,10 @@ WHEN NOT MATCHED THEN values (t2.ID1, t2.ID2, t2.NAME)", sql); iou.ExecuteAffrows(); - iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); sql = iou.ToSql(); Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 -USING (SELECT 1 as ID1, '02' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +USING (SELECT 1 as ID1, '01' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) WHEN MATCHED THEN update set ""NAME"" = t2.NAME WHEN NOT MATCHED THEN diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateIfExistsDoNotingTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateIfExistsDoNotingTest.cs new file mode 100644 index 00000000..5ddbb0a4 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateIfExistsDoNotingTest.cs @@ -0,0 +1,266 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.PostgreSQL +{ + public class PostgreSQLInsertOrUpdateIfExistsDoNotingTest + { + IFreeSql fsql => g.pgsql; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(1) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(1) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(2) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(1), (2), (3), (4) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(1), (2), (3), (4) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbioudb01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(1, '01') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(1, '011') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(2, '02') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '01') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '011') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(2, '02') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('01'), ('02'), ('03'), ('04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('001'), ('002'), ('003'), ('004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '100001'), (2, '100002'), (3, '100003'), (4, '100004') +ON CONFLICT(""id"") DO NOTHING + +; + +INSERT INTO ""tbioudb022""(""name"") VALUES('00001'), ('00002'), ('00003'), ('00004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '01') +ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '011') +ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(2, '02', '02') +ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '01'), (2, '02', '02'), (3, '03', '03'), (4, '04', '04') +ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '001'), (2, '02', '002'), (3, '03', '003'), (4, '04', '004') +ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '01', 0, current_timestamp) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '011', 0, current_timestamp) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(2, '02', 0, current_timestamp) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '01', 0, current_timestamp), (2, '02', 0, current_timestamp), (3, '03', 0, current_timestamp), (4, '04', 0, current_timestamp) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '001', 0, current_timestamp), (2, '002', 0, current_timestamp), (3, '003', 0, current_timestamp), (4, '004', 0, current_timestamp) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs index e539b712..c1ba0fb4 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs @@ -194,9 +194,9 @@ ON CONFLICT(""id1"", ""id2"") DO UPDATE SET ""name"" = EXCLUDED.""name""", sql); Assert.Equal(1, iou.ExecuteAffrows()); - iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); sql = iou.ToSql(); - Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '02', '011') + Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '011') ON CONFLICT(""id1"", ""id2"") DO UPDATE SET ""name"" = EXCLUDED.""name""", sql); Assert.Equal(1, iou.ExecuteAffrows()); diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateIfExistsDoNothingTest.cs new file mode 100644 index 00000000..623205b1 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateIfExistsDoNothingTest.cs @@ -0,0 +1,422 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Odbc.SqlServer +{ + public class SqlServerInsertOrUpdateIfExistsDoNothingTest + { + IFreeSql fsql => g.sqlserver; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb01] t1 +USING (SELECT 1 as id ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb01] t1 +USING (SELECT 1 as id ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb01] t1 +USING (SELECT 2 as id ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb01] t1 +USING (SELECT 1 as id +UNION ALL + SELECT 2 +UNION ALL + SELECT 3 +UNION ALL + SELECT 4 ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb01] t1 +USING (SELECT 1 as id +UNION ALL + SELECT 2 +UNION ALL + SELECT 3 +UNION ALL + SELECT 4 ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbioudb01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb02] t1 +USING (SELECT 1 as id, N'01' as name ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb02] t1 +USING (SELECT 1 as id, N'011' as name ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb02] t1 +USING (SELECT 2 as id, N'02' as name ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb02] t1 +USING (SELECT 1 as id, N'01' as name +UNION ALL + SELECT 2, N'02' +UNION ALL + SELECT 3, N'03' +UNION ALL + SELECT 4, N'04' ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb02] t1 +USING (SELECT 1 as id, N'001' as name +UNION ALL + SELECT 2, N'002' +UNION ALL + SELECT 3, N'003' +UNION ALL + SELECT 4, N'004' ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 1 as id, N'01' as name ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbioudb022] OFF;", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 1 as id, N'011' as name ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbioudb022] OFF;", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 2 as id, N'02' as name ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbioudb022] OFF;", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 1 as id, N'01' as name +UNION ALL + SELECT 2, N'02' +UNION ALL + SELECT 3, N'03' +UNION ALL + SELECT 4, N'04' ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbioudb022] OFF;", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 1 as id, N'001' as name +UNION ALL + SELECT 2, N'002' +UNION ALL + SELECT 3, N'003' +UNION ALL + SELECT 4, N'004' ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbioudb022] OFF;", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbioudb022]([name]) VALUES(N'01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbioudb022]([name]) VALUES(N'011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbioudb022]([name]) VALUES(N'02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbioudb022]([name]) VALUES(N'01'), (N'02'), (N'03'), (N'04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbioudb022]([name]) VALUES(N'001'), (N'002'), (N'003'), (N'004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 1 as id, N'100001' as name +UNION ALL + SELECT 2, N'100002' +UNION ALL + SELECT 3, N'100003' +UNION ALL + SELECT 4, N'100004' ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbioudb022] OFF; + +; + +INSERT INTO [tbioudb022]([name]) VALUES(N'00001'), (N'00002'), (N'00003'), (N'00004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb03] t1 +USING (SELECT 1 as id1, N'01' as id2, N'01' as name ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb03] t1 +USING (SELECT 1 as id1, N'01' as id2, N'011' as name ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb03] t1 +USING (SELECT 2 as id1, N'02' as id2, N'02' as name ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb03] t1 +USING (SELECT 1 as id1, N'01' as id2, N'01' as name +UNION ALL + SELECT 2, N'02', N'02' +UNION ALL + SELECT 3, N'03', N'03' +UNION ALL + SELECT 4, N'04', N'04' ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb03] t1 +USING (SELECT 1 as id1, N'01' as id2, N'001' as name +UNION ALL + SELECT 2, N'02', N'002' +UNION ALL + SELECT 3, N'03', N'003' +UNION ALL + SELECT 4, N'04', N'004' ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb04] t1 +USING (SELECT 1 as id, N'01' as name, 0 as version, getdate() as CreateTime ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb04] t1 +USING (SELECT 1 as id, N'011' as name, 0 as version, getdate() as CreateTime ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb04] t1 +USING (SELECT 2 as id, N'02' as name, 0 as version, getdate() as CreateTime ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb04] t1 +USING (SELECT 1 as id, N'01' as name, 0 as version, getdate() as CreateTime +UNION ALL + SELECT 2, N'02', 0, getdate() +UNION ALL + SELECT 3, N'03', 0, getdate() +UNION ALL + SELECT 4, N'04', 0, getdate() ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb04] t1 +USING (SELECT 1 as id, N'001' as name, 0 as version, getdate() as CreateTime +UNION ALL + SELECT 2, N'002', 0, getdate() +UNION ALL + SELECT 3, N'003', 0, getdate() +UNION ALL + SELECT 4, N'004', 0, getdate() ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs index 90bc5604..148a0e1b 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs @@ -311,10 +311,10 @@ WHEN NOT MATCHED THEN values (t2.id1, t2.id2, t2.name);", sql); Assert.Equal(1, iou.ExecuteAffrows()); - iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); sql = iou.ToSql(); Assert.Equal(@"MERGE INTO [tbiou03] t1 -USING (SELECT 1 as id1, N'02' as id2, N'011' as name ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +USING (SELECT 1 as id1, N'01' as id2, N'011' as name ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) WHEN MATCHED THEN update set [name] = t2.name WHEN NOT MATCHED THEN diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateIfExistsNothingTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateIfExistsNothingTest.cs new file mode 100644 index 00000000..68a5bc27 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateIfExistsNothingTest.cs @@ -0,0 +1,425 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Dameng +{ + public class DamengInsertOrUpdateIfExistsNothingTest + { + IFreeSql fsql => g.dameng; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN01"" t1 +USING (SELECT 1 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN01"" t1 +USING (SELECT 1 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN01"" t1 +USING (SELECT 2 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn01 { id = 1 }, new tbioudn01 { id = 2 }, new tbioudn01 { id = 3 }, new tbioudn01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN01"" t1 +USING (SELECT 1 as ID FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn01 { id = 1 }, new tbioudn01 { id = 2 }, new tbioudn01 { id = 3 }, new tbioudn01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN01"" t1 +USING (SELECT 1 as ID FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + iou.ExecuteAffrows(); + } + class tbioudn01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN02"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN02"" t1 +USING (SELECT 1 as ID, '011' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN02"" t1 +USING (SELECT 2 as ID, '02' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn02 { id = 1, name = "01" }, new tbioudn02 { id = 2, name = "02" }, new tbioudn02 { id = 3, name = "03" }, new tbioudn02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN02"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn02 { id = 1, name = "001" }, new tbioudn02 { id = 2, name = "002" }, new tbioudn02 { id = 3, name = "003" }, new tbioudn02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN02"" t1 +USING (SELECT 1 as ID, '001' as NAME FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudn02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN022"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN022"" t1 +USING (SELECT 1 as ID, '011' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN022"" t1 +USING (SELECT 2 as ID, '02' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn022 { id = 1, name = "01" }, new tbioudn022 { id = 2, name = "02" }, new tbioudn022 { id = 3, name = "03" }, new tbioudn022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN022"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn022 { id = 1, name = "001" }, new tbioudn022 { id = 2, name = "002" }, new tbioudn022 { id = 3, name = "003" }, new tbioudn022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN022"" t1 +USING (SELECT 1 as ID, '001' as NAME FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDN022""(""NAME"") VALUES('01')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDN022""(""NAME"") VALUES('011')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDN022""(""NAME"") VALUES('02')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn022 { name = "01" }, new tbioudn022 { name = "02" }, new tbioudn022 { name = "03" }, new tbioudn022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOUDN022""(""NAME"") VALUES('01') +INTO ""TBIOUDN022""(""NAME"") VALUES('02') +INTO ""TBIOUDN022""(""NAME"") VALUES('03') +INTO ""TBIOUDN022""(""NAME"") VALUES('04') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn022 { name = "001" }, new tbioudn022 { name = "002" }, new tbioudn022 { name = "003" }, new tbioudn022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOUDN022""(""NAME"") VALUES('001') +INTO ""TBIOUDN022""(""NAME"") VALUES('002') +INTO ""TBIOUDN022""(""NAME"") VALUES('003') +INTO ""TBIOUDN022""(""NAME"") VALUES('004') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn022 { id = 1, name = "100001" }, new tbioudn022 { name = "00001" }, new tbioudn022 { id = 2, name = "100002" }, new tbioudn022 { name = "00002" }, new tbioudn022 { id = 3, name = "100003" }, new tbioudn022 { name = "00003" }, new tbioudn022 { id = 4, name = "100004" }, new tbioudn022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN022"" t1 +USING (SELECT 1 as ID, '100001' as NAME FROM dual +UNION ALL + SELECT 2, '100002' FROM dual +UNION ALL + SELECT 3, '100003' FROM dual +UNION ALL + SELECT 4, '100004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME) + +; + +INSERT ALL +INTO ""TBIOUDN022""(""NAME"") VALUES('00001') +INTO ""TBIOUDN022""(""NAME"") VALUES('00002') +INTO ""TBIOUDN022""(""NAME"") VALUES('00003') +INTO ""TBIOUDN022""(""NAME"") VALUES('00004') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbioudn022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn03 { id1 = 1, id2 = "02", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN03"" t1 +USING (SELECT 1 as ID1, '02' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN03"" t1 +USING (SELECT 2 as ID1, '02' as ID2, '02' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn03 { id1 = 1, id2 = "01", name = "01" }, new tbioudn03 { id1 = 2, id2 = "02", name = "02" }, new tbioudn03 { id1 = 3, id2 = "03", name = "03" }, new tbioudn03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02', '02' FROM dual +UNION ALL + SELECT 3, '03', '03' FROM dual +UNION ALL + SELECT 4, '04', '04' FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn03 { id1 = 1, id2 = "01", name = "001" }, new tbioudn03 { id1 = 2, id2 = "02", name = "002" }, new tbioudn03 { id1 = 3, id2 = "03", name = "003" }, new tbioudn03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '001' as NAME FROM dual +UNION ALL + SELECT 2, '02', '002' FROM dual +UNION ALL + SELECT 3, '03', '003' FROM dual +UNION ALL + SELECT 4, '04', '004' FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudn03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN04"" t1 +USING (SELECT 1 as ID, '011' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudn04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN04"" t1 +USING (SELECT 2 as ID, '02' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn04 { id = 1, name = "01" }, new tbioudn04 { id = 2, name = "02" }, new tbioudn04 { id = 3, name = "03" }, new tbioudn04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual +UNION ALL + SELECT 2, '02', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '03', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '04', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudn04 { id = 1, name = "001" }, new tbioudn04 { id = 2, name = "002" }, new tbioudn04 { id = 3, name = "003" }, new tbioudn04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDN04"" t1 +USING (SELECT 1 as ID, '001' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual +UNION ALL + SELECT 2, '002', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '003', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '004', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudn04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateTest.cs index 3a4ceb48..e3dea03d 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/Curd/DamengInsertOrUpdateTest.cs @@ -314,10 +314,10 @@ WHEN NOT MATCHED THEN values (t2.ID1, t2.ID2, t2.NAME)", sql); iou.ExecuteAffrows(); - iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); sql = iou.ToSql(); Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 -USING (SELECT 1 as ID1, '02' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +USING (SELECT 1 as ID1, '01' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) WHEN MATCHED THEN update set ""NAME"" = t2.NAME WHEN NOT MATCHED THEN diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs new file mode 100644 index 00000000..e1dd894b --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs @@ -0,0 +1,453 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.MySql +{ + public class MySqlInsertOrUpdateIfExistsDoNothingTest + { + + IFreeSql fsql => g.mysql; + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '011' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '03' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '04' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '011' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '03' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '04' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('01'), ('02'), ('03'), ('04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('001'), ('002'), ('003'), ('004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '100001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '100002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '100003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '100004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1) + +; + +INSERT INTO `tbioudb022`(`name`) VALUES('00001'), ('00002'), ('00003'), ('00004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '011' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 2, '02', '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1) +UNION ALL + SELECT 2, '02', '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1) +UNION ALL + SELECT 3, '03', '03' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 3 AND a.`id2` = '03') + limit 0,1) +UNION ALL + SELECT 4, '04', '04' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 4 AND a.`id2` = '04') + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1) +UNION ALL + SELECT 2, '02', '002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1) +UNION ALL + SELECT 3, '03', '003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 3 AND a.`id2` = '03') + limit 0,1) +UNION ALL + SELECT 4, '04', '004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 4 AND a.`id2` = '04') + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '01', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '011', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 2, '02', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '01', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '02', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '03', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '04', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '001', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '002', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '003', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '004', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateIfExistsDoNothingTest.cs new file mode 100644 index 00000000..d3becb46 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateIfExistsDoNothingTest.cs @@ -0,0 +1,425 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Oracle +{ + public class OracleInsertOrUpdateIfExistsDoNothingTest + { + IFreeSql fsql => g.oracle; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 2 as ID FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ID FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ID FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbioudb01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ID, '011' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 2 as ID, '02' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ID, '001' as NAME FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 1 as ID, '011' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 2 as ID, '02' as NAME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 1 as ID, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 1 as ID, '001' as NAME FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOUDB022""(""NAME"") VALUES('01') +INTO ""TBIOUDB022""(""NAME"") VALUES('02') +INTO ""TBIOUDB022""(""NAME"") VALUES('03') +INTO ""TBIOUDB022""(""NAME"") VALUES('04') + SELECT 1 FROM DUAL", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOUDB022""(""NAME"") VALUES('001') +INTO ""TBIOUDB022""(""NAME"") VALUES('002') +INTO ""TBIOUDB022""(""NAME"") VALUES('003') +INTO ""TBIOUDB022""(""NAME"") VALUES('004') + SELECT 1 FROM DUAL", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 1 as ID, '100001' as NAME FROM dual +UNION ALL + SELECT 2, '100002' FROM dual +UNION ALL + SELECT 3, '100003' FROM dual +UNION ALL + SELECT 4, '100004' FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME) + +; + +INSERT ALL +INTO ""TBIOUDB022""(""NAME"") VALUES('00001') +INTO ""TBIOUDB022""(""NAME"") VALUES('00002') +INTO ""TBIOUDB022""(""NAME"") VALUES('00003') +INTO ""TBIOUDB022""(""NAME"") VALUES('00004') + SELECT 1 FROM DUAL", sql); + Assert.Equal(8, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 2 as ID1, '02' as ID2, '02' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME FROM dual +UNION ALL + SELECT 2, '02', '02' FROM dual +UNION ALL + SELECT 3, '03', '03' FROM dual +UNION ALL + SELECT 4, '04', '04' FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '001' as NAME FROM dual +UNION ALL + SELECT 2, '02', '002' FROM dual +UNION ALL + SELECT 3, '03', '003' FROM dual +UNION ALL + SELECT 4, '04', '004' FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ID, '011' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 2 as ID, '02' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual +UNION ALL + SELECT 2, '02', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '03', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '04', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ID, '001' as NAME, 0 as VERSION, systimestamp as CREATETIME FROM dual +UNION ALL + SELECT 2, '002', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '003', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '004', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateTest.cs index d383cea5..69ef7b71 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleInsertOrUpdateTest.cs @@ -314,10 +314,10 @@ WHEN NOT MATCHED THEN values (t2.ID1, t2.ID2, t2.NAME)", sql); Assert.Equal(1, iou.ExecuteAffrows()); - iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); sql = iou.ToSql(); Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 -USING (SELECT 1 as ID1, '02' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +USING (SELECT 1 as ID1, '01' as ID2, '011' as NAME FROM dual ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) WHEN MATCHED THEN update set ""NAME"" = t2.NAME WHEN NOT MATCHED THEN diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateIfExistsDoNotingTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateIfExistsDoNotingTest.cs new file mode 100644 index 00000000..d41f8281 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateIfExistsDoNotingTest.cs @@ -0,0 +1,266 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.PostgreSQL +{ + public class PostgreSQLInsertOrUpdateIfExistsDoNotingTest + { + IFreeSql fsql => g.pgsql; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(1) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(1) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(2) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(1), (2), (3), (4) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(1), (2), (3), (4) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbioudb01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(1, '01') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(1, '011') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(2, '02') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '01') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '011') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(2, '02') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('01'), ('02'), ('03'), ('04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('001'), ('002'), ('003'), ('004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '100001'), (2, '100002'), (3, '100003'), (4, '100004') +ON CONFLICT(""id"") DO NOTHING + +; + +INSERT INTO ""tbioudb022""(""name"") VALUES('00001'), ('00002'), ('00003'), ('00004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '01') +ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '011') +ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(2, '02', '02') +ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '01'), (2, '02', '02'), (3, '03', '03'), (4, '04', '04') +ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '001'), (2, '02', '002'), (3, '03', '003'), (4, '04', '004') +ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '01', 0, current_timestamp) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '011', 0, current_timestamp) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(2, '02', 0, current_timestamp) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '01', 0, current_timestamp), (2, '02', 0, current_timestamp), (3, '03', 0, current_timestamp), (4, '04', 0, current_timestamp) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '001', 0, current_timestamp), (2, '002', 0, current_timestamp), (3, '003', 0, current_timestamp), (4, '004', 0, current_timestamp) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs index 4049b04d..0cd580cc 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs @@ -194,9 +194,9 @@ ON CONFLICT(""id1"", ""id2"") DO UPDATE SET ""name"" = EXCLUDED.""name""", sql); Assert.Equal(1, iou.ExecuteAffrows()); - iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); sql = iou.ToSql(); - Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '02', '011') + Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '011') ON CONFLICT(""id1"", ""id2"") DO UPDATE SET ""name"" = EXCLUDED.""name""", sql); Assert.Equal(1, iou.ExecuteAffrows()); diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertOrUpdateIfExistsDoNothingTest.cs new file mode 100644 index 00000000..c9a8fc85 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertOrUpdateIfExistsDoNothingTest.cs @@ -0,0 +1,293 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.ShenTong +{ + public class ShenTongInsertOrUpdateIfExistsDoNothingTest + { + IFreeSql fsql => g.shentong; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ID ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ID ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 2 as ID ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ID +UNION ALL + SELECT 2 +UNION ALL + SELECT 3 +UNION ALL + SELECT 4 ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ID +UNION ALL + SELECT 2 +UNION ALL + SELECT 3 +UNION ALL + SELECT 4 ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.ID)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbioudb01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ID, '01' as NAME ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ID, '011' as NAME ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 2 as ID, '02' as NAME ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ID, '01' as NAME +UNION ALL + SELECT 2, '02' +UNION ALL + SELECT 3, '03' +UNION ALL + SELECT 4, '04' ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ID, '001' as NAME +UNION ALL + SELECT 2, '002' +UNION ALL + SELECT 3, '003' +UNION ALL + SELECT 4, '004' ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.ID, t2.NAME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '011' as NAME ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 2 as ID1, '02' as ID2, '02' as NAME ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '01' as NAME +UNION ALL + SELECT 2, '02', '02' +UNION ALL + SELECT 3, '03', '03' +UNION ALL + SELECT 4, '04', '04' ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ID1, '01' as ID2, '001' as NAME +UNION ALL + SELECT 2, '02', '002' +UNION ALL + SELECT 3, '03', '003' +UNION ALL + SELECT 4, '04', '004' ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.ID1, t2.ID2, t2.NAME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, current_timestamp as CREATETIME ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ID, '011' as NAME, 0 as VERSION, current_timestamp as CREATETIME ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 2 as ID, '02' as NAME, 0 as VERSION, current_timestamp as CREATETIME ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ID, '01' as NAME, 0 as VERSION, current_timestamp as CREATETIME +UNION ALL + SELECT 2, '02', 0, current_timestamp +UNION ALL + SELECT 3, '03', 0, current_timestamp +UNION ALL + SELECT 4, '04', 0, current_timestamp ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ID, '001' as NAME, 0 as VERSION, current_timestamp as CREATETIME +UNION ALL + SELECT 2, '002', 0, current_timestamp +UNION ALL + SELECT 3, '003', 0, current_timestamp +UNION ALL + SELECT 4, '004', 0, current_timestamp ) t2 ON (t1.""ID"" = t2.ID) +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.ID, t2.NAME, t2.VERSION, t2.CREATETIME)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertOrUpdateTest.cs index 4efd6731..801851ae 100644 --- a/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ShenTong/Curd/ShenTongInsertOrUpdateTest.cs @@ -6,7 +6,7 @@ using Xunit; namespace FreeSql.Tests.ShenTong { - public class ShenTongInsertOrUpdateTestpublic + public class ShenTongInsertOrUpdateTest { IFreeSql fsql => g.shentong; @@ -170,10 +170,10 @@ WHEN NOT MATCHED THEN values (t2.ID1, t2.ID2, t2.NAME)", sql); Assert.Equal(1, iou.ExecuteAffrows()); - iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); sql = iou.ToSql(); Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 -USING (SELECT 1 as ID1, '02' as ID2, '011' as NAME ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) +USING (SELECT 1 as ID1, '01' as ID2, '011' as NAME ) t2 ON (t1.""ID1"" = t2.ID1 AND t1.""ID2"" = t2.ID2) WHEN MATCHED THEN update set ""NAME"" = t2.NAME WHEN NOT MATCHED THEN diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateIfExistsDoNothingTest.cs new file mode 100644 index 00000000..350ce5b8 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateIfExistsDoNothingTest.cs @@ -0,0 +1,424 @@ +using FreeSql.DataAnnotations; +using FreeSql.Tests.DataContext.SqlServer; +using SaleIDO.Entity.Storeage; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.SqlServer +{ + public class SqlServerInsertOrUpdateIfExistsDoNothingTest + { + IFreeSql fsql => g.sqlserver; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb01] t1 +USING (SELECT 1 as id ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb01] t1 +USING (SELECT 1 as id ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb01] t1 +USING (SELECT 2 as id ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb01] t1 +USING (SELECT 1 as id +UNION ALL + SELECT 2 +UNION ALL + SELECT 3 +UNION ALL + SELECT 4 ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb01] t1 +USING (SELECT 1 as id +UNION ALL + SELECT 2 +UNION ALL + SELECT 3 +UNION ALL + SELECT 4 ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.id);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbioudb01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb02] t1 +USING (SELECT 1 as id, N'01' as name ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb02] t1 +USING (SELECT 1 as id, N'011' as name ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb02] t1 +USING (SELECT 2 as id, N'02' as name ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb02] t1 +USING (SELECT 1 as id, N'01' as name +UNION ALL + SELECT 2, N'02' +UNION ALL + SELECT 3, N'03' +UNION ALL + SELECT 4, N'04' ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb02] t1 +USING (SELECT 1 as id, N'001' as name +UNION ALL + SELECT 2, N'002' +UNION ALL + SELECT 3, N'003' +UNION ALL + SELECT 4, N'004' ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 1 as id, N'01' as name ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbioudb022] OFF;", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 1 as id, N'011' as name ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbioudb022] OFF;", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 2 as id, N'02' as name ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbioudb022] OFF;", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 1 as id, N'01' as name +UNION ALL + SELECT 2, N'02' +UNION ALL + SELECT 3, N'03' +UNION ALL + SELECT 4, N'04' ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbioudb022] OFF;", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 1 as id, N'001' as name +UNION ALL + SELECT 2, N'002' +UNION ALL + SELECT 3, N'003' +UNION ALL + SELECT 4, N'004' ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbioudb022] OFF;", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbioudb022]([name]) VALUES(N'01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbioudb022]([name]) VALUES(N'011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbioudb022]([name]) VALUES(N'02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbioudb022]([name]) VALUES(N'01'), (N'02'), (N'03'), (N'04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbioudb022]([name]) VALUES(N'001'), (N'002'), (N'003'), (N'004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 1 as id, N'100001' as name +UNION ALL + SELECT 2, N'100002' +UNION ALL + SELECT 3, N'100003' +UNION ALL + SELECT 4, N'100004' ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.id, t2.name);; +SET IDENTITY_INSERT [tbioudb022] OFF; + +; + +INSERT INTO [tbioudb022]([name]) VALUES(N'00001'), (N'00002'), (N'00003'), (N'00004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb03] t1 +USING (SELECT 1 as id1, N'01' as id2, N'01' as name ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb03] t1 +USING (SELECT 1 as id1, N'01' as id2, N'011' as name ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb03] t1 +USING (SELECT 2 as id1, N'02' as id2, N'02' as name ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb03] t1 +USING (SELECT 1 as id1, N'01' as id2, N'01' as name +UNION ALL + SELECT 2, N'02', N'02' +UNION ALL + SELECT 3, N'03', N'03' +UNION ALL + SELECT 4, N'04', N'04' ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb03] t1 +USING (SELECT 1 as id1, N'01' as id2, N'001' as name +UNION ALL + SELECT 2, N'02', N'002' +UNION ALL + SELECT 3, N'03', N'003' +UNION ALL + SELECT 4, N'04', N'004' ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.id1, t2.id2, t2.name);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb04] t1 +USING (SELECT 1 as id, N'01' as name, 0 as version, getdate() as CreateTime ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb04] t1 +USING (SELECT 1 as id, N'011' as name, 0 as version, getdate() as CreateTime ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb04] t1 +USING (SELECT 2 as id, N'02' as name, 0 as version, getdate() as CreateTime ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb04] t1 +USING (SELECT 1 as id, N'01' as name, 0 as version, getdate() as CreateTime +UNION ALL + SELECT 2, N'02', 0, getdate() +UNION ALL + SELECT 3, N'03', 0, getdate() +UNION ALL + SELECT 4, N'04', 0, getdate() ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb04] t1 +USING (SELECT 1 as id, N'001' as name, 0 as version, getdate() as CreateTime +UNION ALL + SELECT 2, N'002', 0, getdate() +UNION ALL + SELECT 3, N'003', 0, getdate() +UNION ALL + SELECT 4, N'004', 0, getdate() ) t2 ON (t1.[id] = t2.id) +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.id, t2.name, t2.version, t2.CreateTime);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs index dcbb2a3b..7ea53b8e 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs @@ -313,10 +313,10 @@ WHEN NOT MATCHED THEN values (t2.id1, t2.id2, t2.name);", sql); Assert.Equal(1, iou.ExecuteAffrows()); - iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); sql = iou.ToSql(); Assert.Equal(@"MERGE INTO [tbiou03] t1 -USING (SELECT 1 as id1, N'02' as id2, N'011' as name ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) +USING (SELECT 1 as id1, N'01' as id2, N'011' as name ) t2 ON (t1.[id1] = t2.id1 AND t1.[id2] = t2.id2) WHEN MATCHED THEN update set [name] = t2.name WHEN NOT MATCHED THEN diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateIfExistsDoNothingTest.cs new file mode 100644 index 00000000..07ca702a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateIfExistsDoNothingTest.cs @@ -0,0 +1,453 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Sqlite +{ + public class SqliteInsertOrUpdateIfExistsDoNothingTest + { + + IFreeSql fsql => g.sqlite; + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") SELECT 1, '01' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb02"" a + WHERE (a.""id"" = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") SELECT 1, '011' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb02"" a + WHERE (a.""id"" = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") SELECT 2, '02' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb02"" a + WHERE (a.""id"" = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") SELECT 1, '01' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb02"" a + WHERE (a.""id"" = 1) + limit 0,1) +UNION ALL + SELECT 2, '02' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb02"" a + WHERE (a.""id"" = 2) + limit 0,1) +UNION ALL + SELECT 3, '03' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb02"" a + WHERE (a.""id"" = 3) + limit 0,1) +UNION ALL + SELECT 4, '04' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb02"" a + WHERE (a.""id"" = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") SELECT 1, '001' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb02"" a + WHERE (a.""id"" = 1) + limit 0,1) +UNION ALL + SELECT 2, '002' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb02"" a + WHERE (a.""id"" = 2) + limit 0,1) +UNION ALL + SELECT 3, '003' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb02"" a + WHERE (a.""id"" = 3) + limit 0,1) +UNION ALL + SELECT 4, '004' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb02"" a + WHERE (a.""id"" = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") SELECT 1, '01' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") SELECT 1, '011' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") SELECT 2, '02' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") SELECT 1, '01' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 1) + limit 0,1) +UNION ALL + SELECT 2, '02' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 2) + limit 0,1) +UNION ALL + SELECT 3, '03' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 3) + limit 0,1) +UNION ALL + SELECT 4, '04' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") SELECT 1, '001' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 1) + limit 0,1) +UNION ALL + SELECT 2, '002' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 2) + limit 0,1) +UNION ALL + SELECT 3, '003' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 3) + limit 0,1) +UNION ALL + SELECT 4, '004' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('01'), ('02'), ('03'), ('04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('001'), ('002'), ('003'), ('004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") SELECT 1, '100001' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 1) + limit 0,1) +UNION ALL + SELECT 2, '100002' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 2) + limit 0,1) +UNION ALL + SELECT 3, '100003' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 3) + limit 0,1) +UNION ALL + SELECT 4, '100004' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb022"" a + WHERE (a.""id"" = 4) + limit 0,1) + +; + +INSERT INTO ""tbioudb022""(""name"") VALUES('00001'), ('00002'), ('00003'), ('00004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") SELECT 1, '01', '01' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 1 AND a.""id2"" = '01') + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") SELECT 1, '01', '011' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 1 AND a.""id2"" = '01') + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") SELECT 2, '02', '02' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 2 AND a.""id2"" = '02') + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") SELECT 1, '01', '01' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 1 AND a.""id2"" = '01') + limit 0,1) +UNION ALL + SELECT 2, '02', '02' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 2 AND a.""id2"" = '02') + limit 0,1) +UNION ALL + SELECT 3, '03', '03' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 3 AND a.""id2"" = '03') + limit 0,1) +UNION ALL + SELECT 4, '04', '04' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 4 AND a.""id2"" = '04') + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") SELECT 1, '01', '001' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 1 AND a.""id2"" = '01') + limit 0,1) +UNION ALL + SELECT 2, '02', '002' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 2 AND a.""id2"" = '02') + limit 0,1) +UNION ALL + SELECT 3, '03', '003' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 3 AND a.""id2"" = '03') + limit 0,1) +UNION ALL + SELECT 4, '04', '004' + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb03"" a + WHERE (a.""id1"" = 4 AND a.""id2"" = '04') + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""CreateTime"") SELECT 1, '01', 0, datetime(current_timestamp,'localtime') + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb04"" a + WHERE (a.""id"" = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""CreateTime"") SELECT 1, '011', 0, datetime(current_timestamp,'localtime') + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb04"" a + WHERE (a.""id"" = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""CreateTime"") SELECT 2, '02', 0, datetime(current_timestamp,'localtime') + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb04"" a + WHERE (a.""id"" = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""CreateTime"") SELECT 1, '01', 0, datetime(current_timestamp,'localtime') + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb04"" a + WHERE (a.""id"" = 1) + limit 0,1) +UNION ALL + SELECT 2, '02', 0, datetime(current_timestamp,'localtime') + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb04"" a + WHERE (a.""id"" = 2) + limit 0,1) +UNION ALL + SELECT 3, '03', 0, datetime(current_timestamp,'localtime') + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb04"" a + WHERE (a.""id"" = 3) + limit 0,1) +UNION ALL + SELECT 4, '04', 0, datetime(current_timestamp,'localtime') + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb04"" a + WHERE (a.""id"" = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""CreateTime"") SELECT 1, '001', 0, datetime(current_timestamp,'localtime') + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb04"" a + WHERE (a.""id"" = 1) + limit 0,1) +UNION ALL + SELECT 2, '002', 0, datetime(current_timestamp,'localtime') + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb04"" a + WHERE (a.""id"" = 2) + limit 0,1) +UNION ALL + SELECT 3, '003', 0, datetime(current_timestamp,'localtime') + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb04"" a + WHERE (a.""id"" = 3) + limit 0,1) +UNION ALL + SELECT 4, '004', 0, datetime(current_timestamp,'localtime') + WHERE NOT EXISTS(SELECT 1 + FROM ""tbioudb04"" a + WHERE (a.""id"" = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateTest.cs index 2e793f17..d0e650ad 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/Curd/SqliteInsertOrUpdateTest.cs @@ -166,9 +166,9 @@ INSERT INTO ""tbiou022""(""name"") VALUES('00001'), ('00002'), ('00003'), ('0000 Assert.Equal(@"REPLACE INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '01')", sql); Assert.Equal(1, iou.ExecuteAffrows()); - iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "02", name = "011" }); + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); sql = iou.ToSql(); - Assert.Equal(@"REPLACE INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '02', '011')", sql); + Assert.Equal(@"REPLACE INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '011')", sql); Assert.Equal(1, iou.ExecuteAffrows()); iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 2, id2 = "02", name = "02" }); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index e0ffd602..6a822109 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1151,6 +1151,13 @@ 实体集合 + + + 当记录存在时,什么都不做 + 换句话:只有记录不存在时才插入 + + + 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; @@ -3929,14 +3936,17 @@ - 插入或更新数据 - MySql: on duplicate key update - PostgreSQL: on conflict do update - SqlServer: merge into - Oracle: merge into + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + MySql 5.6+: on duplicate key update + PostgreSQL 9.4+: on conflict do update + SqlServer 2008+: merge into + Oracle 11+: merge into Sqlite: replace into - Dameng: merge into - 注意:还可以使用 FreeSql.Repository 的 InsertOrUpdate 方法 + 达梦: merge into + 人大金仓:on conflict do update + 神通:merge into + MsAccess:不支持 + 注意区别:FreeSql.Repository 仓储也有 InsertOrUpdate 方法(不依赖数据库特性) diff --git a/FreeSql/Interface/Curd/IInsertOrUpdate.cs b/FreeSql/Interface/Curd/IInsertOrUpdate.cs index c6db9222..639a3ac2 100644 --- a/FreeSql/Interface/Curd/IInsertOrUpdate.cs +++ b/FreeSql/Interface/Curd/IInsertOrUpdate.cs @@ -35,6 +35,13 @@ namespace FreeSql /// IInsertOrUpdate SetSource(IEnumerable source); + /// + /// 当记录存在时,什么都不做 + /// 换句话:只有记录不存在时才插入 + /// + /// + IInsertOrUpdate IfExistsDoNothing(); + /// /// 设置表名规则,可用于分库/分表,参数1:默认表名;返回值:新表名; /// diff --git a/FreeSql/Interface/IFreeSql.cs b/FreeSql/Interface/IFreeSql.cs index bb42ba92..bdc61fa0 100644 --- a/FreeSql/Interface/IFreeSql.cs +++ b/FreeSql/Interface/IFreeSql.cs @@ -45,14 +45,17 @@ public interface IFreeSql : IDisposable IInsert Insert(IEnumerable source) where T1 : class; /// - /// 插入或更新数据 - /// MySql: on duplicate key update - /// PostgreSQL: on conflict do update - /// SqlServer: merge into - /// Oracle: merge into + /// 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + /// MySql 5.6+: on duplicate key update + /// PostgreSQL 9.4+: on conflict do update + /// SqlServer 2008+: merge into + /// Oracle 11+: merge into /// Sqlite: replace into - /// Dameng: merge into - /// 注意:还可以使用 FreeSql.Repository 的 InsertOrUpdate 方法 + /// 达梦: merge into + /// 人大金仓:on conflict do update + /// 神通:merge into + /// MsAccess:不支持 + /// 注意区别:FreeSql.Repository 仓储也有 InsertOrUpdate 方法(不依赖数据库特性) /// /// /// diff --git a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs index ba76d54d..310ecdb7 100644 --- a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs @@ -19,6 +19,7 @@ namespace FreeSql.Internal.CommonProvider protected CommonUtils _commonUtils; protected CommonExpression _commonExpression; protected List _source = new List(); + protected bool _doNothing = false; protected Dictionary _auditValueChangedDict = new Dictionary(StringComparer.CurrentCultureIgnoreCase); protected TableInfo _table; protected Func _tableRule; @@ -106,6 +107,12 @@ namespace FreeSql.Internal.CommonProvider return this; } + public IInsertOrUpdate IfExistsDoNothing() + { + _doNothing = true; + return this; + } + protected string TableRuleInvoke() { if (_tableRule == null) return _table.DbName; diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index fae63436..281837e2 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -494,7 +494,8 @@ namespace FreeSql.Internal.CommonProvider public virtual string ToSql() => ToSqlValuesOrSelectUnionAll(true); - public string ToSqlValuesOrSelectUnionAll(bool isValues = true) + public string ToSqlValuesOrSelectUnionAll(bool isValues = true) => ToSqlValuesOrSelectUnionAllExtension101(isValues, null); + public string ToSqlValuesOrSelectUnionAllExtension101(bool isValues, Action onrow) { if (_source == null || _source.Any() == false) return null; var sb = new StringBuilder(); @@ -541,6 +542,7 @@ namespace FreeSql.Internal.CommonProvider ++colidx2; } if (isValues) sb.Append(")"); + onrow?.Invoke(d, didx, sb); ++didx; } if (_noneParameter && specialParams.Any()) diff --git a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs index 1f4046e2..d4da4540 100644 --- a/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Dameng/Curd/DamengInsertOrUpdate.cs @@ -38,7 +38,7 @@ namespace FreeSql.Dameng.Curd sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); - if (cols.Any()) + if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => a.Attribute.IsVersion ? diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs index 1106945d..e61d1491 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsertOrUpdate.cs @@ -40,7 +40,23 @@ namespace FreeSql.MySql.Curd string sql = ""; if (IdentityColumn != null && flagInsert) sql = insert.ToSql(); - else sql = new OnDuplicateKeyUpdate(insert.InsertIdentity()).ToSql(); + else + { + insert.InsertIdentity(); + if (_doNothing == false) + sql = new OnDuplicateKeyUpdate(insert).ToSql(); + else + { + if (_table.Primarys.Any() == false) throw new Exception($"fsql.InsertOrUpdate + IfExistsDoNothing + MySql 要求实体类 {_table.CsName} 必须有主键"); + sql = insert.ToSqlValuesOrSelectUnionAllExtension101(false, (rowd, idx, sb) => + sb.Append(" \r\n FROM dual WHERE NOT EXISTS(").Append( + _orm.Select() + .AsTable((_, __) => _tableRule?.Invoke(__)).AsType(_table.Type) + .DisableGlobalFilter() + .WhereDynamic(rowd) + .Limit(1).ToSql("1").Replace("\r\n", "\r\n\t")).Append(")")); + } + } if (string.IsNullOrEmpty(sql)) return null; if (insert._params?.Any() == true) dbParams.AddRange(insert._params); return sql; diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs index a6305e38..ed5f4257 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/Curd/OdbcDamengInsertOrUpdate.cs @@ -38,7 +38,7 @@ namespace FreeSql.Odbc.Dameng sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); - if (cols.Any()) + if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => a.Attribute.IsVersion ? diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs index 9125b467..4dce4686 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/Curd/OdbcKingbaseESInsertOrUpdate.cs @@ -44,7 +44,7 @@ namespace FreeSql.Odbc.KingbaseES { var ocdu = new OdbcKingbaseESOnConflictDoUpdate(insert.InsertIdentity()); ocdu.IgnoreColumns(_table.Columns.Values.Where(a => a.Attribute.CanUpdate == false).Select(a => a.Attribute.Name).ToArray()); - if (_table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false) + if (_doNothing == true || _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false) ocdu.DoNothing(); sql = ocdu.ToSql(); } diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs index 86747427..c1e7592a 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsertOrUpdate.cs @@ -1,4 +1,5 @@ using FreeSql.Internal; +using System; using System.Collections.Generic; using System.Data.Common; using System.Linq; @@ -38,7 +39,23 @@ namespace FreeSql.Odbc.MySql string sql = ""; if (IdentityColumn != null && flagInsert) sql = insert.ToSql(); - else sql = new OdbcMySqlOnDuplicateKeyUpdate(insert.InsertIdentity()).ToSql(); + else + { + insert.InsertIdentity(); + if (_doNothing == false) + sql = new OdbcMySqlOnDuplicateKeyUpdate(insert).ToSql(); + else + { + if (_table.Primarys.Any() == false) throw new Exception($"fsql.InsertOrUpdate + IfExistsDoNothing + MySql 要求实体类 {_table.CsName} 必须有主键"); + sql = insert.ToSqlValuesOrSelectUnionAllExtension101(false, (rowd, idx, sb) => + sb.Append(" \r\n FROM dual WHERE NOT EXISTS(").Append( + _orm.Select() + .AsTable((_, __) => _tableRule?.Invoke(__)).AsType(_table.Type) + .DisableGlobalFilter() + .WhereDynamic(rowd) + .Limit(1).ToSql("1").Replace("\r\n", "\r\n\t")).Append(")")); + } + } if (string.IsNullOrEmpty(sql)) return null; if (insert._params?.Any() == true) dbParams.AddRange(insert._params); return sql; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs index ed63ad31..7ea43d2f 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsertOrUpdate.cs @@ -38,7 +38,7 @@ namespace FreeSql.Odbc.Oracle sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); - if (cols.Any()) + if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => a.Attribute.IsVersion ? diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs index 311e46b2..2f3a8a0f 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/Curd/OdbcPostgreSQLInsertOrUpdate.cs @@ -42,7 +42,7 @@ namespace FreeSql.Odbc.PostgreSQL { var ocdu = new OdbcPostgreSQLOnConflictDoUpdate(insert.InsertIdentity()); ocdu.IgnoreColumns(_table.Columns.Values.Where(a => a.Attribute.CanUpdate == false).Select(a => a.Attribute.Name).ToArray()); - if (_table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false) + if (_doNothing == true || _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false) ocdu.DoNothing(); sql = ocdu.ToSql(); } diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs index 18779fe2..d4e711b2 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsertOrUpdate.cs @@ -40,7 +40,7 @@ namespace FreeSql.Odbc.SqlServer sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); - if (cols.Any()) + if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => a.Attribute.IsVersion ? diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs index a79c1694..36d50d18 100644 --- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsertOrUpdate.cs @@ -38,7 +38,7 @@ namespace FreeSql.Oracle.Curd sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); - if (cols.Any()) + if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => a.Attribute.IsVersion ? diff --git a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs index a8a48263..c3a8461c 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/Curd/PostgreSQLInsertOrUpdate.cs @@ -42,7 +42,7 @@ namespace FreeSql.PostgreSQL.Curd { var ocdu = new OnConflictDoUpdate(insert.InsertIdentity()); ocdu.IgnoreColumns(_table.Columns.Values.Where(a => a.Attribute.CanUpdate == false).Select(a => a.Attribute.Name).ToArray()); - if (_table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false) + if (_doNothing == true || _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true).Any() == false) ocdu.DoNothing(); sql = ocdu.ToSql(); } diff --git a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs index f3ec0b2d..b03afa5a 100644 --- a/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.ShenTong/Curd/ShenTongInsertOrUpdate.cs @@ -38,7 +38,7 @@ namespace FreeSql.ShenTong.Curd sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); - if (cols.Any()) + if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => a.Attribute.IsVersion ? diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs index b05b9e2c..d9834bd8 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsertOrUpdate.cs @@ -40,7 +40,7 @@ namespace FreeSql.SqlServer.Curd sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _table.Primarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{a.Attribute.Name}"))).Append(") \r\n"); var cols = _table.Columns.Values.Where(a => a.Attribute.IsPrimary == false && a.Attribute.CanUpdate == true); - if (cols.Any()) + if (_doNothing == false && cols.Any()) sb.Append("WHEN MATCHED THEN \r\n") .Append(" update set ").Append(string.Join(", ", cols.Select(a => a.Attribute.IsVersion ? diff --git a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs index ba2d2189..696d6920 100644 --- a/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs +++ b/Providers/FreeSql.Provider.Sqlite/Curd/SqliteInsertOrUpdate.cs @@ -37,15 +37,32 @@ namespace FreeSql.Sqlite.Curd .NoneParameter(true) as Internal.CommonProvider.InsertProvider; insert._source = data; - if (IdentityColumn != null && flagInsert == false) insert.InsertIdentity(); - - var sql = insert.ToSql(); + string sql = ""; + if (IdentityColumn != null && flagInsert) sql = insert.ToSql(); + else + { + insert.InsertIdentity(); + if (_doNothing == false) + { + sql = insert.ToSql(); + if (sql?.StartsWith("INSERT INTO ") == true) + sql = $"REPLACE INTO {sql.Substring("INSERT INTO ".Length)}"; + } + else + { + if (_table.Primarys.Any() == false) throw new Exception($"fsql.InsertOrUpdate + IfExistsDoNothing + Sqlite 要求实体类 {_table.CsName} 必须有主键"); + sql = insert.ToSqlValuesOrSelectUnionAllExtension101(false, (rowd, idx, sb) => + sb.Append(" \r\n WHERE NOT EXISTS(").Append( + _orm.Select() + .AsTable((_, __) => _tableRule?.Invoke(__)).AsType(_table.Type) + .DisableGlobalFilter() + .WhereDynamic(rowd) + .Limit(1).ToSql("1").Replace("\r\n", "\r\n\t")).Append(")")); + } + } if (string.IsNullOrEmpty(sql)) return null; if (insert._params?.Any() == true) dbParams.AddRange(insert._params); - if (IdentityColumn != null && flagInsert) return sql; - - if (sql.StartsWith("INSERT INTO ") == false) return null; - return $"REPLACE INTO {sql.Substring("INSERT INTO ".Length)}"; + return sql; } } }