有没有人知道我能用以下格式规范化字符串的最佳方法: -
'(20111026,1000,34.10)(20111027,1000,44.10)(20111028,1000,54.10)(20111029,1000,64.10)(20111030,1000,74.10)'
分为5行,3列?
|Date |Time |Amount|
-------------------------------
|2011-10-26 |10:00:00 |34.10 |
|2011-10-27 |10:00:00 |44.10 |
|2011-10-28 |10:00:00 |54.10 |
|2011-10-29 |10:00:00 |64.10 |
|2011-10-30 |10:00:00 |74.10 |
我已经设法使用字符串解析器和分隔符')('获取行和','再次获取列。但是当我对700万字符串执行此操作时,db会爆炸。
这是我到目前为止的SQL:
DECLARE @Text VARCHAR(500) = '(20111026,1000,34.10)(20111027,1000,44.10)(20111028,1000,54.10)(20111029,1000,64.10)(20111030,1000,74.10)'
SELECT
TRY_CONVERT(DATE, [1]) AS StartDate ,
CAST(TRY_CONVERT(TIME(0), DATEADD(HOUR, ( [2] / 100 ) % 100, DATEADD(MINUTE, ( [2] / 1 ) % 100, CAST('00:00' AS TIME)))) AS VARCHAR(8)) AS StartTime ,
TRY_CONVERT(NUMERIC(16, 6), [3]) AS Amount
FROM
(SELECT
X.Ordinal AS RoNum ,
Y.Ordinal AS ColNum ,
REPLACE(Y.StringValue, '(', '') AS Value
FROM
dbo.ParseString(@Text, ')(') X
CROSS APPLY
dbo.ParseString(StringValue,',') Y
WHERE
NOT Y.StringValue = '') AS SRC
PIVOT
( MIN(Value) FOR ColNum IN ( [1], [2], [3] ) ) AS PVT;
解析字符串函数: -
CREATE FUNCTION [dbo].[ParseString]
(@String VARCHAR(500), @Delimiter CHAR(1))
RETURNS TABLE
AS
RETURN
(WITH Results AS
(SELECT 1 AS Ordinal,
LTRIM(LEFT(@String, CHARINDEX(@Delimiter, @String + @Delimiter)-1)) AS StringValue,
CONVERT(VARCHAR(500), RIGHT(@String + @Delimiter, LEN(@String) - CHARINDEX(@Delimiter, @String+@Delimiter) + 1)) AS Remaining
UNION ALL
SELECT Ordinal+1,
LTRIM(LEFT(Remaining, CHARINDEX(@Delimiter, Remaining)-1)),
RIGHT(Remaining, LEN(Remaining) - CHARINDEX(@Delimiter, Remaining))
FROM Results
WHERE LEN(Remaining) > 0)
SELECT Ordinal,
StringValue
FROM Results
)
非常感谢任何帮助。
答案 0 :(得分:1)
没有必要为这样的事情分配字符串。您发布的格式几乎正确使用表值构造函数。使用替换来在()已经很好地包装的值集之间粘贴逗号意味着你可以使用一些动态的sql轻松地完成这项操作。
declare @String varchar(max) = '(20111026,1000,34.10)(20111027,1000,44.10)(20111028,1000,54.10)(20111029,1000,64.10)(20111030,1000,74.10)'
declare @SQL nvarchar(max)
set @SQL = 'select * from (VALUES ' + REPLACE(@String, ')(', '),(') + ')N (col1, col2, col3)'
select @SQL
exec sp_executesql @SQL