T-SQL中的一些小陷阱

来源:http://www.cnblogs.com/wy123/archive/2016/06/13/5580821.html
-Advertisement-
Play Games

1,當心ISNULL函數對你的邏輯引起BUG 有人喜歡或者習慣於(並不代表我推薦,甚至這種寫法沒有任何好處)用ISNULL處理變數這種方式寫查詢 比如:select * from TestISNULL where name = ISNULL(@name,name) @name相當於傳入到存儲過程中的 ...


   

 1,當心ISNULL函數對你的邏輯引起BUG

 

    有人喜歡或者習慣於(並不代表我推薦,甚至這種寫法沒有任何好處)用ISNULL處理變數這種方式寫查詢

    比如:select * from TestISNULL where name = ISNULL(@name,name)

    @name相當於傳入到存儲過程中的參數,如果@name為null,

    相當於:select * from TestISNULL where name = name,看起來恆成立,是真的嗎?

    目的是在@name為null的時候,這個查詢條件不生效

    當時當遇到欄位name中的某些數據為null的時候,實際邏輯就變成了

    select * from TestISNULL where null= null,null=null是什麼結果?

    自己試試或者繼續往下看就知道了,

    此時會產生一些“莫名其妙”的bug,這種bug是跟數據有關,有時候出現,而有時候又沒有問題,

    對於“有時候出現有時候不出現的問題”,不管是SQL還是應用程式代碼,定位起來都不是太容易的

    這種情況,會對對問題的排查產生了很大的干擾

    看例子:

--ISNULL 處理變數的一個小陷阱
Create Table TestISNULL
(
    id int,
    name varchar(50)
)
GO

insert into TestISNULL values (1,'AAA')
insert into TestISNULL values (2,'BBB')
GO

declare @name varchar(50)
set @name=null
select * from TestISNULL where name = ISNULL(@name,name)

--結果是兩行沒有任何問題
/*
id          name
----------- ----------------------
1           AAA
2           BBB
(2 row(s) affected)
*/



--插入一條數據
insert into TestISNULL values (3,null)
GO

select * from TestISNULL
--全部結果是三行
/*
id          name
----------- --------------------
1           AAA
2           BBB
3           NULL
(3 row(s) affected)
*/

--繼續用isnull的方式處理變數做查詢 declare @name varchar(50) set @name=null select * from TestISNULL where name = ISNULL(@name,name) --結果是兩行,你明白為什麼嗎 /* id name ----------- ---------------------- 1 AAA 2 BBB (2 row(s) affected)

    究竟為什麼呢?好看,下麵應該很清楚了

    

 

 2,SQL Server 對數據類型優先順序引起Case When 的一些語法錯誤

 

    繼續用上面的表驗證另外一個小語法問題,某些邏輯處理數據的時候,欄位為null的時候,將結果統一標記為一種數值,如下

    當然,這樣是通不過的,提示將AAA轉換為數值的時候失敗

    這種問題本質上是:會將低優先順序的varchar轉換為高優先順序的int進行對比

    但是在將字元轉換為數值型的時候,就會出現轉換失敗的情況

    這裡就涉及到SQL Server數據類型優先順序的問題,有興趣的自行MSDN

    

SELECT id,
       CASE
         WHEN name IS NULL THEN 0
         ELSE name
       END AS name
FROM   TestISNULL

Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the varchar value 'AAA' to data type int.

 

解決辦法就是統一數據類型,註意字元0和數值0是不一樣的,這樣就不會引起數據類型優先順序轉換的問題

SELECT id,
       CASE
         WHEN name IS NULL THEN '0'
         ELSE name
       END AS name
FROM   TestISNULL

 當然這個問題的“變種”不僅限於case when,有各種各樣的“變種”,

當遇到“Error converting data type *** to ***.”此類問題的時候,可以考慮是不是這個原因引起的,對快速定位問題可以起到幫助作用,避免在這些小邏輯上浪費太多時間。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 安卓項目目錄結構: Assets : 資產目錄:存放文件,這些文件會被打包到APK文件中 Bin : 編譯後的文件目錄 Gen : 自動生成的文件目錄 Project.properties: 代表編譯的版本,對於安卓jar包版本 libs:支持的jar包,會被添加到android depend目錄 ...
  • 淺複製:只複製指向對象的指針,而不複製引用對象本身。計數器+1 ,就像比如retain 深層複製:複製引用對象本身。計數器不變,產生新對象 retain:始終是淺複製。引用計數每次加一。返回對象是否可變與被覆制的對象保持一致。 copy:對於可變對象為深複製,引用計數不改變;對於不可變對象是淺複製, ...
  • App Store: 編程詞典 - Swift version V1.0 這是一本覆蓋Swift基礎辭彙的詞典,也是你可以自定義的單詞本。 學編程的前提是學好英語,傳統詞典編寫速度已趕不上電腦行業發明新詞的速度。本應用專註於Swift語言和iOS開發中有特定含義的英文單詞,對這些單詞進行詳細的中文 ...
  • 什麼是資料庫的事務 事務(Transaction)是訪問並可能更新資料庫中各種數據項的一個程式執行單元(unit)。事務通常由高級資料庫操縱語言或編程語言書寫的用戶程式的執行所引起,並用形如begin transaction和end transaction語句(或函數調用)來界定。事務由事務開始和事 ...
  • 一種用於手勢輸入的透明覆蓋層,可以覆蓋在其他空間的上方,也可包含在其他控制項 android.gesture.GestureOverlayView 獲得手勢文件 需要用GesturesBuilder,如果沒有就安裝這個app 安裝 其實這是一個Sample的,用eclipse和android stud ...
  • 1、佈局文件 2、代碼部分 3、效果展示 ...
  • 1、Activity的 runOnUiThread android Activity runOnUiThread() 方法使用 2、Handler sendEmptyMessage() 3、Handler post() 4、view Post() 總結: 1、其實上面的四種方式都可歸結於一種方式:h ...
  • 1、子線程和子線程之間的通信 註意: 1、調用Looper類的 prepare() 方法可以為當前線程創建一個消息迴圈,調用loop() 方法使之處理信息,直到迴圈結束。 2、Handler有幾個構造重載,如果構造時不提供Looper類對象參數,會獲取當前線程的Looper對象,即將當前線程的消息循 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...