/*
*** DO NOT USE IN PRODUCTION -- TESTING / DEMONSTRATION CODE ONLY ***
This script relates to the following SQL Server Central Forum topic:
Processing strings ( https://www.sqlservercentral.com/forums/topic/processing-strings )
*** DO NOT USE IN PRODUCTION -- TESTING / DEMONSTRATION CODE ONLY ***
This script provides the .NET / C# source code for the [ParseCSV] SQLCLR Stored Procedure.
*** DO NOT USE IN PRODUCTION -- TESTING / DEMONSTRATION CODE ONLY ***
A T-SQL installation script (no external DLL) containing only two Stored Procedures is located at:
https://pastebin.com/aqsWiX1e
*** DO NOT USE IN PRODUCTION -- TESTING / DEMONSTRATION CODE ONLY ***
A T-SQL script containing tests for the [ParseCSV] SQLCLR Stored Procedure is located at:
https://pastebin.com/WGDkQTxt
*** DO NOT USE IN PRODUCTION -- TESTING / DEMONSTRATION CODE ONLY ***
Date: 2016-04-11
Version: 1.0.0
For more functions like this, please visit: https://SQLsharp.com
Stairway to SQLCLR series: https://www.sqlservercentral.com/stairways/stairway-to-sqlclr
Copyright (c) 2016 Sql Quantum Leap. All rights reserved.
https://SqlQuantumLeap.com
*/
using System;
using System.Data.SqlTypes;
using System.IO;
using Microsoft.SqlServer.Server;
using Microsoft.VisualBasic.FileIO;
public class CSVUtils
{
[SqlProcedure()]
public static SqlInt32 ParseCSV(
[SqlFacet(MaxSize = 1)] SqlString Delimiter,
[SqlFacet(MaxSize = -1)] SqlString InputString,
[SqlFacet(MaxSize = 500)] SqlString FilePath)
{
if (Delimiter.IsNull)
{
return 1;
}
if (!FilePath.IsNull && !FilePath.Value.Trim().Equals(string.Empty))
{
using (TextFieldParser _CSV = new TextFieldParser(FilePath.Value))
{
ParseStuff(_CSV, Delimiter.Value);
}
}
else
{
if (InputString.IsNull || InputString.Value.Trim().Equals(string.Empty))
{
return 0;
}
using (StringReader _Reader = new StringReader(InputString.Value))
{
using (TextFieldParser _CSV = new TextFieldParser(_Reader))
{
ParseStuff(_CSV, Delimiter.Value);
}
}
}
return 0;
}
private static void ParseStuff(TextFieldParser CSV, string Delimiter)
{
bool _IsResultSchemaSet = false;
SqlDataRecord _ResultSet = null;
int _FieldCount = 0;
CSV.SetDelimiters(Delimiter); // this also sets TextFieldType = FieldType.Delimited;
CSV.HasFieldsEnclosedInQuotes = true;
string[] _Fields;
while (!CSV.EndOfData)
{
_Fields = CSV.ReadFields();
if (!_IsResultSchemaSet)
{
_FieldCount = _Fields.Length;
SqlMetaData[] _TempStructure = new SqlMetaData[_FieldCount];
for (int _Index = 0; _Index < _FieldCount; _Index++)
{
_TempStructure[_Index] = new SqlMetaData(string.Format("Field{0:D3}", _Index + 1),
System.Data.SqlDbType.NVarChar, SqlMetaData.Max);
}
_ResultSet = new SqlDataRecord(_TempStructure);
SqlContext.Pipe.SendResultsStart(_ResultSet);
_IsResultSchemaSet = true;
}
_ResultSet.SetValues(_Fields);
if (_Fields.Length < _FieldCount)
{
for (int _Index = _Fields.Length; _Index < _FieldCount; _Index++)
{
_ResultSet.SetDBNull(_Index);
}
}
SqlContext.Pipe.SendResultsRow(_ResultSet);
}
SqlContext.Pipe.SendResultsEnd();
return;
}
[SqlProcedure]
public static void GarbageCollect()
{
GC.Collect();
return;
}
}
Comments