假设您有下面的字符串,您会如何建议将其解析为各种值?每个“记录”以break标记结束。第一个值是事件名称,括号中的第二个值是帐号,下一个是票证数量,最后是支付的总价格。
Education Luncheon (501-2620) - 2 - $110<br>Womens Breakfast (512-2620) - 2 - $80<br>Friday Luncheon (502-26200) - 2 - 110<br>
答案 0 :(得分:2)
我想说使用XML
解析以及PARSENAME
和REPLACE
函数直接查询,而不使用任何UDF
:
假设这个字符串:
DECLARE @str VARCHAR(MAX)='Education Luncheon (501-2620) - 2 - $110<br>Womens Breakfast (512-2620) - 2 - $80<br>Friday Luncheon (502-26200) - 2 - 110<br>'
现在只需将该字符串转换为XML
并在cte
内解析它,最后使用提到的字符串函数:
;WITH cte AS(
SELECT Value = tbl.fld.value('(./text())[1]', 'nvarchar(4000)')
FROM
(
SELECT
v = CONVERT(XML, '<i>'
+ REPLACE(@str, '<br>' , '</i><i>')
+ '</i>')
) AS a
CROSS APPLY v.nodes('i') AS tbl(fld)
WHERE tbl.fld.value('(./text())[1]', 'nvarchar(4000)') IS NOT NULL
)
SELECT PARSENAME(REPLACE(Value ,'(','.'),2) AS [Event],
PARSENAME(REPLACE(REPLACE(Value ,'(','.') ,')','.'),2)AS AccNumber,
PARSENAME(REPLACE(Value ,'-','.'),2) AS Qty ,
PARSENAME(REPLACE(Value ,'-','.'),1) AS Price
FROM cte
我们将得到此结果:
| Event | AccNumber | Qty | Price |
|---------------------|-----------|-----|-------|
| Education Luncheon | 501-2620 | 2 | $110 |
| Womens Breakfast | 512-2620 | 2 | $80 |
| Friday Luncheon | 502-26200 | 2 | 110 |
答案 1 :(得分:1)
首先创建一个分割功能。然后使用以下查询。
CREATE FUNCTION dbo.Split
(
@delimited nvarchar(max),
@delimiter nvarchar(100)
) RETURNS @t TABLE
(
-- Id column can be commented out, not required for sql splitting string
id int identity(1,1), -- I use this column for numbering splitted parts
val nvarchar(max)
)
AS
BEGIN
declare @xml xml
set @xml = N'<root><r>' + replace(@delimited,@delimiter,'</r><r>') + '</r></root>'
insert into @t(val)
select
r.value('.','varchar(max)') as item
from @xml.nodes('//root/r') as records(r)
RETURN
END
GO
DECLARE @String VARCHAR(1000) = 'Education Luncheon (501-2620) - 2 - $110<br>Womens Breakfast (512-2620) - 2 - $80<br>Friday Luncheon (502-26200) - 2 - 110<br>'
SELECT LEFT(val , CHARINDEX('(', Val) -1 ) AS EventName
,REPLACE( REPLACE(
SUBSTRING(Val , CHARINDEX('(', Val) , LEN(Val) - CHARINDEX(')', Val))
,'(',''),')','') AS AccountNumber
,REPLACE(SUBSTRING(Val,
CHARINDEX(') -', Val) +2, LEN(Val) - CHARINDEX(') -', Val)
- CHARINDEX('-', REVERSE(Val)))
,'-','') AS Quantity
,PARSENAME(REPLACE(Val ,'-','.'),1) AS PricePaid
FROM dbo.Split(@String, '<br>')
WHERE NULLIF(val ,'') IS NOT NULL
╔═════════════════════╦═══════════════╦══════════╦═══════════╗
║ EventName ║ AccountNumber ║ Quantity ║ PricePaid ║
╠═════════════════════╬═══════════════╬══════════╬═══════════╣
║ Education Luncheon ║ 501-2620 ║ 2 ║ $110 ║
║ Womens Breakfast ║ 512-2620 ║ 2 ║ $80 ║
║ Friday Luncheon ║ 502-26200 ║ 2 ║ 110 ║
╚═════════════════════╩═══════════════╩══════════╩═══════════╝