首页 新闻 会员 周边

SQL导出DBF字段名被截取

0
悬赏园豆:80 [已解决问题] 解决于 2008-08-11 12:43
<P>最近做项目要求从SQL中导出数据到VF,但DBF表之前不存在,导出时要新建DBF表,在网上看到下面的存储过程。用的过程中发现如果我的字段名长度大于10就会出问题,因为VF的自由表字段名长度最大只能为10,数据库表可以允许为128,在存储过程中新建表字段名被截取前10个字符,导出数据时SQL的字段和DBF字段就不匹配了,希望有人能帮忙看下该如何改进。</P> <P>&nbsp;</P> <P>&nbsp;</P> <P>&nbsp;</P> <P>/*--数据导出dBase<BR>&nbsp;<BR>&nbsp;导出查询语句中的数据到dBase,如果文件不存在,将自动创建文件<BR>&nbsp;基于通用性考虑,仅支持导出标准数据类型<BR>--*/</P> <P>/*--调用示例</P> <P>&nbsp;--导出dBase<BR>&nbsp;p_exportvf @sqlstr='select * from t_tdd',@path='d:\',@over=1<BR>--*/</P> <P>if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_exportvf]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)<BR>drop procedure [dbo].[p_exportvf]<BR>GO</P> <P>create proc p_exportvf<BR>@sqlstr varchar(8000),&nbsp;&nbsp; --要导出的查询名<BR>@path nvarchar(1000),&nbsp;&nbsp; --文件存放目录<BR>@fname nvarchar(250)='temp.dbf',--文件名,默认为temp<BR>@over bit=0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --是否覆盖已经存在的文件,如果不覆盖,则直接追加<BR>as<BR>declare @err int,@src nvarchar(255),@desc nvarchar(255),@out int<BR>declare @obj int,@constr nvarchar(1000),@sql varchar(8000),@fdlist varchar(8000)</P> <P>--参数检测<BR>if isnull(@fname,'')='' set @fname='temp.dbf'</P> <P>--检查文件是否已经存在<BR>if right(@path,1)&lt;&gt;'\' set @path=@path+'\'<BR>create table #tb(a bit,b bit,c bit)<BR>set @sql=@path+@fname<BR>insert into #tb exec master..xp_fileexist @sql<BR>if exists(select 1 from #tb where a=1)<BR>&nbsp;if @over=1<BR>&nbsp;begin<BR>&nbsp; set @sql='del <A href="mailto:'+@sql"><FONT color=#0000ff>'+@sql</FONT></A><BR>&nbsp; exec master..xp_cmdshell @sql,no_output<BR>&nbsp;end<BR>&nbsp;else<BR>&nbsp; set @over=0<BR>else<BR>&nbsp;set @over=1</P> <P>--数据库创建语句<BR>set @sql=@path+@fname<BR>set @constr='Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties="dBASE 5.0;'<BR>&nbsp;+';HDR=NO;DATABASE='+@path+'"'</P> <P>--创建表的SQL<BR>declare @tbname sysname<BR>set @tbname='##tmp_'+convert(varchar(38),newid())<BR>set @sql='select * into ['+@tbname+'] from(<A href="mailto:'+@sqlstr+'"><FONT color=#0000ff>'+@sqlstr+'</FONT></A>) a'<BR>exec(@sql)</P> <P>--连接数据库<BR>exec @err=sp_oacreate 'adodb.connection',@obj out<BR>if @err&lt;&gt;0 goto lberr</P> <P>exec @err=sp_oamethod @obj,'open',null,@constr<BR>if @err&lt;&gt;0 goto lberr</P> <P>--创建表的SQL<BR>select @sql='',@fdlist=''<BR>select @fdlist=@fdlist+','+a.name<BR>&nbsp;,@sql=@sql+',['+a.name+'] '<BR>&nbsp; +case when b.name in('char','nchar','varchar','nvarchar') then<BR>&nbsp;&nbsp;&nbsp;&nbsp; 'text('+cast(case when a.length&gt;250 then 250 else a.length end as varchar)+')'<BR>&nbsp;&nbsp; when b.name in('tynyint','int','bigint','tinyint') then 'int'<BR>&nbsp;&nbsp; when b.name in('smalldatetime','datetime') then 'datetime'<BR>&nbsp;&nbsp; when b.name in('money','smallmoney') then 'money'<BR>&nbsp;&nbsp; else b.name end<BR>FROM tempdb..syscolumns a left join tempdb..systypes b on a.xtype=b.xusertype<BR>where b.name not in('image','text','uniqueidentifier','sql_variant','ntext','varbinary','binary','timestamp')<BR>&nbsp;and a.id=(select id from tempdb..sysobjects where <A href="mailto:name=@tbname"><FONT color=#0000ff>name=@tbname</FONT></A>)<BR>select @sql='create table ['+@fname<BR>&nbsp;+']('+substring(@sql,2,8000)+')'<BR>&nbsp;,@fdlist=substring(@fdlist,2,8000)</P> <P>if @over=1<BR>begin<BR>&nbsp;exec @err=sp_oamethod @obj,'execute',@out out,@sql<BR>&nbsp;if @err&lt;&gt;0 goto lberr<BR>end</P> <P>exec @err=sp_oadestroy @obj</P> <P>set @sql='openrowset(''MICROSOFT.JET.OLEDB.4.0'',''dBase 5.0;DATABASE='<BR>&nbsp;<A href="mailto:+@path+''',''select"><FONT color=#0000ff>+@path+''',''select</FONT></A> * from ['+@fname+']'')'</P> <P>--导入数据<BR>exec('insert into <A href="mailto:'+@sql+'('+@fdlist+'"><FONT color=#810081>'+@sql+'('+@fdlist+'</FONT></A>) select <A href="mailto:'+@fdlist+'"><FONT color=#810081>'+@fdlist+'</FONT></A> from ['+@tbname+']')</P> <P>set @sql='drop table ['+@tbname+']'<BR>exec(@sql)</P> <P>return</P> <P>lberr:<BR>&nbsp;exec sp_oageterrorinfo 0,@src out,@desc out<BR>lbexit:<BR>&nbsp;select cast(@err as varbinary(4)) as 错误号<BR>&nbsp; ,@src as 错误源,@desc as 错误描述<BR>&nbsp;select @sql,@constr,@fdlist<BR>go</P> <P>&nbsp;</P>
问题补充: 急!急!急!加分 我也是以前从没弄过VF 项目要求导出DBF表 VFP表分为两种: 1、数据库表 字段名长度最长可以为128 2、自由表 字段名长度最长可以为10 就是查到这个,看能不能新建VFP数据库表...
斌的主页 | 初学一级 | 园豆:150
提问于:2008-08-01 17:45
< >
分享
最佳答案
0
如果VF的10字符限制无法绕过,那么只有两条路: 一是修改原数据库的字段名保持到10以下 二是不一样就不一样,数据过去再说 无论哪一个,使用这些数据的程序都得做不小的改动,呵呵,没有用过VF,不晓得能不能绕过限制
丁学 | 专家六级 |园豆:18730 | 2008-08-02 12:01
其他回答(2)
0
很久很久以前,也曾经弄过VF,不过是从VF将数据弄到SQLSERVER中,因此没有遇到过你的这个问题 建议直接使用SQLSERVER的导入导出向导,导的时候改改数据库对象的名称。或者用SSIS也行,那个自定义的能力强大得多。 PS:在不同数据源之间转换数据,有些修改是无法避免的。记得当年有一次要把SQLSERVER中的数据导到Oracle中,直接把我折腾得只剩半条命了……
电机拖动 | 园豆:1295 (小虾三级) | 2008-08-03 18:09
0

t_tdd,呵呵招生人士!

杀猪屠龙刀 | 园豆:202 (菜鸟二级) | 2012-11-09 23:05
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册