如果是用于 bcp导出就好处理了,如果是要在select中显示,就必须查系统表来处理.

解决方案 »

  1.   

    呵呵,我就是要借助bcp,但bcp不处理列名,所以我要在这里加上这一列!是根据定义列时的长度来固定每列显示的数据的宽度么? 
    没错,就是这样的!
      

  2.   

    --用bcp主要是列名的问题,数据很简单,用下面的命令导出的就是数据根据列定义固定宽度的exec master..xp_cmdshell 'bcp "pubs..sales" out "c:\sales.txt" /T /t"" /c'
      

  3.   

    对,我就是要用SQL语句在生成的时候在第一行自动的生成一行使用列名组成的行,并且要和下面的数据行对起!
      

  4.   

    对于字段名,个人觉得还是单独写个程序处理一下,在导出的bcp文件第一行中插入列名.
    如果要用sql语句写,就要使用union all将字段名数据和表中的数据组合成查询,然要再导出,这样处理要考虑的问题就比较多.
    1. 字段类型的转换问题,数据必须全部转换成字符型,而binary/varbinary这类的数据很难直接转换为字符型
    2. sql语句的长度问题,字段多的话,生成的sql语句容易超过8000,那又变成一个新的处理问题.
    3. 列的宽度,对于数字这类列不好确定列的宽度
      

  5.   

    程序中插入的话,对齐还是比较容易处理吧? 对于字符,查系统表就知道宽度了,对于数字,可以通过估算长度+查找空格(或者非空格)来定位(读取bcp导出后的第一行数据做为参考)
      

  6.   

    或者在程序中
    你专门读出bcp导出的第一条数据,表中的第一条记录,系统表中该表的字段定义
    对于字符,直接可以定位(宽度已知嘛)
    非字符,读取表中第一条记录的该列值,从bcp数据中的第一行数据中查找,再配合列分隔符空格及估算的字段宽度,应该不太难.
      

  7.   

    刚才测试了一下DTS,结果同样让我很失望!现在他所能作到的跟我做到的一样!
    就是这样的效果!
    a e
    286        2005-04-23 20:34:07.187000000
    287        2005-04-23 20:34:07.187000000我需要的效果
    a          e
    286        2005-04-23 20:34:07.187000000
    287        2005-04-23 20:34:07.187000000
    哎,看看有别的什么办法没有,也许我做的已经可以了,呵呵!!
      

  8.   

    呵呵,下面是我写的SQL,其实就是抄袭你的了,哈哈~~/*名称:NEW_SP_Center_File2table*/
    /*时间:2005-4-19*/
    /*作用:创建表的导入和导出*/
    /*所有者:邹建*/
    CREATE    Procedure NEW_SP_Center_File2table 
    @servername varchar(200)='172.168.1.11' --服务器名
    ,@username varchar(200)='sa'  --用户名,如果用NT验证方式,则为空''
    ,@password varchar(200)=''  --密码
    ,@localname varchar(200)='172.168.1.228' --本机名
    ,@pathname varchar(1000)='c:' --要导出的目录名(最后一个字符不能是'\')
    ,@filename varchar(1000)='test.txt' --要导出的文件名(不含路径)
    ,@dbname varchar(50)='CHCenter' --数据库
    ,@tbname varchar(500)='a' --表名
    ,@isout bit=1    --1为导出(默认),0为导入
    ,@fdsplit varchar(10)='\t' --字段分隔符,默认为制表符
    ,@rowsplit varchar(10)='\n' --记录分隔符,默认为回车符
    ,@starttime datetime='' --导出数据的开始时间
    ,@endtime datetime='' --导出数据的结束时间
    as
    declare @sql varchar(8000)
    declare @Dir varchar(4)--共享磁盘名/*1.对于导出,做特殊处理*/
    /*1.1从导出信息表中取出导出信息语句*/
    select @starttime=getdate()
    select @endtime=getdate()set @Dir='z:'
    set @sql='net use '+@Dir+' /del' 
    print @sql
    exec master.dbo.xp_cmdshell @sql/*1.2建立文件共享*/
    set @sql='net use '+@Dir+' \\'+@localname+'\'+replace(@pathname,':','$')+' 123 /user:administrator'            
    print @sql
    exec master.dbo.xp_cmdshell @sql /*1.3如果是导出,则生成头文件*/
    if @isout=1
    Begin
    declare @tbInfo Varchar(200)
    declare @tbWhere Varchar(200)
    select @tbInfo=tbInfo,@tbWhere=tbWhere From tbInfo Where tbName=@tbname
    print @tbInfo
    set @sql='echo '+@tbInfo+'>'+@Dir+'\head_'+@filename
    print @sql
    exec master.dbo.xp_cmdshell @sql /*2.导出或者导入数据*/
    set @tbname='select '+Replace(@tbInfo,char(9),',')+' from '+@dbname+'..'+@tbname+' '+@tbWhere
    --set @tbname='select convert(char(10),'a'),convert(varchar(20),'e',120) from a union select convert(char(10),a) ,convert(varchar(20),e,120) from CHCenter..a'
    print @tbname 
    End
    else
    set @tbname=@dbname+'..'+@tbname
    set @sql='bcp "'+@tbname
     +case when @isout=1 then '" queryout' else '" in' end
     +' "'+@Dir+ +case when @isout=1 then '\temp_' else '' end+@filename+'" -c' +' -S"'+@servername
     +case when isnull(@username,'')='' then '' 
      else '" -U"'+@username end
     +'" -P"'+isnull(@password,'')+'"'
     +' -t"'+@fdsplit+'"'
     +' -r"'+@rowsplit+'"'
     +' -E'
     +case when @isout=1 then ' -F 1' else ' -F 2 -h FIRE_TRIGGERS' endprint @sql
    exec master..xp_cmdshell @sql/*2.2如果是导出,则合并生成的文件*/
    If @isout=1
    Begin
    select @sql='copy/b '+@Dir+'\head_'+@filename+'+'+@Dir+'\temp_'+@filename+' '+@Dir+@filename
    print @sql
    exec master..xp_cmdshell @sql
    End/*3.删除文件共享*/
    set @sql='net use '+@Dir+' /del' 
    print @sql
    exec master.dbo.xp_cmdshell @sql
    GO
      

  9.   

    一定要在sql中处理么? 那必须为字符型外的每种类型(text/ntext/image除外)测试一下,看看bcp是如何估算列宽的,然后再处理改天有时间测测,楼主自己也可以测试一下.