我有一个原始数据文件,其内容如下所示:
MSN_Check,Text,25,MSN check
0,Text,1,(Result)
HWIMPL,Text,10,HWIMPL version reading
007F,Text,6,(Measure)
1,Text,1,(Result)
VHW,Text,10,FMT hardware version
494131383346,Text,10,(Measure)
0,Text,1,(Result)
TOTAL_VER,Text,25,Total version reading
313031303130,Text,6,(Measure)
1,Text,1,(Result)
CAL_MCU,Text,25,Total version reading
05,Text,6,(Measure)
Error,Text,25,Error
9.8499985089315E-07,Numeric,Float 3.3,(Measure)
CAL_EEPROM,Text,25,Total version reading
05,Numeric,Float 3.3,(Measure)
1,Text,1,(Result)
我需要在变量中提取和存储名称,例如MSN_Check
,描述,示例MSN check
,例如0
的结果及其度量,例如{{1}但是在某些地方我只有结果或仅采取措施,所以只是将它们分开就不会有帮助。所以我的想法是:
首先,我创建了一个名为dbo.template的模板表,如下所示:
007F
在此表中,我们有名称,描述,if_measure(如果我们有一个度量,则表示 Name TestDescription Measure Result ID
----------------------------------------------
MSN_Check MSN check 0 1 1
HWIMPL HWIMPL version reading 1 1 2
VHW FMT hardware version 1 1 3
TOTAL_VER Total version reading 1 1 4
CAL_MCU Total version reading 1 0 5
Error Error 1 0 6
CAL_EEPROM Total version reading 1 1 7
,如果我们没有,则表示1
)和if_result.And我查询如下:< / p>
0
它有效!但我唯一的问题是我的名称为DECLARE @crlf AS CHAR(2) = CHAR(13) + CHAR(10)
declare @testname varchar(max),@testDescription varchar(max), @if_measure char(1), @if_result char(1), @row int = '1', @id int
set @LogEntry = (SELECT REPLACE(@LogEntry,@crlf,','))
declare @name varchar(max),@description varchar(MAX), @measure varchar(20), @result char(1)
declare @Output table(OutTestName varchar(max),OUTTestDescription varchar(max), OutMeasure varchar(50), OutResult varchar(50))
declare @maximum int = (select MAX(ID) from dbo.template_FMT)
declare @LogEntry1 as nvarchar(max)
declare @LogEntry2 as nvarchar(max)
while @row <= @maximum
BEGIN
set @name = null
set @description = null
set @measure = null
set @result = null
set @testname = (select Name from dbo.template_FMT where ID = @row)
set @testDescription = (select TestDescription from dbo.template_FMT where ID = @row)
set @if_measure = (select Measure from dbo.template_FMT where ID = @row)
set @if_result = (select Result from dbo.template_FMT where ID = @row)
set @id = (select ID from dbo.Split(@LogEntry, ',') where Data = @testname)
SELECT @LogEntry1 = Name FROM dbo.template_FMT where id = @row
set @name = @LogEntry1
SELECT @LogEntry2 = TestDescription FROM dbo.template_FMT where id = @row
set @description = @LogEntry2
if @if_measure > 0 and @if_result > 0
begin
set @measure = (select Data from dbo.Split(@LogEntry, ',') where ID = @id+4)
set @result = (select Data from dbo.Split(@LogEntry, ',') where ID = @id+8)
insert into @Output (OutTestName, OUTTestDescription, OutMeasure, OutResult) Values(@name,@description, @measure, @result)
end
if @if_measure > 0 and @if_result = 0
begin
set @measure = (select Data from dbo.Split(@LogEntry, ',') where ID = @id+4)
set @result = null
insert into @Output (OutTestName, OUTTestDescription, OutMeasure, OutResult) Values(@name,@description, @measure, @result)
end
if @if_measure = 0 and @if_result > 0
begin
set @measure = null
set @result = (select Data from dbo.Split(@LogEntry, ',') where ID = @id+4)
insert into @Output (OutTestName, OUTTestDescription, OutMeasure, OutResult) Values(@name,@description, @measure, @result)
end
set @row = @row + 1
END
select * from @Output
的行的描述为Error
,它会返回最后记住的值而不是
Error
我明白了:
CAL_MCU Total version reading 05 NULL
Error Error 9.8499985089315E-07 NULL
CAL_EEPROM Total version reading 05 1
如果您有任何建议,我想将CAL_MCU Total version reading 05 NULL
Error Error 05 NULL
CAL_EEPROM Total version reading 05 1
存储到变量中:)
附:我认为这与Error cant find Result with ID
和name
具有相同名称(description
)
答案 0 :(得分:1)
我相信您的问题可以在不需要while循环和字符串拆分功能的情况下解决。我建议使用OPENROWSET函数将原始数据文件作为标准表读取。然后,您可以使用标准T-SQL查询将结果格式化为所需的输出。 第一步是确保在服务器上启用即席查询,这可以通过执行以下命令来完成。
sp_configure 'show advanced options', 1;
RECONFIGURE;
GO
sp_configure 'Ad Hoc Distributed Queries', 1;
RECONFIGURE;
下一步是为文本文件定义格式文件。这将有助于SQL Server在加载原始数据时理解文本文件结构。根据提供的示例数据,您的格式文件应如下所示:
10.0
4
1 SQLCHAR 0 100 "," 1 Col1 SQL_Latin1_General_CP1_CI_AS
2 SQLCHAR 0 100 "," 2 Col2 SQL_Latin1_General_CP1_CI_AS
3 SQLCHAR 0 100 "," 3 Col3 SQL_Latin1_General_CP1_CI_AS
4 SQLCHAR 0 100 "\r\n" 4 Col4 SQL_Latin1_General_CP1_CI_AS
我上传了以下链接中用于测试示例的格式文件和示例原始数据文件:
http://www.filedropper.com/format
http://www.filedropper.com/rawdatafile
最后一步是运行OPENROWSET查询以加载文件数据并将数据转换为所需的输出。如果您使用的是SQL Server 2008 r2,则以下查询应该有效:
-- 2008 R2 Version
WITH CTE_VariableRawData
AS
(
SELECT ROW_NUMBER() OVER(ORDER BY (SELECT 0)) AS ID
,[RawData].Col1 AS [VariableOrMeasure]
,(
CASE [RawData].Col4
WHEN '(Result)' THEN 0
WHEN '(Measure)' THEN 0
ELSE 1
END
) AS IsVariable
,(
CASE [RawData].Col4
WHEN '(Result)' THEN 1
ELSE 0
END
) AS IsResult
,(
CASE [RawData].Col4
WHEN '(Measure)' THEN 1
ELSE 0
END
) AS IsMeasure
,[RawData].Col4 AS [Description]
FROM OPENROWSET(BULK N'C:\temp\raw_data_file.txt', FORMATFILE = 'c:\temp\format.txt') AS [RawData]
)
,
CTE_RawDataByVariableID
AS
(
SELECT ID
,(
SELECT SUM([IsVariable])
FROM CTE_VariableRawData RunningTotal
WHERE RunningTotal.ID <= CTE_VariableRawData.ID
) AS VariableID
,[VariableOrMeasure]
,[IsVariable]
,[IsResult]
,[IsMeasure]
,[Description]
FROM CTE_VariableRawData
)
SELECT VariableID
,MAX(
CASE [IsVariable]
WHEN 1 THEN [VariableOrMeasure]
ELSE NULL
END
) AS [Variable]
,MAX(
CASE [IsVariable]
WHEN 1 THEN [Description]
ELSE NULL
END
) AS [Description]
,MAX(
CASE [IsMeasure]
WHEN 1 THEN [VariableOrMeasure]
ELSE NULL
END
) AS [Measure]
,MAX(
CASE [IsResult]
WHEN 1 THEN [VariableOrMeasure]
ELSE NULL
END
) AS [Result]
FROM CTE_RawDataByVariableID
GROUP BY VariableID
ORDER BY VariableID
如果您使用的是SQL Server 2012或更高版本,则以下查询将更加优化:
WITH CTE_VariableRawData
AS
(
SELECT ROW_NUMBER() OVER(ORDER BY (SELECT 0)) AS ID
,[RawData].Col1 AS [VariableOrMeasure]
,(
CASE [RawData].Col4
WHEN '(Result)' THEN 0
WHEN '(Measure)' THEN 0
ELSE 1
END
) AS IsVariable
,(
CASE [RawData].Col4
WHEN '(Result)' THEN 1
ELSE 0
END
) AS IsResult
,(
CASE [RawData].Col4
WHEN '(Measure)' THEN 1
ELSE 0
END
) AS IsMeasure
,[RawData].Col4 AS [Description]
FROM OPENROWSET(BULK N'C:\temp\raw_data_file.txt', FORMATFILE = 'c:\temp\format.txt') AS [RawData]
)
,
CTE_RawDataByVariableID
AS
(
SELECT ID
,SUM([IsVariable]) OVER (ORDER BY ID) AS VariableID
,[VariableOrMeasure]
,[IsVariable]
,[IsResult]
,[IsMeasure]
,[Description]
FROM CTE_VariableRawData
)
SELECT VariableID
,MAX(
CASE [IsVariable]
WHEN 1 THEN [VariableOrMeasure]
ELSE NULL
END
) AS [Variable]
,MAX(
CASE [IsVariable]
WHEN 1 THEN [Description]
ELSE NULL
END
) AS [Description]
,MAX(
CASE [IsMeasure]
WHEN 1 THEN [VariableOrMeasure]
ELSE NULL
END
) AS [Measure]
,MAX(
CASE [IsResult]
WHEN 1 THEN [VariableOrMeasure]
ELSE NULL
END
) AS [Result]
FROM CTE_RawDataByVariableID
GROUP BY VariableID
ORDER BY VariableID;
请注意,在两个查询中,您都必须将原始数据文件的位置和格式文件更改为OPENROWSET(BULK N'C:\temp\raw_data_file.txt', FORMATFILE = 'c:\temp\format.txt')
调用中的所需位置。