【问题标题】:BCP / sqlcmd / osql with encapsulated text fields?带有封装文本字段的 BCP / sqlcmd / osql?
【发布时间】:2012-03-13 09:49:18
【问题描述】:

这些命令行工具中的任何一个都可以导出到 .csv,例如:

"int_field", "varchar_field", "another_int_field"
10, "some text", 10
5, "more text", 1

等等?

我不想使用视图或存储过程来破解 :) 中的双引号

【问题讨论】:

  • 您是否也想在某些 int 字段周围使用“”?或者“int_field”只是一些你想要引号的文本?
  • 抱歉 - 格式不正确。第一行是列标题(我想它们都会被引用,因为它们都是字符串)
  • 你能用 C# 或其他东西写代码吗?据我所知,没有标准的命令行工具,但写起来很容易
  • @Jaques 我正朝着那条路前进——但令我惊讶的是,没有任何工具能够做到这一点(重新发明轮子弹簧)

标签: sql sql-server bcp sqlcmd osql


【解决方案1】:

执行此操作的内置工具是 SSIS,尽管我很欣赏它可能是一个比您想要的“更重”的解决方案,并且它在 Express Edition 中不完全支持(您没有提到您的版本或版本'正在使用)。您可以在包中的flat file connection manager 中定义文本限定符。

或者,用您喜欢的脚本语言编写一个小脚本。

【讨论】:

  • 对SSIS不太熟悉,能不先创建包就执行查询导出到文本文件吗?
  • 不,SSIS 是基于包的,因此您无法避免创建一个。就个人而言,如果我不能使用 SSIS,那么我会使用已经支持 CSV 库的语言(如 Perl 或 Python),因为它比最初编写 CSV 文件似乎更难。例如,您的代码似乎无法处理字符串包含引号的情况。
【解决方案2】:

我很快就完成了。如果你知道 c#,你可以添加它,否则它可能会没用。不是我最好的代码,但它正在完成这项工作。这里没有添加所有的字段类型,所以需要添加。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.IO;

namespace SQLCSVExport
{
    class Program
    {
        static void Main(string[] args)
        {
            bool trustedConn = false;
            string Servername = "";
            string Username = "";
            string Password = "";
            bool quotestring = false;
            string fieldterminater = ",";
            string tablename = "";
            string operation = "";
            string datafile = "";
            bool includeheadings = false;

            if (args.Length < 3)
            {
                ShowOptions();
                return;
            }
            else
            {
                tablename = args[0];
                operation = args[1];
                datafile = args[2];
                for (int i = 3; i < args.Length; i++)
                {
                    switch (args[i].Substring(0, 2))
                    {
                        case "-Q":
                            quotestring = true;
                            break;
                        case "-T":
                            trustedConn = true;
                            break;
                        case "-S":
                            Servername = args[i].Substring(2);
                            break;
                        case "-U":
                            Username = args[i].Substring(2);
                            break;
                        case "-P":
                            Password = args[i].Substring(2);
                            break;
                        case "-t":
                            fieldterminater = args[i].Substring(2);
                            break;
                        case "-H":
                            includeheadings = true;
                            break;
                    }
                }
            }
            SqlConnection conn;

            if(File.Exists(datafile))
            {
                try
                {
                    File.Delete(datafile);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    ShowOptions();
                    return;
                }
            }
            if (trustedConn)
                conn = new SqlConnection("Integrated Security=True;Initial Catalog=master;Data Source=" + Servername);
            else
                conn = new SqlConnection("Password=" + Password + ";Persist Security Info=True;User ID=" + Username + ";Initial Catalog=master;Data Source=" + Servername);
            try
            {
                conn.Open();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                ShowOptions();
                return;
            }
            SqlCommand cmd = new SqlCommand();
            SqlDataReader read = null;
            cmd.Connection = conn;
            if (operation == "out")
                cmd.CommandText = "Select * from " + tablename;
            else
                cmd.CommandText = tablename;
            try
            {
                read = cmd.ExecuteReader();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                ShowOptions();
                return;
            }
            string Dummy = "";
            if (read.HasRows)
            {
                if(includeheadings)
                {
                    for (int i = 0; i < read.FieldCount; i++)
                    {
                        if (quotestring)
                            Dummy += "\"" + read.GetName(i) + "\"" + fieldterminater;
                        else
                            Dummy += read.GetName(i) + fieldterminater;
                    }
                    WriteStrToFile(datafile, Dummy, fieldterminater);
                }
                while (read.Read())
                {
                    Dummy = "";
                    for (int i = 0; i < read.FieldCount; i++)
                    {
                        switch (read[i].GetType().ToString())
                        {
                            case "System.Int32":
                                Dummy += read[i].ToString() + fieldterminater;
                                break;
                            case "System.String":
                                if (quotestring)
                                    Dummy += "\"" + read[i].ToString() + "\"" + fieldterminater;
                                else
                                    Dummy += read[i].ToString() + fieldterminater;
                                break;
                            case "System.DBNull":
                                Dummy += fieldterminater;
                                break;
                            default:
                                break;
                        }
                    }
                    WriteStrToFile(datafile, Dummy, fieldterminater);
                }
            }
        }

        static void WriteStrToFile(string datafile, string dummy, string fieldterminator)
        {
            FileStream fs = new FileStream(datafile, FileMode.Append, FileAccess.Write);
            StreamWriter sr = new StreamWriter(fs);
            if (dummy.Trim().Substring(dummy.Trim().Length - 1) == fieldterminator)
                dummy = dummy.Substring(0, dummy.Trim().Length - 1);
            sr.WriteLine(dummy);
            sr.Close();
            fs.Close();
            sr.Dispose();
            fs.Dispose();
        }

        static void ShowOptions()
        {
            Console.WriteLine("usage: SQLCSVExport {dbtable | query} {out | queryout} datafile");
            Console.WriteLine("[-q quote string fields]         [-S Server Name]        [-U User Name]");
            Console.WriteLine("[-P Password]                    [-T Trusted Connection] [-t field terminator]");
            Console.WriteLine("[-H Add Headings]");
        }
    }
}

【讨论】:

    【解决方案3】:

    看起来这证实了我的猜测,答案是:

    没有。

    感谢其他建议。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-07
      • 1970-01-01
      • 1970-01-01
      • 2014-08-12
      相关资源
      最近更新 更多