iT邦幫忙

0

MSSQL 日期加減問題請教

  • 分享至 

  • xImage

您好:
如下圖,我在語法最外圈,要去計算
日期

其中 我直接用
CONVERT(VARCHAR(8), DATEADD( DAY , vaildday , CONVERT(DATE, CONVERT(VARCHAR(8), manudate+19110000) ) ) ,112 ) -19110000 'vailddate'

這樣,不到1秒就出來

但是,我將該段,寫成FUNC

ALTER function fn_DATEADD_C(@cdate varchar(7), @vaildday  int )
returns varchar(7)
AS
BEGIN
	declare @rtn varchar(7)

	DECLARE @datex as datetime 
	

	select @rtn=   CONVERT(VARCHAR(8), 
	                           DATEADD( DAY , @vaildday  ,  CONVERT(DATE, CONVERT(VARCHAR(8), @cdate+19110000) ) ) 
						   ,112 ) -19110000
	RETURN @rtn
END;

同樣環境下,卻要跑到3秒鐘才會出來,請問這是什麼問題
謝謝

https://ithelp.ithome.com.tw/upload/images/20240508/20104095dQNfdpQS9y.png

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
0
rain_yu
iT邦研究生 5 級 ‧ 2024-05-09 08:39:07
ALTER FUNCTION fn_DATEADD_C(@cdate varchar(7), @vaildday int)
RETURNS varchar(7)
AS
BEGIN
    DECLARE @rtn varchar(7)

    SELECT @rtn = CONVERT(VARCHAR(8), DATEADD(DAY, @vaildday, DATEADD(DAY, -1, CAST(@cdate + '01' AS date))), 112)

    RETURN @rtn
END;
noway iT邦研究生 1 級 ‧ 2024-05-09 08:43:30 檢舉

您好:
謝謝,但
訊息 241,層級 16,狀態 1,行 5
從字元字串轉換成日期及/或時間時,轉換失敗。

rain_yu iT邦研究生 5 級 ‧ 2024-05-17 09:02:38 檢舉

這個錯誤訊息是因為函數嘗試將@cdate字串轉換為日期時發生錯誤。

造成這個問題的可能原因包括:

  1. @cdate的格式不正確。函數期望的格式可能是YYYYMM,但你提供的格式可能不符。

  2. 該函數在處理YYYYMM格式的日期時存在問題。

  3. DATEADD函數在處理某些日期值時會遇到問題。

這裡有一個修改後的版本,可以處理YYYYMM格式的日期:

ALTER FUNCTION fn_DATEADD_C(@cdate varchar(6), @vaildday int)
RETURNS varchar(6)
AS
BEGIN
    DECLARE @rtn varchar(6)
    DECLARE @dateVal date

    SELECT @dateVal = CAST(CONCAT(@cdate, '01') AS date)
    SELECT @rtn = CONVERT(VARCHAR(6), DATEADD(DAY, @vaildday, @dateVal), 112)

    RETURN @rtn
END;

這個版本做了以下改變:

  1. 函數參數@cdate改為varchar(6),因為YYYYMM格式只有6個字元。

  2. 在轉換為日期時,先將@cdate拼接上'01'來建立完整的日期字串。

  3. 使用CONCAT函數將@cdate和'01'拼接,然後轉換為DATE型別。

  4. 最後使用CONVERT函數將結果轉換回YYYYMM格式的字串。

這個修改後的函數應該可以正確處理YYYYMM格式的日期了。希望這個解決方案對你有幫助。

0
dreamfly
iT邦新手 5 級 ‧ 2024-05-09 11:03:40

因為SQL function只是在撰寫程序上方便,不代表執行運作效能也會提升。
另外裡面還帶入了日期轉文字型態互轉處理,如果資料查詢筆數量體多的話;function會每筆個別深入邏輯層運作,勢必須要時間處理。
會建議先查詢條件(例如帶入的@cdateu前就要有值才運作),符合查詢筆數後在做function方法處理。
如果資料筆數結果需要符合跟不符合都要顯示,可以使用union聯集來處理。
雖然可能SQL寫起來會比較麻煩,但如果要讓效能提升必須需要做點處理。

noway iT邦研究生 1 級 ‧ 2024-05-09 14:19:19 檢舉

您好:
目前使1000筆資料,濃縮到剩下3筆
這3筆資料,在去做轉換
理論上,會很快就出來
但結果卻不是

我有另外將原來的篩選語法結果 先寫入到#temp
在用此#temp來用 func,這樣一下子就出來了
不知原因為何?
謝謝

1
pilipala
iT邦研究生 5 級 ‧ 2024-05-09 17:20:35

就不要用 function,主因是 2019 前的 function 會一筆一筆跑,可以從 SQL Profile 去觀察,但該情況在執行計畫內卻完全不會呈現

2019 推出 inline function 則是改善該情況

noway iT邦研究生 1 級 ‧ 2024-05-09 21:15:46 檢舉

請問 您說的是這一個 内嵌表值函数(Inline Function) 嗎?
他是回傳TABLE, 目前我只需要回傳一個值 而已

執行計畫,不太會看卡在哪一塊
SQL profile 要如何去看?
謝謝

pilipala iT邦研究生 5 級 ‧ 2024-05-09 21:34:12 檢舉

內嵌資料表值函數是 Inline Table-Valued Function,兩者不一樣

Inline function 可以參考該篇文章-Wonderful Scalar UDF Inlining

pilipala iT邦研究生 5 級 ‧ 2024-05-09 21:34:27 檢舉

SQL profile 要如何去看?

profile 開 tuning 範本觀察,應該會有才是

我要發表回答

立即登入回答