如何将VFP本地表数据传送到SQL-Server后台进行更新

转载 2006年05月30日 16:57:00

前言:

讲解涉及到VFPSQL-Server的并不多,MSDN中主要介绍的是VFP如何通过SPTSQL-Server进行通讯的常用几个函数,连接、断开、执行、设置环境等。

我在MSDN中找了很久,也许是她的内容太多了,我始终没有找到一个介绍如何将VFP本地表传递到SQL-Server进行存储的例子(所有涉及视图的例子除外)。

为什么不采用视图呢?可以说没有为什么,这也是我个人的喜好,我不喜欢后台用了SQL-Server后,前台还需要搞个什么视图,而为了这个视图还要创建一个数据库(DBC),那么前台还要来维护这个数据库。不知道是不是因为不了解数据库(DBC)所以不懂如何维护好她,反正我见过很多次就是因为DBC莫名其妙的问题导致程序无法正确的执行。。。

我喜欢前台干干净净的就一个EXE文件足以,而且这个文件放哪个目录都可以正常运行,程序设置性的数据可放置在注册表,或者放在INI配置文件。而INI配置文件又可放在Windows系统目录下,象System.ini、Win.ini那些一样。。。

好像有点跑题了,呵呵,下面言归正传了。。。

将本地表的数据传到服务器的方法很多种,当然我们得根据自己实际的需要进行。虽然DTS功能很强大,但未必能满足我们的要求。尤其是我们做的一个数据输入画面,或者一个小的数据更新执行时,好像用DTS有点小题大做吧?呵呵,我不知道高手们是不是用DTS都能搞定本文所涉及的中心思想,反正我在SQL-Server2000的帮助中看了一晚上的DTS方面的文字,还是有点晕~~

     下面我们来看一个例子。

实例介绍:

       SQL-Server数据库上有一个表,因为为了测试,我给她取名test,她有3个字段,分别是自动增长型的ID(int)字段(默认0),一个字符的字段TEST(varchar),一个逻辑字段LL(bit)(默认0)。

      

注意从这个实例中大家是不是想想为什么用这个例子来说明。

       该表的结构很简单,只是为了说明问题,TEST字段是一个可以随便修改的字段,类似一些描述、名称、备注、标题之类的性质,她的值的内容并不是很重要。而字段LL是一个标记性字段,因为她是逻辑型嘛,她起的作用是这样的:只有当LL=0的时候,才可以修改TEST字段的内容,而且修改后,要置LL=1,之后这条记录就不能再修改了。指字段TEST的值就不再修改了。好像被LL字段确认过了,不能再确认了。

       以下是在SQL-Server的查询分析器中运行的两段代码:

代码1

Declare @bitError bit

Set @bitError=0

Begin Transaction

     Update test

         Set TEST = GetDate(),

              LL = 1

         Where ID = 13 and LL=0

     If @@Error<>0 or @@RowCount<>1 Set @bitError=1

--

If @bitError=0

     Commit

Else

     Rollback

--

Select Case @bitError

         When 0 Then '成功!'

         When 1 Then '失败!'

         End

         as 结果

代码2

Begin Transaction

     Update test

         Set TEST = GetDate(),

              LL = 1

         Where ID = 13 and LL=0

     If @@Error<>0 or @@RowCount<>1 goto ErrorHandle

Commit

Select '成功' as 结果

return

ErrorHandle:

     Rollback

     Select '失败' as 结果

     return

代码说明:

以上代码1代码2的效果是一样的,都是为了更新表test中字段ID=13,并且LL=0的记录,使字段TEST等于当前的日期,字段LL的值由逻辑假到逻辑真。

    

     当执行完UPDATE命令后,会改变2个系统变量(暂不管还改变了其他什么系统变量)@@Error@@RowCount,如果命令执行有错,@@Error就是记录错误的代码,没有错则@@Error=0。按正确更新时UPDATE命令应该只更新一个记录,但是当更新时,表中的ID=13的记录上LL已经等于1时,再次执行UPDATE势必就是违反了先前说过的意思,就是不能再确认了,因此在WHERE条件的LL=0中就不会满足,导致一个记录都没更新到,从而改变系统变量 @@RowCount=0,这个结果就是错误的,正确更新应该是@@RowCount=1时才对!

     代码1代码2的区别在只更新一个记录时体现的不是很明显,如果多个记录同时更新时,主要表现

update …

if … set …

update …

if … goto …

以上分别两行代码其实是应该由客户端循环处理产生的N个组合。代码量上应该差不多,可当中间有更新时错误时,代码1的方案会继续更新,因为事物提交/回滚在最后才执行的。而代码2的方案会在一旦遇到更新错误时就直接到最后进行回滚了。

以上的代码都是后台直接运行的,我们可以在VFP中将他们放在一个变量中,然后将这个变量传递到后台执行,大家可以试下2组代码分别有什么不同。如果是代码1,当代码中含有错误的命令时,比如将TEST表名打错,使得到一个不存在的表,那么运行时是会产生错误的。可代码1不会返回错误,而代码2则会返回后台产生的错误!

我试过是因为代码1中有Set @bitError=0 这样的赋值语句。至于原因,我也不得而知了。

