Kaynağa Gözat

#14 SQL Error [1067] [42000]: Invalid default value for 'name'

Lith 7 ay önce
ebeveyn
işleme
edb7ebc731

+ 13 - 4
src/Vitorm.MySql/SqlTranslateService.cs

@@ -198,23 +198,25 @@ CREATE TABLE IF NOT EXISTS {DelimitTableName(entityDescriptor)} (
 
             string GetColumnSql(IColumnDescriptor column)
             {
+                var isNullable = !column.isKey && column.isNullable;
                 var columnDbType = column.columnDbType ?? GetColumnDbType(column);
-                var defaultValue = column.isNullable ? "default null" : "";
+                var defaultValue = isNullable ? "default null" : "";
                 if (column.isIdentity)
                 {
                     var type = TypeUtil.GetUnderlyingType(column.type);
                     if (type == typeof(Guid)) { }
                     else defaultValue = "AUTO_INCREMENT";
                 }
+                var nullable = isNullable ? "" : "not null";
 
                 // https://mysql.net.cn/doc/refman/8.0/en/create-table.html
                 /*
-                  name  type    nullable        defaultValue        primaryKey
-                  id    int     not null/null   default null        primary key
+                  name  type    primaryKey      defaultValue    nullable
+                  id    int     primary key     default null    not null/null
                                                 AUTO_INCREMENT
                  */
 
-                return $"  {DelimitIdentifier(column.columnName)}  {columnDbType}  {(column.isNullable ? "null" : "not null")}  {defaultValue}  {(column.isKey ? "primary key" : "")}";
+                return $"  {DelimitIdentifier(column.columnName)}  {columnDbType}  {(column.isKey ? "primary key" : "")}  {defaultValue}  {nullable}";
             }
         }
         public readonly static Dictionary<Type, string> columnDbTypeMap = new()
