• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

用c#中实现的,调用cmd来执行bcp

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

引用空间:
using System;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
private void Page_Load(object sender, System.EventArgs e)
        {
            // 在此处放置用户代码以初始化页面
            string Conn = "data source=192.168.0.1;initial catalog=Test;user

id=sa;password=1";
            SqlConnection sqlConn = new SqlConnection(Conn);
            SqlCommand cmd = new SqlCommand();
            cmd.Connection = sqlConn;
            SqlDataAdapter sda = new SqlDataAdapter(cmd);
            sqlConn.Open();
            cmd.CommandText = "Select * from Files";
            DataSet ds = new DataSet();
            sda.Fill(ds);

            if(ds.Tables[0].Rows.Count>0)
            {
                string BcpExec = "";
                for(int i=0;i<ds.Tables[0].Rows.Count;i++)//循环取本地文件名
                {           
                    BcpExec = @"bcp Test..Data in D:\test\";
                    BcpExec += ds.Tables[0].Rows[i]["path"].ToString();
                    BcpExec += " -S192.168.0.1 -Usa -P1 -c -t,";//组合bcp命令
                    Response.Write(ExeCommand(BcpExec));//执行bcp命令并显示操作结果
                }
            }
        }


        /**//// <summary>
        /// 执行Cmd命令
        /// </summary>
        /// <param name="commandText"></param>
        /// <returns></returns>
        public static string ExeCommand(string commandText)
        {
            Process p = new Process();
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = true;
            string strOutput = null;
            try
            {
                p.Start();
                p.StandardInput.WriteLine(commandText);
                p.StandardInput.WriteLine("exit");
                strOutput = p.StandardOutput.ReadToEnd();
                p.WaitForExit();
                p.Close();
            }
            catch(Exception e)
            {
                strOutput = e.Message;
            }
            return strOutput;
        }

 


C#中利用process类调用外部程序以及执行dos命令
c#中的Process类可方便的调用外部程序,所以我们可以通过调用cmd.exe程序

加入参数 "/c " + 要执行的命令来执行一个dos命令
(/c代表执行参数指定的命令后关闭cmd.exe /k参数则不关闭cmd.exe)

 1         private string RunCmd(string command)
     2         {
 3             //實例一個Process類,啟動一個獨立進程
 4             Process p = new Process();
 5
 6             //Process類有一個StartInfo屬性,這個是ProcessStartInfo類,包括了一些屬性和方

法,下面我們用到了他的幾個屬性:
 7
 8             p.StartInfo.FileName = "cmd.exe";           //設定程序名
 9             p.StartInfo.Arguments = "/c " + command;    //設定程式執行參數
10             p.StartInfo.UseShellExecute = false;        //關閉Shell的使用
11             p.StartInfo.RedirectStandardInput = true;   //重定向標準輸入
12             p.StartInfo.RedirectStandardOutput = true;  //重定向標準輸出
13             p.StartInfo.RedirectStandardError = true;   //重定向錯誤輸出
14             p.StartInfo.CreateNoWindow = true;          //設置不顯示窗口
15
16             p.Start();   //啟動
17            
18             //p.StandardInput.WriteLine(command);       //也可以用這種方式輸入要執行的命


19             //p.StandardInput.WriteLine("exit");        //不過要記得加上Exit要不然下一行

程式執行的時候會當機
20            
21             return p.StandardOutput.ReadToEnd();        //從輸出流取得命令執行結果
22
23         }

 

 

Process   pc=new   Process();  
  pc.StartInfo.FileName="bcp.exe";  
  pc.StartInfo.Arguments="bcp   \"Northwind.dbo.Orders\"   out   \"Orders.txt\"   -c   -q  

-U\"dboP\"go   dba\"";  
  pc.Start();  
 
  C#操作文本文件
  这是一个写日志的方法:
public static void writeLog(string message)
{
    try
    {
       StreamWriter writer=null;
       string filePath="log.txt";
       if (File.Exists(filePath))
       {
         writer=File.AppendText(filePath);
       }
       else
       {
         writer=File.CreateText(filePath);
       }
       writer.WriteLine("["+DateTime.Now.ToString()+"]:"+message);
       writer.Close();
     }
     catch (Exception e)
     {
       //把错误日志写到另一个文本文件中
       writeError(e.Message);
     }
}

需要补充的一点要注意:这个writer.Close();是绝对不能省的,不然写操作将会失败,看看bill是怎么

解释的:

    Close 的此实现调用传递 true 值的 Dispose 方法。

必须调用 Close 以确保所有数据正确写出到基础流中。调用 Close 后,在 StreamWriter 上进行的任何

操作均可能引发异常。

除非显式地调用 Flush 或 Close,否则,刷新流时不会刷新其基础编码器。将 AutoFlush 设置为 true

意味着将数据从缓冲区刷新到流中,但不刷新编码器状态。这将允许编码器保持其状态(不完全字符),

以便它可以正确地对下一个字符块进行编码。此方案影响 UTF8 和 UTF7,这二者中,某些字符只能在编

码器收到相邻的一个或多个字符后才能进行编码。

============================================================================================

=============================
用BCP命令导入数据到数据库的方法
将oledb读取的excel数据快速插入的sqlserver中,很多人通过循环来拼接sql,这样做不但容易出错而且

效率低下,最好的办法是使用bcp,也就是System.Data.SqlClient.SqlBulkCopy 类来实现。不但速度快

,而且代码简单,下面测试代码导入一个6万多条数据的sheet,包括读取(全部读取比较慢)在我的开发

