有点似懂非懂。
第一个问题,用sql管理单号,这单号是自动生成的呢,还是由凭证得来的。可以说的详细一些。
还是先解决第二个问题吧。
我想你说是改进的话,应该代码错误是不大有的吧。
改进的方法:
1。你可以这样,把事物处理部分的代码都作成存储过程,而不要放在前端,把回滚防在sql端来处理。代码这么多,可能会影响网络的流量。代码作成存储过程,维护起来,要方便的多。前端只要用一个sqlexec(handle,"exec procname")就行了。另外,你这端代码,应当在以后的使用中的改动可能性比较大,那样你也只要改动服务器的存储过程就行了。
2。不要用循环,用sql语句来完成。比如你那段scan的代码。你可以用sql 语句。因为insert into tablename(field1,field2) select field1,field2 from table2在vfp中是不支持的。你可以把它作成存储过程,然后调用它。因为它基于集合处理,比scan的速度快的多,而且,代码也容易看的懂。在视图中移动指针很影响性能的。
3。由于,你程序要实现的业务流程不是很清楚,从字符推测表的内容不大方便,所以不知道能否从流程上进行改善。
4。第四个问题,你这个handle是哪来的,用的是spt还是远程视图。
第一个问题,用sql管理单号,这单号是自动生成的呢,还是由凭证得来的。可以说的详细一些。
还是先解决第二个问题吧。
我想你说是改进的话,应该代码错误是不大有的吧。
改进的方法:
1。你可以这样,把事物处理部分的代码都作成存储过程,而不要放在前端,把回滚防在sql端来处理。代码这么多,可能会影响网络的流量。代码作成存储过程,维护起来,要方便的多。前端只要用一个sqlexec(handle,"exec procname")就行了。另外,你这端代码,应当在以后的使用中的改动可能性比较大,那样你也只要改动服务器的存储过程就行了。
2。不要用循环,用sql语句来完成。比如你那段scan的代码。你可以用sql 语句。因为insert into tablename(field1,field2) select field1,field2 from table2在vfp中是不支持的。你可以把它作成存储过程,然后调用它。因为它基于集合处理,比scan的速度快的多,而且,代码也容易看的懂。在视图中移动指针很影响性能的。
3。由于,你程序要实现的业务流程不是很清楚,从字符推测表的内容不大方便,所以不知道能否从流程上进行改善。
4。第四个问题,你这个handle是哪来的,用的是spt还是远程视图。
第一:单号当然希望是SQL管理。自动生成。但是要做到年月日+单号
第二:SQL的存储过成我没写过呀。(可以帮写一下吗?)
第三:我开始是用远程视图但解决不了回滚问题。(后来改成SCAN的)
第四:HANDLE=SQLCONNECT("Y1")谢谢!!!!!!!!
在sql server里选中数据库里stored proced,右键选新建,在里面写上
create proc procname(自己定义) as
begin
insert into jcdmx(jcdh,ks_no,ckmc,lb,hpbm,hpmc,hpdw,jcsl,jcdj,jcje,jczk)
select jcdh,ks_no from jcdmx_c
end
客户端调用
if sqlexec(handle,"exec procname")!=1
messagebox("数据更新失败!")
endif
你的连接我建议用字符串连接,因为,老是要建odbc数据源很麻烦。
handle=sqlstringconnect("driver=sql server;server=servername;uid=客户机名;pwd=登录密码;database=数据库名")
这样的话,连接比较有通用性
至于单号,有两个办法,一个是前端更新单号的地方写程序,或者sqlserver段写存储过程,更好的方法是写触发器。我触发器不大熟,只会一点简单的。
SCAN
SQLSTRINGS="INSERT INTO JCDMX (JCDH,KS_NO,CKMC,LB,HPBM,HPMC,HPDW,JCSL,JCDJ,JCJE,JCZK) VALUES ('"+ALLT(JCDMX_C.JCDH)+"','"+ALLT(JCDMX_C.KS_NO)
SQLSTRINGS=SQLSTRINGS+"','"+ALLT(JCDMX_C.CKMC)+"','"+ALLT(JCDMX_C.LB)+"','"+ALLT(JCDMX_C.HPBM)+"','"+ALLT(JCDMX_C.HPMC)+"','"+ALLT(JCDMX_C.HPDW)
SQLSTRINGS=SQLSTRINGS+"','"+ALLT(STR(JCDMX_C.JCSL,12,2))+"','"+ALLT(STR(JCDMX_C.JCDJ,12,2))
SQLSTRINGS=SQLSTRINGS+"','"+ALLT(STR(JCDMX_C.JCJE,12,2))+"',"+ALLTRIM(STR(JCDMX_C.JCZK))+")"
IF SQLEXEC(HANDLE,SQLSTRINGS)<1
SQLEXEC(HANDLE,"ROLLBACK TRANSACTION")
MESSAGEBOX('生效失败',16,'提示')
RETU
ENDIF
ENDSCAN
是不是这样呀??可是这样会快吗?写代码也烦死了.有没有跟好的办法???还有就是如果上面的"SQLSTRINGS"大于256字节时有什么好办法?
我现在是用先INSERT再UPDATE分开两次写,是不是很笨呀?
在sql server里找到你的数据库,然后展开,选中stored procedures,右键选new procedures
然后写代码(它已替你写了一点,那段你可以不写)
create proc proc1(我定义该存储过程名为proc1)
as
begin
insert into jcdmx(jcdh,ks_no,ckmc,lb,hpbm,hpmc,hpdw,jcsl,jcdj,jcje,jczk)
select jcdh,ks_no,ckmc,lb,hpbm,hpmc,hpdw,convert(numeric (9,2),jcsl)as jcsl,convert(numeric (9,2),jcdj) as jcdj,convert(numeric (9,2),jcje) as jcje,convert(numeric (9,2),jczk) as jczk from jcdmx_c
end然后,在vfp里写这段代码的地方先注释,改成如下代码:
if sqlexec(handle,"exec proc1")!=1
messagebox("生效失败!")
endif
全都换成convert(chr(width),fieldname),把width换成转换字段的宽度,fieldname换成要转换的字段。
建议:进厂金额在数据库里不要,jczk不知道是什么,如果可以由计算得到也不要,因为只要有单价有数量,就有金额。进厂金额一般是在查询里用到。比如我今天要查进厂金额。那我只要在查询的地方写上select jcsl,jcdj,jcsl*jcdj as jcje from table.
这样的话,你可以不处理这些字段,出错的可能性小。另外,最好不要把数值性专程字符性。
是VFP本地的数据表呀.现在说的是上传的问题呀.
你所说的先insert在update是怎么回事,我想用刚才的语句,你可以直接insert的
不要用scan,直接用appe from tablename field1,field2 要转换类型的地方,你可以把服务器上的表改成数值型,每次都转换多麻烦
你所说的先insert在update是怎么回事,我想用刚才的语句,你可以直接insert的 "VFP的字段好象只支持256字节的吧?"SQLSTRINGS="INSERT INTO JCDMX (JCDH,KS_NO,CKMC,LB,HPBM,HPMC,HPDW,JCSL,JCDJ,JCJE,JCZK).........."这个SQLSTRINGS大于256字节怎么办?
不要用scan,直接用appe from tablename field1,field2 要转换类型的地方,你可以把服务器上的表改成数值型,每次都转换多麻烦"JCDMX_C是VFP表.
JCDMX是SQL表.怎么还可以用APPEN.快说一说怎么个用法...
sele jcdmx
appe from path/jcdmx_c fields jcdh,ks_no……,当然,必须保证两个表中的字段名一样。
不过用视图追加的话,可能速度可能更你现在的差不了多少。我不喜欢远程视图就是这一点,追加几条记录也要老半天。
老大呀.JCDMX_C是VFP表.JCDMX是SQL表.
哪就是说还是用我现在的办法了.(我现在就是用你说的办法在做了)
视图会比SCAN加SQL语句慢吗?
还用就是用视图数据是不可以加滚的。
哪用SQL管理单号呢(也就是说自动生成单号,但前题是要做到年月日+单号.)
2000112160001.2000112160002......2000112169999.
这个怎么做得到。
视图当然不会比scan慢,我只不过夸张了一点。
begin tran
sele jcdmx_c
appe from paht/jcdmx
end transql表可以用appe from从vfp表追加数据,但vfp表不能从sql表中用appe from 追加数据 。
begin tran
sele jcdmx_c
appe from paht/jcdmx
end tranVFP上的事务管理不了SQL的.我还加了SQL的事务也是不行呀.
只要数据是上传了,不管你用VFP的回滚还是SQL的回滚都是无效.(你可以试一下)
(sql表可以用appe from从vfp表追加数据,但vfp表不能从sql表中用appe from 追加数据 。)
你的意思是不是SQL用远程视图,才可以用APPEN.
VFP的APPEN 我用会用呀.只是不知道怎么样才可以在SQL上也用APPEN.
SQL的INSERT我也有用....
你可以先索引一下,go bott得到编号,repl新进编号加一就行了。
也可以先select max(bh) as max_bh from table
max=max_bh
然后repl 新进编号 with 年+月+日+allt(str(max+1)
最好还是用触发器。不过触发器要sql高手帮忙了。
对我来说有点难
至于appe from,很简单,你可以试试。把jcdmx_c做成远程视图,然后你appe from path/jcdmx fields jcdh,ks_no……
也不一定要作成远程视图,也可以用spt的光标。
do prg\link &&调用程序建立连接if jb>0 and sqlexec(jb,"")=1 &&测试连接有效性
sqlexec(jb,"select gwg.sno,gwgje,qxns,wyjje,qdsj,gdh,rsda.xm,rsda.xb,wxgsbm.mc as gs_bm from rsda join gwg on;
rsda.sno=gwg.sno join wxgsbm on wxgsbm.bh=rsda.gbbh","lsb")&&通过多表连接生成光标
sqlexec(jb,"exec rsda_gs_bm","rsda") &&调用存储过程生成光标
else
messagebox("网络正忙或连接出错,请稍侯再试!")
cancel
endif
sele lsb
cursorsetprop("tables","gwg","lsb") &&设置临时表的更新目标表
cursorsetprop("keyfieldlist",'sno',"lsb") &&设置临时表的关键字
cursorsetprop("updatablefieldlist","sno,gwgje,qxns,wyjje,qdsj,gdh","lsb")&&设置临时表的更新字段
cursorsetprop("updatenamelist","sno gwg.sno,gwgje gwg.gwgje,qxns gwg.qxns,wyjje gwg.wyjje,qdsj gwg.qdsj,gdh gwg.gdh","lsb") &&&用lsb中的相应字段更新 gwg表
cursorsetprop("sendupdates",.t.,"lsb")&&设置为可更新
cursorsetprop("wheretype",2)sele lsb
appe from temp\gwg field name,xb &&temp\gwg为vfp表
tableupdate(0,.t.)
我给你的回滚解决了。发到你的信箱了
有关在VFP中使用SPT,不必全部这样将变量转成字符串再连接,在SPT中是可以使用变量的,格式如下:
local iTest
iTest=0
public iSqlcon
iSqlcon=Sqlcon(Dsn,DsnUser,DsnPws) && Dsn为DNS,Dsnuser为用户名,DsnPws为密码
sqlexec(iSqlcon,"Select field_a as a,field_b as b "+;
"from test_tab "+;
"where field_a = ?iTest and field_b = ?iTest",'test_tmp')
(注:这里变量、字段、表的名字我是代表意思的,要换成你实际使用的)
如上,变量前加'?'就可以使用,这样写代码要方便清楚多了,象那样转成字符串再连接的,看的不清,容易出错!对于?后只能是变量,不可以是运算式!
还有关于这个SQL字符传长度会大于255的问题:当整句长度过长时,中间如例用"+;"将字符串分割连接起来就可以了,只要每行不过长就没问题(过长会系统回有提示!),全句可以随意多长!
希望有点帮助!