@@ -238,6 +240,13 @@ CREATE TABLE IF NOT EXISTS {DelimitTableName(entityDescriptor)} (
         {
             Type type = column.type;
 
+            if (column.isKey && column.type == typeof(string))
+            {
+                // avoid issue: SQL Error [1071] [42000]: Specified key was too long; max key length is 3072 bytes.
+                // example "CREATE TABLE test ( `name` varchar(1000)  primary key);"
+                return "varchar(200)";
+            }
+
             if (column.columnLength.HasValue && type == typeof(string))
             {
                 // varchar(1000)

+ 13 - 5
src/Vitorm.SqlServer/SqlTranslateService.cs

@@ -240,25 +240,26 @@ create table {DelimitTableName(entityDescriptor)} (
 
             string GetColumnSql(IColumnDescriptor column)
             {
+                var isNullable = !column.isKey && column.isNullable;
                 var columnDbType = column.columnDbType ?? GetColumnDbType(column);
-                var defaultValue = column.isNullable ? "default null" : "";
+                var defaultValue = isNullable ? "default null" : "";
                 if (column.isIdentity)
                 {
                     var type = TypeUtil.GetUnderlyingType(column.type);
                     if (type == typeof(Guid)) defaultValue = "default NewId()";
                     else defaultValue = "identity(1,1)";
                 }
-
+                var nullable = isNullable ? "" : "not null";
                 /*
-                  name  type    nullable        defaultValue                    primaryKey 
-                  id    int     not null/null   default null                    primary key
+                  name  type    primaryKey      defaultValue        nullable
+                  id    int     primary key     default null        not null/null
                                                 identity(1,1)
                                                 default NewId()
                                                 default NewSequentialId()
                                                 default 12
                  */
 
-                return $"  {DelimitIdentifier(column.columnName)}  {columnDbType}  {(column.isNullable ? "null" : "not null")}  {defaultValue}  {(column.isKey ? "primary key" : "")}";
+                return $"  {DelimitIdentifier(column.columnName)}  {columnDbType}  {(column.isKey ? "primary key" : "")}  {defaultValue}  {nullable}";
             }
         }
 
@@ -283,6 +284,13 @@ create table {DelimitTableName(entityDescriptor)} (
         {
             Type type = column.type;
 
+            if (column.isKey && column.type == typeof(string))
+            {
+                // avoid issue: SQL Error [1919] [S0001]: Column 'name' in table 'Issue006_Setting' is of a type that is invalid for use as a key column in an index.
+                // example "create table [Issue006_Setting] ( [name]  varchar(max) primary key not null );"
+                return "varchar(200)";
+            }
+
             if (column.columnLength.HasValue && type == typeof(string))
             {
                 // varchar(1000)

+ 4 - 2
src/Vitorm.Sqlite/SqlTranslateService.cs

@@ -181,8 +181,9 @@ CREATE TABLE IF NOT EXISTS {DelimitTableName(entityDescriptor)} (
 
             string GetColumnSql(IColumnDescriptor column)
             {
+                var isNullable = !column.isKey && column.isNullable;
                 var columnDbType = column.columnDbType ?? GetColumnDbType(column);
-                var defaultValue = column.isNullable ? "default null" : "";
+                var defaultValue = isNullable ? "default null" : "";
                 if (column.isIdentity)
                 {
                     var type = TypeUtil.GetUnderlyingType(column.type);
@@ -190,13 +191,14 @@ CREATE TABLE IF NOT EXISTS {DelimitTableName(entityDescriptor)} (
                     else defaultValue = "autoincrement";
                     //throw new NotSupportedException("identity for Sqlite is not supported yet.");
                 }
+                var nullable = isNullable ? "" : "not null";
 
                 /*
                   name  type    primaryKey      defaultValue    nullable
                   id    int     primary key     default null    not null/null
                                                 autoincrement
                  */
-                return $"  {DelimitIdentifier(column.columnName)}  {columnDbType}  {(column.isKey ? "primary key" : "")}  {defaultValue}  {(column.isNullable ? "null" : "not null")}";
+                return $"  {DelimitIdentifier(column.columnName)}  {columnDbType}  {(column.isKey ? "primary key" : "")}  {defaultValue}  {nullable}";
             }
         }
 

+ 65 - 0
test/IssuesTest/Vitorm.MsTest.Issue000_099/Issues/Issue_014_Test.cs

@@ -0,0 +1,65 @@
+using System.ComponentModel.DataAnnotations.Schema;
+
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace Vitorm.MsTest.Issue000_099.Issues
+{
+    /// <summary>
+    /// https://github.com/Vit-Orm/Vitorm/issues/14
+    /// #14 SQL Error [1067] [42000]: Invalid default value for 'name'
+    /// </summary>
+    [TestClass]
+    public class Issue_014_Test
+    {
+        static void Test(string dataProviderName)
+        {
+            // #1 Init
+            using var dbContext = Data.DataProvider(dataProviderName).CreateSqlDbContext();
+            var dbSet = dbContext.DbSet<Setting>();
+            dbSet.TryDropTable();
+            dbSet.TryCreateTable();
+            dbSet.Add(new Setting { name = "enable", value = "false" });
+
+            // #2 Assert
+            {
+                var entity = dbSet.Query().Where(m => m.name == "enable").First();
+                Assert.AreEqual("false", entity.value);
+            }
+        }
+
+
+        [TestMethod]
+        public void Test_SqlServer()
+        {
+            Test("SqlServer");
+        }
+
+
+        [TestMethod]
+        public void Test_MySql()
+        {
+            Test("MySql");
+        }
+
+
+        [TestMethod]
+        public void Test_Sqlite()
+        {
+            Test("Sqlite");
+        }
+
+        // Entity
+        [Table("Issue014_Setting")]
+        public class Setting
+        {
+            [System.ComponentModel.DataAnnotations.Key]
+            public string name { get; set; }
+
+            public string value { get; set; }
+        }
+
+    }
+
+
+}
+