所以代码1的方案不可取,除非她在后台的存储过程中呆着。

可是测试代码2时,按理论上应该返回一个光标文件,字段为“结果”存着“成功”还是“失败”的记录,后台运行时会按自己的想法去执行,可在VFP中,什么都没有,有时还会出现错误,叫“不能从服务器返回记录集”!

为了实现上述代码所达到的目的,通过改写代码,在VFP中按以下代码3的编写规则书写即可得到比较理想的答案(至少我现在觉得比较好)。

代码3

IF RunSQL("Begin transaction")

     RunSQL("Update test set test = GetDate(),ll=1 where ID = 13 and ll=0")

     RunSQL("Select @@Error as nError,@@RowCount as nRowCount")

     IF nError#0 OR nRowCount#1

         *-- 更新失败

         RunSQL("Rollback")

         MESSAGEBOX("更新错误,或数据没有更新到,总之此次更新失败!",16,"更新")

         RETURN

     ELSE

         *-- 更新成功

         RunSQL("Commit")

         MESSAGEBOX("成功更新!",64,"更新")

     ENDIF

ENDIF

代码说明:

       代码3中的RunSQL() 是自定义函数,主要是调用 =sqlexec()

     代码的第3行至所以能这么写,是因为@@Error@@RowCount是系统变量,如果是自己定义的又不是全局变量的则不能这么使用,会提示找不到变量的错误

参考代码:

调用SQL上的一个DTS包进行DOS方式下执行:

EXEC xp_cmdshell 'DTSRun /S "(local)" /U "sa" /N "DTS 转换测试" /G "{AA52E887-9372-4036-A501-1E50C559D05A}"'

(下划线部分是DOS下可以运行的命令)

同时向服务器添加多个记录时:

*-- 开始一个事务

IF !RunSQL("Begin Transaction")

     RETURN .F.

ENDIF

SELECT temp_SelectPers

ShowProcessBar(Submiting_loc,RECCOUNT()+1)

SCAN

     oProcessbar.showbar(RECNO())

     lcPerID  = ALLTRIM(STR(ID))

     lcSQL    = "Insert into l_jobs (。。。) values (。。。)"

     IF RunSQL(lcSQL) && 执行插入命令

         IF RunSQL("Select @@Error as nError,@@RowCount as nRowCount")     && 返回执行的状态

              IF nError#0 OR nRowCount#1

                   *-- 更新失败

                   RunSQL("RollBack")  && 进行回滚

                   MESSAGEBOX(Fail_loc,16,stop_loc)

                   showbar(RECCOUNT("temp_SelectPers")+1)

                   RETURN .F.

              ENDIF

         ENDIF

     ELSE

          RunSQL("RollBack")

          showbar(RECCOUNT("temp_SelectPers")+1)

          RETURN .F.

     ENDIF

ENDSCAN

showbar(RECCOUNT("temp_SelectPers")+1)

IF RunSQL("Commit")

     MESSAGEBOX(DataSaved_loc,64,info_loc)

ENDIF

相关文章推荐

VFP调用Sql Server的更新语句(通用类)!

* ----------------------------------------------------------------------- \\ sql_update m_db...

如何将SQL Server数据表中的数据按条件批量导出为多个Excel文件

昨天,某位大大提了个要求,需要将某个有数十万行数据的表按类别导出为xls文件,每个类别一个xls。将数据表中的数据导出并保存为xls简单,用SSIS或者查询出来之后另存为都可以。但是,这个表中的分类有...

如何将数据导入到 SQL Server Compact Edition 数据库中

一、场景描述在智能设备(Smart Device)应用程序和智能客户端(Smart Client)应用程序的部署阶段,我们需要对离线数据进行初始化,即将后台数据库服务器中的一些数据,导入到离线数据库中...
  • zz_mm
  • zz_mm
  • 2011-03-10 15:54
  • 714

如何将数据导入到 SQL Server Compact Edition 数据库中(二)

在我发表了《如何将数据导入到 SQL Server Compact Edition 数据库中(一)》一文后,有一位读者提出这样的疑问:示例程序是否能够在 PPC 上跑,直接从远程 PC 上的 SQL ...
  • zz_mm
  • zz_mm
  • 2011-03-10 16:58
  • 829

如何将SQL Server数据导入到Oracle数据库中

在我们使用SQL Server数据库的过程中,有时需要将SQL Server数据导出,导入到其他的数据库中,比如导入到Oracle中。     假设要将SQL Server中的Northwind数...

如何将数据导入到 SQL Server Compact Edition 数据库中(五) 收藏

如何将数据导入到 SQL Server Compact Edition 数据库中(五) 收藏 系列文章导航:如何将数据导入到 SQL Server Compact Edition 数据库中(一)如何将...

VFP调用Sql Server的取字段值(通用类)!

* ----------------------------------------------------------------------- \\ sql_field ...

VFP调用Sql Server的插入语句(通用类)!

* ----------------------------------------------------------------------- \\ sql_insert     m_dbf1='...

VFP调用Sql Server的取最小值(通用类)!

* ----------------------------------------------------------------------- \\ sql_max m_dbf="...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)