我不相信「INT(255)
」是一個有效的數據類型。
我知道255只是一個顯示寬度屬性。 INT數據類型定義值的範圍,顯示寬度不影響值的範圍。但是我從來沒有在大於11的INT上看到長度修飾符。(10爲無符號整數)(?)
作爲測試,您可以嘗試指定INT(11)
,或者只是INT
。
更大的問題也許是,該數據類型爲INT
的變量正在作爲第一個參數傳遞給DATE_FORMAT
函數。但DATE_FORMAT
的第一個參數需要是DATE
,DATETIME
或TIMESTAMP
(iirc)。 INT到DATE可能會有一些隱含的轉換,但我認爲不存在。
我不明白爲什麼你需要一個函數從日期減去的月數。 MySQL內置了函數和簡單的表達式。
例如:
dateexpr + INTERVAL -6個月
返回日期(或DATETIME)6個月值從dateexpr
減去。 如果您需要「向下舍入」到本月的第一個月,或者轉換爲只有'yyyy-mm'的字符串,則可以分別執行DATE_FORMAT(dateexpr,'%Y-%m-01')
或SUBSTRING(dateexpr,1,7)
。
審查
CREATE FUNCTION a_testbed.PrevMonth (
in_date date,
in_mn_count int)
這看起來不錯,兩個輸入參數,日期和INT。 (功能參數始終IN參數。)
RETURNS int
有點奇怪一個名爲PrevMonth
函數採用一個DATE參數,但返回一個INT,而不是DATE,但這不是一個錯誤。
BEGIN
/* local variable declaration */
DECLARE v_date INT(255);
255的顯示寬度是bizzarre。以前從未在INT上看到過。
DECLARE v_date_format VARCHAR(10);
DECLARE v_date_sub VARCHAR(10);
兩個字符串,看起來不錯。
SET v_date_format := DATE_FORMAT(v_date, '%Y-%m');
^^^^^^
但是v_date
是一個INT,而不是DATE或DATETIME。它沒有初始化,所以它是NULL。如果這不會拋出異常,那麼我們期望v_date_format
爲NULL。 (我懷疑你想代替v_date
在這裏指定in_date
)
SET v_date_sub := DATE_FORMAT(curdate(), '%Y-%m');
這應該讓我們的7個字符,例如「2013年7月」。所以沒有問題。
IF (in_date IS NULL) THEN
SET v_date := v_date_sub;
下面是in_date
參數的用法。檢查它是否爲空。如果是,請分配與我們分配給v_date_sub相同的7個字符。得到它了。
ELSEIF (in_mn_count IS NULL OR in_mn_count < 0) THEN
SET in_mn_count := 0;
將值賦給IN參數有效嗎? (這可能是有效的,但它是奇怪的。通常我們不給參數賦值,除非它們是OUT或INOUT參數。我們通常給過程變量賦值(有時候是MySQL用戶變量)。
爲什麼這取決於是否in_date爲空或不是(前面的IF)。好像我們希望在這兩種情況下,以檢查此參數。
ELSE
SET v_date := v_date_sub;
這不是在第一IF
指定的相同動作?看來就像這裏的邏輯讀取「如果in_date不爲空,並且ifnull(in_mn_count,-1)」我們做了一件事,否則我們做了其他的事情。我們要麼給IN參數賦值,要麼我們'重新分配將當前的YYYY-MM改爲v_date。
END IF;
到目前爲止,in_date參數的唯一用途是檢查它是否爲NULL。 in_mn_count參數的唯一用法是嘗試爲其分配一個零值,如果它爲零或小於零。
RETURN v_date_format;
我們分配什麼v_date_format
唯一的一次是在功能的開始,當我們分配從DATE_FORMAT函數的返回,以NULL值傳遞(作爲INT,而不是一個日期。)那麼什麼是所有其他代碼應該在做什麼?
END
是的,請結束。這個功能有太多的錯誤,它讓我頭痛。所以,請,是的,結束。只要讓它停止。
什麼是確切的錯誤信息? – Barmar
錯誤1265(01000)第1行的列'v_date'的數據被截斷 – user1813619
您是否有理由需要您自己的函數來執行此操作?爲什麼這會返回一個INT而不是DATE? MySQL具有內建函數和表達式以從日期中減去幾個月,例如'dateexpr + INTERVAL -n MONTH'。 – spencer7593