我創建了一個能夠從字串中提取日期的 T-SQL 函式。
當日期沒有..
請幫助獲取缺少的部分,以使此功能適用于有句點的日期。
帶句號的日期有 2 種不同的風格:
MM.DD.YYYY
M.DD.YY
我的功能代碼:
IF OBJECT_ID(N'tempdb..#fileNameTable', N'U') IS NOT NULL
DROP TABLE #fileNameTable
CREATE TABLE #fileNameTable
(
[fName] [VARCHAR](250) NULL
)
INSERT INTO #fileNameTable (fName)
SELECT '9999999991_Agent Name_08.02.2018.WAV'
INSERT INTO #fileNameTable (fName)
SELECT '9999999999 - Internal ID 1446683 (Pedro) 6.26.17 WB.mp3'
INSERT INTO #fileNameTable (fName)
SELECT '9999999998 - Internal ID 1464807 (John) 7.11.17.mp3'
INSERT INTO #fileNameTable (fName)
SELECT '9999999997 - Internal ID 1447503 (Marta) 6.27.17.mp3'
INSERT INTO #fileNameTable (fName)
SELECT '9999999996 - Internal ID 1437403 (Ruby) 6.20.17.mp3'
INSERT INTO #fileNameTable (fName)
SELECT 'rc_20200817_1612_9999999995_NJ.wav'
INSERT INTO #fileNameTable (fName)
SELECT 'rc_20200817_1543_9999999994_PA.wav'
INSERT INTO #fileNameTable (fName)
SELECT 'rc_20200817_1211_9999999993_MA.wav'
INSERT INTO #fileNameTable (fName)
SELECT 'rc_20200817_1211_9999999992_MD.wav'
SELECT *, [dbo].[ExtractDateFromFileName](fName)
FROM #fileNameTable
CREATE FUNCTION [dbo].[ExtractDateFromFileName]
(@str VARCHAR(256))
RETURNS VARCHAR(256)
AS
BEGIN
DECLARE @validchars VARCHAR(MAX)
SET @validchars = '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
DECLARE @idx INT
SET @idx = PATINDEX('%' @validchars '%',@str)
IF @idx > 0 AND (@idx = LEN(@str) - 8
OR PATINDEX(SUBSTRING(@str, @idx 9, 1), '[0-9]') = 0)
SET @str = SUBSTRING(@str, PATINDEX('%' @validchars '%', @str), 8)
ELSE
SET @str = ''
RETURN @str
END
uj5u.com熱心網友回復:
另一種方法:
CREATE FUNCTION dbo.ExtractDateFromGarbage ( @garbage varchar(250))
RETURNS TABLE WITH SCHEMABINDING
AS
RETURN
(
SELECT theDate = TRY_CONVERT(date,
x REPLACE(LEFT(y, PATINDEX('%[^0-9]%', y '.')-1),'.','/'))
FROM (SELECT g = @garbage) AS f
CROSS APPLY (VALUES (PATINDEX('%[01 ][0-9].%[0-9].[0-9][0-9]%', g),
PATINDEX('%2[0-9][0-9][0-9][0-1][0-9][0-3][0-9]%', g))) AS v(s,t)
CROSS APPLY (VALUES (SUBSTRING(g, COALESCE(NULLIF(s,0),t), 250))) AS q(q)
CROSS APPLY (VALUES(LEFT(q,6), SUBSTRING(q,7,250))) AS z(x,y)
);
它可以處理 Stu 沒有 ( mm.d.yy) 的一個極端情況:
- 示例db<>fiddle
這個故事的寓意仍然是您應該在其他地方執行此操作(并在資料進入 SQL Server 后將正確的日期存盤在正確的資料型別中)。
uj5u.com熱心網友回復:
我建議您將其實作為表值函式,我嘗試重寫您的函式以適用于示例資料中的兩種型別的日期。它可能仍然需要對邊緣情況進行一些調整,但應該大部分都在那里。
在我的臺式 PC 上使用 130 萬行(您的樣本資料,通過笛卡爾連接復制)進行測驗,您當前的標量值函式具有以下statistics time資料:
SQL Server 執行時間:CPU 時間 = 19886 毫秒,經過時間 = 19961 毫秒。
與下面的函式相同的 130 萬行有以下時間:
SQL Server 執行時間:CPU 時間 = 7122 毫秒,經過時間 = 7296 毫秒。
表值函式要快得多,因為 SQL Server 能夠將它行內到查詢中,而不是每行單獨運行一個單獨的函式,即 RBAR。
create or alter function [dbo].[ExtractDateFromFileName2](@str varchar(256))
returns table
as return
select coalesce(
Try_Convert(date,Substring(string, d1.v,8),111),
Try_Convert(date,Substring(string, d3.v,10),104),
Try_Convert(date,Substring(string, d2.v,7),1)
) [Value]
from (select @str string)s
outer apply (values(PatIndex('%[1-3][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%',string)))d1(v)
outer apply (values(PatIndex('%[0-9].[0-9][0-9].[0-9][0-9]%',string)))d2(v)
outer apply (values(PatIndex('%[0-9][0-9].[0-9][0-9].[0-9][0-9][0-9][0-9]%',string)))d3(v);
見演示小提琴
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/435007.html
