[研究]SQL Server 2019 欄位是允許 NULL 的 bit,ASP.NET 「將這個欄位轉換為 TemplatedField」後的處理
2021-07-01
Visual Studio 2019 v16.10 + ASP.NET + WebForm + WebApplication + C#
如果是 Not Null 欄位,不會有 Null 狀態,不會有問題。
偶然發現 Nullable 的 bit 欄位,使用「將這個欄位轉換為 TemplatedField」把 BoundField 轉成為 TemplateField 後,網頁程式執行時會出錯,所以做了點研究測試。
為何要轉換,因為 RowDataBound() 或 DataBound() 時候,要抓取欄位值,隱藏顯示某些資訊。
(下圖) 把上面問題都註解排除後,顯示畫面如下
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="BitTest.Default" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> </head> <body> <form id="form1" runat="server"> <div> <asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:TestDBConnectionString %>" DeleteCommand="DELETE FROM [TestTable2] WHERE [SN] = @SN" InsertCommand="INSERT INTO [TestTable2] ([NullableBit1], [NullableBit2], [NullableBit3], [NullableBit4], [NullableBit5], [NullableBit6], [NullableBit7], [NullableBit8], [NullableBit9], [NullableBit10], [NullableBit11], [NullableBit12], [NullableBit13], [NullableBit14], [NullableBit15], [NullableBit16], [NotNullBit]) VALUES (@NullableBit1, @NullableBit2, @NullableBit3, @NullableBit4, @NullableBit5, @NullableBit6, @NullableBit7, @NullableBit8, @NullableBit9, @NullableBit10, @NullableBit11, @NullableBit12, @NullableBit13, @NullableBit14, @NullableBit15, @NullableBit16, @NotNullBit)" SelectCommand="SELECT [SN] ,[NullableBit1] ,[NullableBit2] ,[NullableBit3] ,[NullableBit4] ,ISNULL([NullableBit5],0) AS [NullableBit5] ,ISNULL([NullableBit6],0) AS [NullableBit6] ,ISNULL([NullableBit7],0) AS [NullableBit7] ,ISNULL([NullableBit8],0) AS [NullableBit8] ,CASE WHEN [NullableBit9] IS NULL THEN 0 ELSE [NullableBit9] END AS [NullableBit9] ,CASE WHEN [NullableBit10] IS NULL THEN 0 ELSE [NullableBit10] END AS [NullableBit10] ,CASE WHEN [NullableBit11] IS NULL THEN 0 ELSE [NullableBit11] END AS [NullableBit11] ,CASE WHEN [NullableBit12] IS NULL THEN 0 ELSE [NullableBit12] END AS [NullableBit12] ,CASE WHEN [NullableBit13] IS NULL THEN CAST(0 AS BIT) ELSE [NullableBit13] END AS [NullableBit13] ,CASE WHEN [NullableBit14] IS NULL THEN CAST(0 AS BIT) ELSE [NullableBit14] END AS [NullableBit14] ,CASE WHEN [NullableBit15] IS NULL THEN CAST(0 AS BIT) ELSE [NullableBit15] END AS [NullableBit15] ,CASE WHEN [NullableBit16] IS NULL THEN CAST(0 AS BIT) ELSE [NullableBit16] END AS [NullableBit16] ,[NotNullBit] FROM [TestDB].[dbo].[TestTable2]" UpdateCommand="UPDATE [TestTable2] SET [NullableBit1] = @NullableBit1, [NullableBit2] = @NullableBit2, [NullableBit3] = @NullableBit3, [NullableBit4] = @NullableBit4, [NullableBit5] = @NullableBit5, [NullableBit6] = @NullableBit6, [NullableBit7] = @NullableBit7, [NullableBit8] = @NullableBit8, [NullableBit9] = @NullableBit9, [NullableBit10] = @NullableBit10, [NullableBit11] = @NullableBit11, [NullableBit12] = @NullableBit12, [NullableBit13] = @NullableBit13, [NullableBit14] = @NullableBit14, [NullableBit15] = @NullableBit15, [NullableBit16] = @NullableBit16, [NotNullBit] = @NotNullBit WHERE [SN] = @SN"> <DeleteParameters> <asp:Parameter Name="SN" Type="Int32" /> </DeleteParameters> <InsertParameters> <asp:Parameter Name="NullableBit1" Type="Boolean" /> <asp:Parameter Name="NullableBit2" Type="Boolean" /> <asp:Parameter Name="NullableBit3" Type="Boolean" /> <asp:Parameter Name="NullableBit4" Type="Boolean" /> <asp:Parameter Name="NullableBit5" Type="Boolean" /> <asp:Parameter Name="NullableBit6" Type="Boolean" /> <asp:Parameter Name="NullableBit7" Type="Boolean" /> <asp:Parameter Name="NullableBit8" Type="Boolean" /> <asp:Parameter Name="NullableBit9" Type="Boolean" /> <asp:Parameter Name="NullableBit10" Type="Boolean" /> <asp:Parameter Name="NullableBit11" Type="Boolean" /> <asp:Parameter Name="NullableBit12" Type="Boolean" /> <asp:Parameter Name="NullableBit13" Type="Boolean" /> <asp:Parameter Name="NullableBit14" Type="Boolean" /> <asp:Parameter Name="NullableBit15" Type="Boolean" /> <asp:Parameter Name="NullableBit16" Type="Boolean" /> <asp:Parameter Name="NotNullBit" Type="Boolean" /> </InsertParameters> <UpdateParameters> <asp:Parameter Name="NullableBit1" Type="Boolean" /> <asp:Parameter Name="NullableBit2" Type="Boolean" /> <asp:Parameter Name="NullableBit3" Type="Int16" /> <asp:Parameter Name="NullableBit4" Type="Int16" /> <asp:Parameter Name="NullableBit5" Type="Boolean" /> <asp:Parameter Name="NullableBit6" Type="Boolean" /> <asp:Parameter Name="NullableBit7" Type="Int16" /> <asp:Parameter Name="NullableBit8" Type="Int16" /> <asp:Parameter Name="NullableBit9" Type="Boolean" /> <asp:Parameter Name="NullableBit10" Type="Boolean" /> <asp:Parameter Name="NullableBit11" Type="Int16" /> <asp:Parameter Name="NullableBit12" Type="Int16" /> <asp:Parameter Name="NullableBit13" Type="Boolean" /> <asp:Parameter Name="NullableBit14" Type="Boolean" /> <asp:Parameter Name="NullableBit15" Type="Int16" /> <asp:Parameter Name="NullableBit16" Type="Int16" /> <asp:Parameter Name="NotNullBit" Type="Boolean" /> <asp:Parameter Name="SN" Type="Int32" /> </UpdateParameters> </asp:SqlDataSource> <asp:GridView ID="GridView2" runat="server" AllowPaging="True" AllowSorting="True" AutoGenerateColumns="False" DataKeyNames="SN" DataSourceID="SqlDataSource2"> <Columns> <asp:CommandField ShowEditButton="True" /> <asp:BoundField DataField="SN" HeaderText="SN" InsertVisible="False" ReadOnly="True" SortExpression="SN" /> <asp:CheckBoxField DataField="NullableBit1" HeaderText="NullableBit1" SortExpression="NullableBit1" /> <asp:TemplateField HeaderText="NullableBit2" SortExpression="NullableBit2"> <EditItemTemplate> <%--System.InvalidCastException,HResult=0x80004002,指定的轉換無效。--%> <%--<asp:CheckBox ID="CheckBox1" runat="server" Checked='<%# Bind("NullableBit2") %>' />--%> </EditItemTemplate> <ItemTemplate> <%--System.InvalidCastException,HResult=0x80004002,指定的轉換無效。--%> <%--<asp:CheckBox ID="CheckBox1" runat="server" Checked='<%# Bind("NullableBit2") %>' Enabled="false" />--%> </ItemTemplate> </asp:TemplateField> <asp:CheckBoxField DataField="NullableBit3" HeaderText="NullableBit3" SortExpression="NullableBit3" /> <asp:TemplateField HeaderText="NullableBit4" SortExpression="NullableBit4"> <EditItemTemplate> <%--System.InvalidCastException,HResult=0x80004002,指定的轉換無效。--%> <%--<asp:CheckBox ID="CheckBox2" runat="server" Checked='<%# Bind("NullableBit4") %>' />--%> </EditItemTemplate> <ItemTemplate> <%--System.InvalidCastException,HResult=0x80004002,指定的轉換無效。--%> <%--<asp:CheckBox ID="CheckBox2" runat="server" Checked='<%# Bind("NullableBit4") %>' Enabled="false" />--%> </ItemTemplate> </asp:TemplateField> <%--********************************************************************************--%> <%--,ISNULL([NullableBit5],0) AS [NullableBit5]--%> <asp:CheckBoxField DataField="NullableBit5" HeaderText="NullableBit5" SortExpression="NullableBit5" /> <asp:TemplateField HeaderText="NullableBit6" SortExpression="NullableBit6"> <EditItemTemplate> <asp:CheckBox ID="CheckBox3" runat="server" Checked='<%# Bind("NullableBit6") %>' /> </EditItemTemplate> <ItemTemplate> <asp:CheckBox ID="CheckBox3" runat="server" Checked='<%# Bind("NullableBit6") %>' Enabled="false" /> </ItemTemplate> </asp:TemplateField> <asp:CheckBoxField DataField="NullableBit7" HeaderText="NullableBit7" SortExpression="NullableBit7" /> <asp:TemplateField HeaderText="NullableBit8" SortExpression="NullableBit8"> <EditItemTemplate> <asp:CheckBox ID="CheckBox4" runat="server" Checked='<%# Bind("NullableBit8") %>' /> </EditItemTemplate> <ItemTemplate> <asp:CheckBox ID="CheckBox4" runat="server" Checked='<%# Bind("NullableBit8") %>' Enabled="false" /> </ItemTemplate> </asp:TemplateField> <%--********************************************************************************--%> <%--,CASE WHEN [NullableBit9] IS NULL THEN 0 ELSE [NullableBit9] END AS [NullableBit9]--%> <%--字串未被辨認為有效的 Boolean。--%> <%--<asp:CheckBoxField DataField="NullableBit9" HeaderText="NullableBit9" SortExpression="NullableBit9" />--%> <asp:TemplateField HeaderText="NullableBit10" SortExpression="NullableBit10"> <EditItemTemplate> <%--System.InvalidCastException,HResult=0x80004002,指定的轉換無效。--%> <%--<asp:CheckBox ID="CheckBox5" runat="server" Checked='<%# Bind("NullableBit10") %>' />--%> </EditItemTemplate> <ItemTemplate> <%--System.InvalidCastException,HResult=0x80004002,指定的轉換無效。--%> <%--<asp:CheckBox ID="CheckBox5" runat="server" Checked='<%# Bind("NullableBit10") %>' Enabled="false" />--%> </ItemTemplate> </asp:TemplateField> <%--字串未被辨認為有效的 Boolean。--%> <%--<asp:CheckBoxField DataField="NullableBit11" HeaderText="NullableBit11" SortExpression="NullableBit11" />--%> <asp:TemplateField HeaderText="NullableBit12" SortExpression="NullableBit12"> <EditItemTemplate> <%--System.InvalidCastException,HResult=0x80004002,指定的轉換無效。--%> <%--<asp:CheckBox ID="CheckBox6" runat="server" Checked='<%# Bind("NullableBit12") %>' />--%> </EditItemTemplate> <ItemTemplate> <%--System.InvalidCastException,HResult=0x80004002,指定的轉換無效。--%> <%--<asp:CheckBox ID="CheckBox6" runat="server" Checked='<%# Bind("NullableBit12") %>' Enabled="false" />--%> </ItemTemplate> </asp:TemplateField> <%--********************************************************************************--%> <%--CASE WHEN [NullableBit13] IS NULL THEN CAST(0 AS BIT) ELSE [NullableBit13] END AS [NullableBit13]--%> <asp:CheckBoxField DataField="NullableBit13" HeaderText="NullableBit13" SortExpression="NullableBit13" /> <asp:TemplateField HeaderText="NullableBit14" SortExpression="NullableBit14"> <EditItemTemplate> <asp:CheckBox ID="CheckBox7" runat="server" Checked='<%# Bind("NullableBit14") %>' /> </EditItemTemplate> <ItemTemplate> <asp:CheckBox ID="CheckBox7" runat="server" Checked='<%# Bind("NullableBit14") %>' Enabled="false" /> </ItemTemplate> </asp:TemplateField> <asp:CheckBoxField DataField="NullableBit15" HeaderText="NullableBit15" SortExpression="NullableBit15" /> <asp:TemplateField HeaderText="NullableBit16" SortExpression="NullableBit16"> <EditItemTemplate> <asp:CheckBox ID="CheckBox8" runat="server" Checked='<%# Bind("NullableBit16") %>' /> </EditItemTemplate> <ItemTemplate> <asp:CheckBox ID="CheckBox8" runat="server" Checked='<%# Bind("NullableBit16") %>' Enabled="false" /> </ItemTemplate> </asp:TemplateField> <asp:CheckBoxField DataField="NotNullBit" HeaderText="NotNullBit" SortExpression="NotNullBit" /> </Columns> </asp:GridView> </div> </form> </body> </html> |
結論,如果 bit 欄位是 Not Null ,不會有問題,建議作法。
如果bit欄位一定要 Nullable,SELECT 最好先用 ISNULL() 或 CASE WHEN 把 NULL 換成 0,
而且用 CASE WHEN 時候,要用 CAST 把結果 0 指定為 BIT 型態。
(完)
沒有留言:
張貼留言