环境中只需要10秒左右,而真正的导入过程只需要4.5秒。

 

view plaincopy to clipboardprint?
using System;
using System.Data;
using System.Windows.Forms;
using System.Data.OleDb;
namespace WindowsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
//测试,将excel中的sheet1导入到sqlserver中
string connString = "server=localhost;uid=sa;pwd=sqlgis;database=master";
System.Windows.Forms.OpenFileDialog fd = new OpenFileDialog();
if (fd.ShowDialog() == DialogResult.OK)
{
TransferData(fd.FileName, "sheet1", connString);
}
}

public void TransferData(string excelFile, string sheetName, string connectionString)
{
DataSet ds = new DataSet();
try
{
//获取全部数据
string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + excelFile + ";" +

"Extended Properties=Excel 8.0;";
OleDbConnection conn = new OleDbConnection(strConn);
conn.Open();
string strExcel = "";
OleDbDataAdapter myCommand = null;
strExcel = string.Format("select * from [{0}$]", sheetName);
myCommand = new OleDbDataAdapter(strExcel, strConn);
myCommand.Fill(ds, sheetName);

//如果目标表不存在则创建
string strSql = string.Format("if object_id(&apos;{0}&apos;) is null create table {0}(",

sheetName);
foreach (System.Data.DataColumn c in ds.Tables[0].Columns)
{
strSql += string.Format("[{0}] varchar(255),", c.ColumnName);
}
strSql = strSql.Trim(&apos;,&apos;) + ")";

using (System.Data.SqlClient.SqlConnection sqlconn = new

System.Data.SqlClient.SqlConnection(connectionString))
{
sqlconn.Open();
System.Data.SqlClient.SqlCommand command = sqlconn.CreateCommand();
command.CommandText = strSql;
command.ExecuteNonQuery();
sqlconn.Close();
}
//用bcp导入数据
using (System.Data.SqlClient.SqlBulkCopy bcp = new System.Data.SqlClient.SqlBulkCopy

(connectionString))
{
bcp.SqlRowsCopied += new System.Data.SqlClient.SqlRowsCopiedEventHandler(bcp_SqlRowsCopied);
bcp.BatchSize = 100;//每次传输的行数
bcp.NotifyAfter = 100;//进度提示的行数
bcp.DestinationTableName = sheetName;//目标表
bcp.WriteToServer(ds.Tables[0]);
}
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}

}

//进度显示
void bcp_SqlRowsCopied(object sender, System.Data.SqlClient.SqlRowsCopiedEventArgs e)
{
this.Text = e.RowsCopied.ToString();
this.Update();
}


}
}

using System;
using System.Data;
using System.Windows.Forms;
using System.Data.OleDb;
namespace WindowsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
//测试,将excel中的sheet1导入到sqlserver中
string connString = "server=localhost;uid=sa;pwd=sqlgis;database=master";
System.Windows.Forms.OpenFileDialog fd = new OpenFileDialog();
if (fd.ShowDialog() == DialogResult.OK)
{
TransferData(fd.FileName, "sheet1", connString);
}
}

public void TransferData(string excelFile, string sheetName, string connectionString)
{
DataSet ds = new DataSet();
try
{
//获取全部数据
string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + excelFile + ";" +

"Extended Properties=Excel 8.0;";
OleDbConnection conn = new OleDbConnection(strConn);
conn.Open();
string strExcel = "";
OleDbDataAdapter myCommand = null;
strExcel = string.Format("select * from [{0}$]", sheetName);
myCommand = new OleDbDataAdapter(strExcel, strConn);
myCommand.Fill(ds, sheetName);

//如果目标表不存在则创建
string strSql = string.Format("if object_id(&apos;{0}&apos;) is null create table {0}(",

sheetName);
foreach (System.Data.DataColumn c in ds.Tables[0].Columns)
{
strSql += string.Format("[{0}] varchar(255),", c.ColumnName);
}
strSql = strSql.Trim(&apos;,&apos;) + ")";

using (System.Data.SqlClient.SqlConnection sqlconn = new

System.Data.SqlClient.SqlConnection(connectionString))
{
sqlconn.Open();
System.Data.SqlClient.SqlCommand command = sqlconn.CreateCommand();
command.CommandText = strSql;
command.ExecuteNonQuery();
sqlconn.Close();
}
//用bcp导入数据
using (System.Data.SqlClient.SqlBulkCopy bcp = new System.Data.SqlClient.SqlBulkCopy

(connectionString))
{
bcp.SqlRowsCopied += new System.Data.SqlClient.SqlRowsCopiedEventHandler(bcp_SqlRowsCopied);
bcp.BatchSize = 100;//每次传输的行数
bcp.NotifyAfter = 100;//进度提示的行数
bcp.DestinationTableName = sheetName;//目标表
bcp.WriteToServer(ds.Tables[0]);
}
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}

}

//进度显示
void bcp_SqlRowsCopied(object sender, System.Data.SqlClient.SqlRowsCopiedEventArgs e)
{
this.Text = e.RowsCopied.ToString();
this.Update();
}


}
} 上面的TransferData基本可以直接使用,如果要考虑周全的话,可以用oledb来获取excel的表结构,并

且加入ColumnMappings来设置对照字段,这样效果就完全可以做到和sqlserver的dts相同的效果了。

============================================================================================

 

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C#键盘事件发布时间:2022-07-14
下一篇:
C#资源释放及Dispose、Close和析构方法发布时间:2022-07-14
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap