2015-08-17 61 views
0

我正在使用以下內容來處理我認爲是用戶可以鍵入到數據輸入窗體中的衆多時間格式(其中代碼庫在字段驗證或強制時間格式方面極其有限) 。實質上,這是一個自由文本字段,我們希望人們閱讀鼠標懸停的提示,其中提到「請輸入像上午8:00一樣的時間」。數據然後被觸發到SQL。經歷了足夠長的時間,我知道人們會閱讀並輸入除「8:00 AM」以外的其他格式的時間。爲了解決這個問題,並且缺乏強制前端驗證格式的能力,我在一個SQL觸發器中實現了以下功能,該功能處理從前端發佈到SQL表的結果時處理各種時間格式:使用時間轉換處理錯誤

TIME_START = CASE 
      --Time Format like 0800 or 1030 or 2230 
      WHEN p.TIME_START LIKE '[0-9][0-9][0-9][0-9]' THEN CONVERT(time, LEFT(p.TIME_START,2) + ':' + RIGHT(p.TIME_START,2) + ':00', 108) 
      --Time Format like 800 or 930 
      WHEN p.TIME_START LIKE '[0-9][0-9][0-9]' THEN CONVERT(time, '0' + LEFT(p.TIME_START,1) + ':' + RIGHT(p.TIME_START,2) + ':00', 108) 
      --Time Format like 08:30 or 22:30 
      WHEN p.TIME_START LIKE '[0-9][0-9]:[0-9][0-9]' OR p.TIME_START LIKE '[0-9][0-9]:[0-9][0-9]' THEN CONVERT(time, p.TIME_START, 109) 
      --Time Format like 8:30 or 9:35 
      WHEN p.TIME_START LIKE '[0-9]:[0-9][0-9]' OR p.TIME_START LIKE '[0-9]:[0-9][0-9]' THEN CONVERT(time, p.TIME_START, 108) 
      -- Time Format like 08:30 AM or 12:30 PM 
      WHEN p.TIME_START LIKE '[0-9][0-9]:[0-9][0-9] AM' OR p.TIME_START LIKE '[0-9][0-9]:[0-9][0-9] PM' THEN     CONVERT(time, p.TIME_START, 0) 
      --Time Format like 8:30 AM or 7:45 PM 
      WHEN p.TIME_START LIKE '[0-9]:[0-9][0-9] AM' OR p.TIME_START LIKE '[0-9]:[0-9][0-9] PM' THEN CONVERT(time, p.TIME_START, 0) 
      --Time Format like 08:30:00 AM or 21:45:00 PM 
      WHEN p.TIME_START LIKE '[0-9][0-9]:[0-9][0-9]:[0-9][0-9] AM' OR p.TIME_START LIKE '[0-9][0-9]:[0-9][0-9]:[0-9][0-9] PM' THEN CONVERT(time, p.TIME_START, 0) 
      --Time Format like 8:30:00 AM or 7:45:00 PM 
      WHEN p.TIME_START LIKE '[0-9]:[0-9][0-9]:[0-9][0-9] AM' OR p.TIME_START LIKE '[0-9]:[0-9][0-9]:[0-9][0-9] PM' THEN CONVERT(time, p.TIME_START, 0) 
      END 

這很好。如果我得到「0800」或「8:00 AM」或「08:00 AM」等等,SQL將總是發佈「08:00:00.0000000」(我們想要並且需要時間(n)格式來做一些數學以後)。

問題是,我似乎無法將我的頭包裹在一些錯誤處理中,如果某人輸入的時間與這些格式之一不匹配,那麼這些錯誤處理會向TIME_START發佈默認的虛擬值,例如「 2930「或」19:00 AM「,甚至」6點鐘「或」六點鐘在晚上「。目前,SQL只是在發生錯誤時拋出錯誤。如前所述,將錯誤處理放在前端代碼中不是一種選擇(該API僅支持DATETIME,從未真正意圖在「Form Builder」中支持僅用於時間的字段,您很想知道,這是Esri的「Web應用程序生成器」)。當時間超出格式例如「00:00:00.00000」時,我只想得到一個虛擬值,然後允許我們查看所有具有「00:00:00.00000」的行,然後回顧在數據錄入日誌中嘗試翻譯他們打算輸入的內容,或跟進用戶,詢問他們真正意義的時間,這種情況我預計會在5%的時間內發生。希望這是有道理的。

+0

您可以通過爲用戶提供適當的工具來爲自己節省很多痛苦在應用程序層上創建時間值,例如在C#應用程序中,您可以使用['TimePicker'](http://www.codeproject.com/Articles/170684/Time-Picker),它將爲用戶提供統一的選擇時間值的方法,對你來說不那麼頭疼,對於前輩用戶來說也更加圓滑和方便。 –

+0

不幸的是,我們僅限於雲提供商給我們用作數據輸入表單的內容,並且無法對其進行修改。 「......將錯誤處理放在前端代碼中不是一個選項」 – tpcolson

回答

0

啊,服務器端用戶輸入驗證......我感到你的痛苦。 :)

對於您的錯誤情況,您只需指定ELSE作爲您的CASE聲明的一部分。但是,我看到您的LIKE聲明中可能有所改進。例如,第一種情況將匹配'9999''2468',這兩個時間都是無效的。

我有點累了,一直沒能對此進行測試的所有情況,但下面應該有希望的工作:

/* 
-- This section provided to give the query context 
CREATE TABLE ##TimeTable (
    TIME_START VARCHAR(64) NOT NULL 
); 


INSERT INTO ##TimeTable (TIME_START) VALUES('19:00 AM'); 
INSERT INTO ##TimeTable (TIME_START) VALUES('2930'); 
INSERT INTO ##TimeTable (TIME_START) VALUES('1930'); 
*/ 

SELECT 
     CASE 
      --Time Format like 0800 or 1030 or 2230 
      WHEN p.TIME_START LIKE '[0-1][0-9][0-5][0-9]' 
       OR p.TIME_START LIKE '2[0-3][0-5][0-9]' 
       THEN CONVERT(time, LEFT(p.TIME_START,2) + ':' + RIGHT(p.TIME_START,2) + ':00', 108) 
      --Time Format like 800 or 930 
      WHEN p.TIME_START LIKE '[0-9][0-5][0-9]' THEN CONVERT(time, '0' + LEFT(p.TIME_START,1) + ':' + RIGHT(p.TIME_START,2) + ':00', 108) 
      --Time Format like 08:30 or 22:30 
      WHEN p.TIME_START LIKE '[0-1][0-9]:[0-5][0-9]' 
       OR p.TIME_START LIKE '2[0-3]:[0-5][0-9]' 
       THEN CONVERT(time, p.TIME_START, 109) 
      --Time Format like 8:30 or 9:35 
      WHEN p.TIME_START LIKE '[0-9]:[0-5][0-9]' 
       OR p.TIME_START LIKE '[0-9]:[0-5][0-9]' 
       THEN CONVERT(time, p.TIME_START, 108) 
      -- Time Format like 08:30 AM or 12:30 PM 
      WHEN p.TIME_START LIKE '0[0-9]:[5-9][0-9] [AP]M' 
       OR p.TIME_START LIKE '1[0-2]:[5-9][0-9] [AP]M' 
       THEN CONVERT(time, p.TIME_START, 0) 
      --Time Format like 8:30 AM or 7:45 PM 
      WHEN p.TIME_START LIKE '[0-9]:[0-5][0-9] [AP]M' 
       THEN CONVERT(time, p.TIME_START, 0) 
      --Time Format like 08:30:00 or 21:45:00 
      WHEN p.TIME_START LIKE '[0-1][0-9]:[0-5][0-9]:[0-5][0-9]' 
       OR p.TIME_START LIKE '2[0-3]:[0-5][0-9]:[0-5][0-9]' 
       THEN CONVERT(time, p.TIME_START, 0) 
      --Time Format like 08:30:00 AM or 09:45:00 PM 
      WHEN p.TIME_START LIKE '0[0-9]:[0-5][0-9]:[0-5][0-9] [AP]M' 
       OR p.TIME_START LIKE '1[0-2]:[0-5][0-9]:[0-5][0-9] [AP]M' 
       THEN CONVERT(time, p.TIME_START, 0) 
      --Time Format like 8:30:00 AM or 7:45:00 PM 
      WHEN p.TIME_START LIKE '[0-9]:[0-5][0-9]:[0-5][0-9] [AP]M' 
       THEN CONVERT(time, p.TIME_START, 0) 
      ELSE CAST('06:00' AS TIME) 
     END 
FROM ##TimeTable AS p;