Hi Jeff,
First of all, Happy New Year! Out here it still 21:55... Hope you are having a great time with your family!
Based on the first file you created for me (treating the header), I made some changes (including the path) for using the real file (atached). When I run "EXEC dbo.GetFileType01 'C:\temp\sm\urso47Test02.csv'" (the real file now is "02"), I get the error message:
Msg 50000, Level 18, State 1, Procedure GetFileType01, Line 123
ERROR:[GetFileType01]Incorrect header for file C:\temp\sm\urso47Test02.csv
Acording with CTRL+G = 123, the error is somewhere out here:
RAISERROR('ERROR:[%s]Incorrect header for file %s',18,1,@ProcName,@pFullPath);
Maybe one critical change I did should be replacing ":" by "." because I don't have the colon sign at the first header line:
WHEN RowNum = 1 AND LineData LIKE '[#Lista Estat].%'
THEN LTRIM(RTRIM(SUBSTRING(LineData,CHARINDEX('.',LineData)+1,8000)))
I didn't make any changes in the formatfile. Here goes the statement changed:
CREATE PROCEDURE dbo.GetFileType01
/**********************************************************************************************************************
Purpose:
Give a full path/filename/extension, load the file according to the specs for "FileType01".
Usage Example:
EXEC dbo.GetFileType01 'C:\Temp\urso47Test01.txt'
Dependencies:
1. The related "BCP Format File" (RawData8000.fmt) must be located in "C:\Temp".
Obviously, you can change that.
2. The dbo.DelimitedSplitFunction must exist in the same database as this stored procedure.
It carries its own documentation
Programmers Notes:
1. Some minor error checking with the file is done. You can easily enhance the simple error checking to be full
validation, at some point.
Revision History
Rev 00 - 16 Dec 2012 - Jeff Moden - Initial creation/test
Ref - http://www.sqlservercentral.com/Forums/Topic1396968-1292-1.aspx
**********************************************************************************************************************/
--===== Declare the input parameters for this stored procedure
@pFullPath VARCHAR(500)
AS
--=====================================================================================================================
-- Presets
--=====================================================================================================================
--===== Setup the environment just to be sure
SET NOCOUNT ON;
SET DATEFORMAT MDY;
--===== Create the staging table for the raw data
CREATE TABLE #RawData
(
RowNum INT IDENTITY(1,1),
LineData VARCHAR(8000)
)
;
--===== Create some obviously named variables
DECLARE @ProcName VARCHAR(128),
@RowCount INT,
@SQL VARCHAR(8000)
;
--===== Preset variables with constants
SELECT @ProcName = OBJECT_NAME(@@PROCID),
@SQL = REPLACE('
BULK INSERT #RawData
FROM ''<<@pFullPath>>''
WITH (
BATCHSIZE = 2000000000,
CODEPAGE = ''RAW'',
DATAFILETYPE = ''char'',
--ERRORFILE = ''<<@pFullPath>>'', --Uncomment this line if you want to capture error rows
FIELDTERMINATOR = ''\t'',
FORMATFILE = ''C:\Temp\sm\RawData8000.fmt'',
MAXERRORS = 2000000000,
ROWTERMINATOR = '''',
TABLOCK
);'
,'<<@pFullPath>>',@pFullPath)
;
--===== Load the file for parsing using the format file
EXEC (@SQL)
;
--===== Parse and save the header information using a "CROSSTAB" to pivot the data
SELECT [#Lista Estat] =
MAX(
CASE
WHEN RowNum = 1 AND LineData LIKE '[#Lista Estat].%'
THEN LTRIM(RTRIM(SUBSTRING(LineData,CHARINDEX('.',LineData)+1,8000)))
ELSE ''
END
),
[#Format Version] =
MAX(
CASE
WHEN RowNum = 2 AND LineData LIKE '[Format Version]:%'
THEN LTRIM(RTRIM(SUBSTRING(LineData,CHARINDEX(':',LineData)+1,8000)))
ELSE ''
END
),
[#Data Obtida] =
CAST(MAX(
CASE
WHEN RowNum = 3 AND LineData LIKE '[#Data Obtida]:%'
THEN LTRIM(RTRIM(SUBSTRING(LineData,CHARINDEX(':',LineData)+1,8000)))
ELSE ''
END
) AS DATETIME),
[#Nome do Disposit.] =
MAX(
CASE
WHEN RowNum = 4 AND LineData LIKE '[#Nome do Disposit.]:%'
THEN LTRIM(RTRIM(SUBSTRING(LineData,CHARINDEX(':',LineData)+1,8000)))
ELSE ''
END
),
[#Endereço] =
MAX(
CASE
WHEN RowNum = 5 AND LineData LIKE '[#Endereço]:%'
THEN LTRIM(RTRIM(SUBSTRING(LineData,CHARINDEX(':',LineData)+1,8000)))
ELSE ''
END
)
INTO #Header
FROM #RawData
WHERE RowNum BETWEEN 1 AND 5
;
--===== Check to make sure the header was loaded correctly.
-- Raise an error and exit if it wasn't
SELECT @RowCount = COUNT(*)
FROM #Header
WHERE [#Lista Estat]> '' --Is Not Blank or NULL
AND [#Format Version]> '' --Is Not Blank or NULL
AND [#Data Obtida]> '1900' --Wasn't an "empty" date (and assumes no dates before 1900-01-01)
AND [#Nome do Disposit.]> '' --Is Not Blank or NULL
AND [#Endereço]> '' --Is Not Blank or NULL
;
IF @RowCount <> 1
BEGIN
RAISERROR('ERROR:[%s]Incorrect header for file %s',18,1,@ProcName,@pFullPath);
RETURN;
END
;
--===== Check to make sure the detail header is at row 7.
-- Raise an error and exit if it isn't.
IF NOT EXISTS (SELECT 1 FROM #RawData WHERE RowNum = 7 AND LineData = '[#Utilizador],[Nome],[Tot. de Impressões],[P & B(Tot. de Impressões)],[Cor(Tot. de Impressões)],[P & B: Resultado(Tot. de Impressões)],[Cor: Resultado(Tot. de Impressões)],[Total de Preto e branco(Copidora/Servidor de Documentos)],[Preto e branco(Formato pequeno)(Copidora/Servidor de Documentos)],[Preto e branco(Formato grande)(Copidora/Servidor de Documentos)],[Total de Uma cor(Copidora/Servidor de Documentos)],[Cor Única(Formato pequeno)(Copidora/Servidor de Documentos)],[Cor Única(Formato grande)(Copidora/Servidor de Documentos)],[Total de Duas cores(Copidora/Servidor de Documentos)],[Duas cores(Formato pequeno)(Copidora/Servidor de Documentos)],[Duas cores(Formato grande)(Copidora/Servidor de Documentos)],[Total de Cor integral(Copidora/Servidor de Documentos)],[Cor Integral(Formato pequeno)(Copidora/Servidor de Documentos)],[Cor Integral(Formato grande)(Copidora/Servidor de Documentos)],[Total de Preto e branco(Impressora)],[Preto e branco(Formato pequeno)(Impressora)],[Preto e branco(Formato grande)(Impressora)],[Total de Uma cor(Impressora)],[Cor Única(Formato pequeno)(Impressora)],[Cor Única(Formato grande)(Impressora)],[Total de Duas cores(Impressora)],[Duas cores(Formato pequeno)(Impressora)],[Duas cores(Formato grande)(Impressora)],[Total a Cores(Impressora)],[Cor(Formato pequeno)(Impressora)],[Cor(Formato grande)(Impressora)],[Total de Scanner(Scanner)],[Total de Preto e branco(Scanner)],[Preto e branco(Formato pequeno)(Scanner)],[Preto e branco(Formato grande)(Scanner)],[Total a Cores(Scanner)],[Cor(Formato pequeno)(Scanner)],[Cor(Formato grande)(Scanner)],[Total de Preto e branco(Fax)],[Preto e branco(Formato pequeno)(Fax)],[Preto e branco(Formato grande)(Fax)],[Total a Cores(Fax)],[Cor(Formato pequeno)(Fax)],[Cor(Formato grande)(Fax)],[Transmissão(Fax)],[Custos(Fax)],[Volume utilizado(Limitação de volumes de utilização para impressão)],[Valor limite(Limitação de volumes de utilização para impressão)]
')
BEGIN
RAISERROR('ERROR:[%s] Misplaced detail-header for file %s',16,1,@ProcName, @pFullPath);
RETURN;
END
;
--===== Load and return the detail rows 114
SELECT [#Lista Estat] = MAX(hdr.[#Lista Estat]),
[#Format Version] = MAX(hdr.[#Format Version]),
[#Data Obtida] = MAX(hdr.[#Data Obtida]),
[#Nome do Disposit.] = MAX(hdr.[#Nome do Disposit.]),
[#Endereço] = MAX(hdr.[#Endereço]),
[#Utilizador] = MAX(CAST(CASE WHEN split.ItemNumber = 1THEN Item ELSE '' END AS VARCHAR(10))),
[Nome] = MAX(CAST(CASE WHEN split.ItemNumber = 2THEN Item ELSE '' END AS VARCHAR(10))),
[Tot. de Impressões] = MAX(CAST(CASE WHEN split.ItemNumber = 3THEN Item ELSE '' END AS INT)),
[P & B(Tot. de Impressões)] = MAX(CAST(CASE WHEN split.ItemNumber = 4THEN Item ELSE '' END AS INT)),
[Cor(Tot. de Impressões)] = MAX(CAST(CASE WHEN split.ItemNumber = 5THEN Item ELSE '' END AS INT)),
[P & B: Resultado(Tot. de Impressões)] = MAX(CAST(CASE WHEN split.ItemNumber = 6THEN Item ELSE '' END AS INT)),
[Cor: Resultado(Tot. de Impressões)] = MAX(CAST(CASE WHEN split.ItemNumber = 7THEN Item ELSE '' END AS INT)),
[Total de Preto e branco(Copidora/Servidor de Documentos)] = MAX(CAST(CASE WHEN split.ItemNumber = 8THEN Item ELSE '' END AS INT)),
[Preto e branco(Formato pequeno)(Copidora/Servidor de Documentos)] = MAX(CAST(CASE WHEN split.ItemNumber = 9THEN Item ELSE '' END AS INT)),
[Preto e branco(Formato grande)(Copidora/Servidor de Documentos)] = MAX(CAST(CASE WHEN split.ItemNumber = 10THEN Item ELSE '' END AS INT)),
[Total de Uma cor(Copidora/Servidor de Documentos)] = MAX(CAST(CASE WHEN split.ItemNumber = 11THEN Item ELSE '' END AS INT)),
[Cor Única(Formato pequeno)(Copidora/Servidor de Documentos)] = MAX(CAST(CASE WHEN split.ItemNumber = 12THEN Item ELSE '' END AS INT)),
[Cor Única(Formato grande)(Copidora/Servidor de Documentos)] = MAX(CAST(CASE WHEN split.ItemNumber = 13THEN Item ELSE '' END AS INT)),
[Total de Duas cores(Copidora/Servidor de Documentos)] = MAX(CAST(CASE WHEN split.ItemNumber = 14THEN Item ELSE '' END AS INT)),
[Duas cores(Formato pequeno)(Copidora/Servidor de Documentos)] = MAX(CAST(CASE WHEN split.ItemNumber = 15THEN Item ELSE '' END AS INT)),
[Duas cores(Formato grande)(Copidora/Servidor de Documentos)] = MAX(CAST(CASE WHEN split.ItemNumber = 16THEN Item ELSE '' END AS INT)),
[Total de Cor integral(Copidora/Servidor de Documentos)] = MAX(CAST(CASE WHEN split.ItemNumber = 17 THEN Item ELSE '' END AS INT)),
[Cor Integral(Formato pequeno)(Copidora/Servidor de Documentos)] = MAX(CAST(CASE WHEN split.ItemNumber = 18THEN Item ELSE '' END AS INT)),
[Cor Integral(Formato grande)(Copidora/Servidor de Documentos)] = MAX(CAST(CASE WHEN split.ItemNumber = 19THEN Item ELSE '' END AS INT)),
[Total de Preto e branco(Impressora)] = MAX(CAST(CASE WHEN split.ItemNumber = 20THEN Item ELSE '' END AS INT)),
[Preto e branco(Formato pequeno)(Impressora)] = MAX(CAST(CASE WHEN split.ItemNumber = 21THEN Item ELSE '' END AS INT)),
[Preto e branco(Formato grande)(Impressora)] = MAX(CAST(CASE WHEN split.ItemNumber = 22THEN Item ELSE '' END AS INT)),
[Total de Uma cor(Impressora)] = MAX(CAST(CASE WHEN split.ItemNumber = 23THEN Item ELSE '' END AS INT)),
[Cor Única(Formato pequeno)(Impressora)] = MAX(CAST(CASE WHEN split.ItemNumber = 24THEN Item ELSE '' END AS INT)),
[Cor Única(Formato grande)(Impressora)] = MAX(CAST(CASE WHEN split.ItemNumber = 25THEN Item ELSE '' END AS INT)),
[Total de Duas cores(Impressora)] = MAX(CAST(CASE WHEN split.ItemNumber = 26THEN Item ELSE '' END AS INT)),
[Duas cores(Formato pequeno)(Impressora)] = MAX(CAST(CASE WHEN split.ItemNumber = 27THEN Item ELSE '' END AS INT)),
[Duas cores(Formato grande)(Impressora)] = MAX(CAST(CASE WHEN split.ItemNumber = 28THEN Item ELSE '' END AS INT)),
[Total a Cores(Impressora)] = MAX(CAST(CASE WHEN split.ItemNumber = 29THEN Item ELSE '' END AS INT)),
[Cor(Formato pequeno)(Impressora)] = MAX(CAST(CASE WHEN split.ItemNumber = 30THEN Item ELSE '' END AS INT)),
[Cor(Formato grande)(Impressora)] = MAX(CAST(CASE WHEN split.ItemNumber = 31THEN Item ELSE '' END AS INT)),
[Total de Scanner(Scanner)] = MAX(CAST(CASE WHEN split.ItemNumber = 32THEN Item ELSE '' END AS INT)),
[Total de Preto e branco(Scanner)] = MAX(CAST(CASE WHEN split.ItemNumber = 33THEN Item ELSE '' END AS INT)),
[Preto e branco(Formato pequeno)(Scanner)] = MAX(CAST(CASE WHEN split.ItemNumber = 34THEN Item ELSE '' END AS INT)),
[Preto e branco(Formato grande)(Scanner)] = MAX(CAST(CASE WHEN split.ItemNumber = 35THEN Item ELSE '' END AS INT)),
[Total a Cores(Scanner)] = MAX(CAST(CASE WHEN split.ItemNumber = 36THEN Item ELSE '' END AS INT)),
[Cor(Formato pequeno)(Scanner)] = MAX(CAST(CASE WHEN split.ItemNumber = 37THEN Item ELSE '' END AS INT)),
[Cor(Formato grande)(Scanner)] = MAX(CAST(CASE WHEN split.ItemNumber = 38THEN Item ELSE '' END AS INT)),
[Total de Preto e branco(Fax)] = MAX(CAST(CASE WHEN split.ItemNumber = 39THEN Item ELSE '' END AS INT)),
[Preto e branco(Formato pequeno)(Fax)] = MAX(CAST(CASE WHEN split.ItemNumber = 40THEN Item ELSE '' END AS INT)),
[Preto e branco(Formato grande)(Fax)] = MAX(CAST(CASE WHEN split.ItemNumber = 41THEN Item ELSE '' END AS INT)),
[Total a Cores(Fax)] = MAX(CAST(CASE WHEN split.ItemNumber = 42THEN Item ELSE '' END AS INT)),
[Cor(Formato pequeno)(Fax)] = MAX(CAST(CASE WHEN split.ItemNumber = 43THEN Item ELSE '' END AS INT)),
[Cor(Formato grande)(Fax)] = MAX(CAST(CASE WHEN split.ItemNumber = 44THEN Item ELSE '' END AS INT)),
[Transmissão(Fax)] = MAX(CAST(CASE WHEN split.ItemNumber = 45THEN Item ELSE '' END AS INT)),
[Custos(Fax)] = MAX(CAST(CASE WHEN split.ItemNumber = 46THEN Item ELSE '' END AS INT)),
[Volume utilizado(Limitação de volumes de utilização para impressão)] = MAX(CAST(CASE WHEN split.ItemNumber = 47THEN Item ELSE '' END AS INT)),
[Valor limite(Limitação de volumes de utilização para impressão)] = MAX(CAST(CASE WHEN split.ItemNumber = 48THEN Item ELSE '' END AS INT))
FROM #RawData rd
CROSS JOIN #Header hdr --There's only one header so this works
CROSS APPLY ( --=== This parses the CSV in each row and removes the braces (every kid's dream ;-))
SELECT ItemNumber,
Item = REPLACE(REPLACE(Item,'[','') ,']','')
FROM dbo.DelimitedSplit8K(LineData,',')
) split
WHERE rd.RowNum > 7 --Data header is at row 7
AND LEN(LineData) > 1 --Gets rid of blank rows
GROUP BY rd.RowNum --Completes the pivot
;
GO
By the way for my level, this script is hard to understand, what level is this in the SQL world?
Thanks again!