天天看點

SQL開發中容易忽視的一些小地方(一)

       寫此系列文章緣由: 做開發三年來(B/S),發現基于web 架構的項目技術主要分兩大方面: 

          第一:C#,它是程式的基礎,也可是其它開發語言,沒有開發語言也就不存在應用程式.

          第二:資料庫,現在是資訊化世界,大多數資訊都可以通過資料庫存儲來交換資訊.常與應用程式互相交流資訊.

         但在SQL開發應用時,我們往往隻觀注些常用的方法(insert delete select update),對些小細節方面(系統存儲過程,函數的應用,優化分析)研究的并不多或者是知其一不知其二,是以本人想把在學習工作當中遇到的問題總結些,希望還沒有重視這些方面的朋友會有幫助,少走些彎路.

       主旨:本文首先根據自己的經驗整理了一下SQL中的null的用法及要注意的方面.

       名詞解釋(英文辭典): null:無效的, 無價值的, 等于零的.

                   (SQL定義):SQL中, NULL 與空格, 零, 都不相同. 是指為未定義或是不可用的.

        構成因素:造成某一列成為 NULL 的因素可能是:

                        (1),值不存在;

                        (2), 值未知;

                        (3), 列對表不可用.         

       它與普通的值最大的異同是:

          相同點:

             1:統統屬于值範疇.數字1是一個值,字元串'aaa'同樣是一個值,同理 null也是一個值.

             2:都是合法的值,普通的數字,字元可以存在于表中字段,null也可以,而且是有意義的.

           不同點:

              先建立測試表:

USE [myTestDB]

GO

/****** 對象:  Table [dbo].[testNull]    腳本日期: 10/11/2008 13:45:14 ******/

SET ANSI_NULLS ON

SET QUOTED_IDENTIFIER ON

CREATE TABLE [dbo].[testNull](

    [ID] [int] IDENTITY(1,1) NOT NULL,

    [a] [nchar](10) COLLATE Chinese_PRC_CI_AS NULL,

    [b] [nchar](10) COLLATE Chinese_PRC_CI_AS NULL,

 CONSTRAINT [PK_testNull] PRIMARY KEY CLUSTERED

(

    [ID] ASC

)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]

) ON [PRIMARY]

              插入相關測試值:

insert into testNull

values('1','')

values('2',null)

                   1:普通的值一般都可能進行運算符操作,例如:ID列為int,是以可以這樣:ID=ID+1等,但如果一列的值為null,null+1=null,就是說null與任何運算符運算後都為null,這就是大家說的黑洞,會吃掉所有的東西.

        update testNull

 set b=b+1

 where b is null

                           結論:查詢後發現b的值沒有變化,仍然為null.

                   2:普通的值可以進行"="操作,例如條件中一般都會這樣出現:sUserName='張三',如果sUserName的值為null,要想找出所有名字為null的記錄時,不能這樣用:sUserName=null,因為null不是一個具體的值,任何值與它比較時都會傳回false.此時可借用is null 或者是is not null.

                  示例查詢:

                            1:select * from testNull where a=null --傳回空結果集

                            2:select * from testNull where b is null --傳回結果集 2 2 NULL

                            結論:說明null是不能用"="來比較,可用is null來替換

                   3:在用統計函數count時會不同,例如count(ID):統計記錄數.當統計的記錄中的包含有null值時,它會忽略null值.

                       示例查詢:

                            1:select count(*),count(b) from testNull 它的傳回值為2 1

                            2: select count(*),count(isnull(b,'')) from testNull 它的傳回值為2 2

                            結論:對于列包含null 時,統計行數是可用count(*),或者是先把null值轉換成對應的值再統計,例如count(isnull(b,''));

                   4:對于in 的影響不同.

                      示例查詢: 查詢testNull表中b的值包含在null中的記錄.

            select * from testNull

where b in(null) --沒有任何記錄

                           結論:in在查詢時會忽略null的記錄,查詢的時候可用is not null來查詢.

                    5:排序時順序有不同:當使用ORDER BY時,首先呈現NULL值。如果你用DESC以降序排序,NULL值最後顯示。

                        1:select * from testNull

                            1 1 ''

                            2 2 NULL

                        2:select * from testNull order by b

                             2 2 NULL

                             1 1 ''

                         3:select * from testNull order by b desc

                      6:當使用GROUP BY時,所有的NULL值被認為是相等的。這時先多插入幾條資料,友善檢視結果.

           insert into testNull

values('3',null)

         values('4','4')

select * from testNull

           select count(b) from testNull

group by b

                         傳回結果:

                           0 1 1

                           結論:可見在group by  的時候,null視為等同.

                      7:永遠不會有什麼資料等于NULL。1不等于NULL,2也一樣。但NULL也不等于NULL。是以我們隻能比較它“是”或“不是”。

        總結:SQL中提供了如此衆多的存儲過程,函數供我們調用,而我們又真正的了解幾個呢?隻有真正了解它們,才會對開發中出現的種種問題迅速找出問題所在并解決它.  

注:

   本文引用網絡上相關資料.