使用SqlDataSource.InsertParameters新增資料至NOT NULL欄位的小技巧

使用SqlDataSource.InsertParameters新增資料至NOT NULL欄位的小技巧

當資料表結構類似下列SQL命令時,大家都知道c1欄位不能為NULL,因此若從前端透過SqlDataSource新增資料到t1時,可以下列的C#語法來完成,

create table t1
(
 c1 varchar(10) not null
)
using (SqlDataSource sds = new SqlDataSource())
{
    sds.ConnectionString = @"Data Source=.;Initial Catalog=db;Persist Security Info=True;User ID=usr;Password=pwd";
    sds.InsertCommand = @"INSERT INTO [GeneralAssembly].[dbo].[t1]([c1]) VALUES (@c1)";
    sds.InsertParameters.Add(new Parameter("c1", System.Data.DbType.String, "1234567890"));               
    sds.Insert();
}

這是在要寫入c1有明確內容時適用,當我們要新增空白至c1欄位時,若指定Parameter參數的預設值為 String.Empty或是""時,會收到【無法插入 NULL 值到資料行 'c1',資料表 'GeneralAssembly.dbo.t1'; 資料行不得有 Null。INSERT 失敗】的錯誤訊息。

using (SqlDataSource sds = new SqlDataSource())
{
    sds.ConnectionString = @"Data Source=.;Initial Catalog=db;Persist Security Info=True;User ID=usr;Password=pwd";
    sds.InsertCommand = @"INSERT INTO [GeneralAssembly].[dbo].[t1]([c1]) VALUES (@c1)";
    sds.InsertParameters.Add(new Parameter("c1", System.Data.DbType.String, String.Empty));               
    sds.Insert();
}

透過SQL Profiler錄製ADO.NET所轉的TSQL語法,會發現ADO.NET自動將空字串轉成NULL,如下:

exec sp_executesql N'INSERT INTO [GeneralAssembly].[dbo].[t1] 
            ([c1]) VALUES (@c1)',N'@c1 nvarchar(4000)',@c1=NULL

經查MSDN的Parameter.ConvertEmptyStringToNull 屬性得知,【如果應將 Parameter繫結至的值轉換成 Null 參照 (即 Visual Basic 中的 Nothing) (當其為 String.Empty 時),則為 true,否則為 false。預設值為 true。】,這也是為什麼空字串會被轉成NULL的原因,因此解決方式為設定ConvertEmptyStringToNull為False,完整程式碼如下:

sds.ConnectionString = @"Data Source=.;Initial Catalog=db;Persist Security Info=True;User ID=usr;Password=pwd";
sds.InsertCommand = @"INSERT INTO [GeneralAssembly].[dbo].[t1] ([c1]) VALUES (@c1)";
Parameter c1 = new Parameter("c1", System.Data.DbType.String, string.Empty);
c1.ConvertEmptyStringToNull = false;
sds.InsertParameters.Add(c1);
sds.Insert();