从SQL批量插入中排除内容

时间:2012-08-03 21:49:20

标签: sql-server-2008 bulkinsert

我想将我的IIS日志导入SQL以使用批量插入进行报告,但注释行 - 以#开头的那些 - 会导致问题,因为这些行与数据行的字段数不同。

如果我手动删除了评论,我可以执行批量插入。

有没有办法在根据匹配排除行时执行批量插入,例如:任何带有“#”的行。

感谢。

4 个答案:

答案 0 :(得分:2)

我通常与BULK INSERT和不规则数据一起使用的方法是将传入的数据推送到具有单个VARCHAR(MAX)列的临时临时表中。

一旦进入,我可以使用更灵活的决策工具,如SQL查询和字符串函数来决定我要从登台表中选择哪些行并将其带入我的主表。这也很有用,因为BULK INSERT可能会对于为什么以及如何在特定文件上失败而感到非常神秘。

我能想到的唯一其他选择是在进行批量插入之前使用预上传脚本修剪评论和其他不符合表格标准的行。

答案 1 :(得分:1)

我建议改用logparser.exe。 LogParser有一些非常neat capabilities on its own,但它也可用于格式化IIS日志,以便SQL Server正确导入。

答案 2 :(得分:0)

Microsoft有一个名为“PrepWebLog”http://support.microsoft.com/kb/296093的工具 - 它会剥离这些哈希/磅字符,但是我现在正在运行它(使用PowerShell脚本存储多个文件)并且发现它的性能无法缓慢

我认为如果我写一个C#程序(或者甚至是一个宏)会更快。


更新:PrepWebLog刚刚崩溃了。我会避免它。


更新#2,我查看了PowerShell的Get-Content和Set-Content命令,但不喜欢语法和可能的性能。所以我写了这个小C#控制台应用程序:

        if (args.Length == 2)
        {
            string path = args[0];
            string outPath = args[1];

            Regex hashString = new Regex("^#.+\r\n", RegexOptions.Multiline | RegexOptions.Compiled);
            foreach (string file in Directory.GetFiles(path, "*.log"))
            {
                string data;
                using (StreamReader sr = new StreamReader(file))
                {
                    data = sr.ReadToEnd();
                }

                string output = hashString.Replace(data, string.Empty);
                using (StreamWriter sw = new StreamWriter(Path.Combine(outPath, new FileInfo(file).Name), false))
                {
                    sw.Write(output);
                }
            }
        }
        else
        {
            Console.WriteLine("Source and Destination Log Path required or too many arguments");
        }

这很快。


答案 3 :(得分:0)

跟进PeterX写的内容,我修改了应用程序以处理大型日志文件,因为任何足够大的内容都会产生内存不足的异常。另外,由于我们只关心一行的第一个字符是否以散列开头,我们可以在读取操作中使用StartsWith()方法。

class Program
{
    static void Main(string[] args)
    {
        if (args.Length == 2)
        {
            string path = args[0];
            string outPath = args[1];
            string line;

            foreach (string file in Directory.GetFiles(path, "*.log"))
            {
                using (StreamReader sr = new StreamReader(file))
                {
                    using (StreamWriter sw = new StreamWriter(Path.Combine(outPath, new FileInfo(file).Name), false))
                    {
                        while ((line = sr.ReadLine()) != null)
                        {
                            if(!line.StartsWith("#"))
                            {
                                sw.WriteLine(line);
                            }
                        }                          
                    }
                }

            }
        }
        else
        {
            Console.WriteLine("Source and Destination Log Path required or too many arguments");
        }
    }
}