http://www.itren.info/-MS-SQL-Server-SQL-Server_tiupi.htm
在数据窗口中查询出来的数据进行修改后,保存,使用UPDATE(),第一次点击按钮出现如上错误,以后均能成功保存.是什么问题,谢谢!!
2005-02-19 15:06:51回复人: qltouming
update()后commit了吗
2005-02-19 15:08:48回复人: xuam
你可能設了autocommit=true了
2005-02-19 15:08:53回复人: yougang_ok
当然有了
if dw_1.update() = 1 then
commit using sqlca;
messagebox("提示","保存成功!")
else
rollback using sqlca;
messagebox("提示","保存失败,请重试!")
end if
2005-02-22 02:09:53回复人: hygougou
并发造成的
参考
http://search.csdn.net/search.asp?key=No+changes+made+to+database&class=PowerBuilder&size=10&option=advance&x=85&y=6
2005-02-22 02:15:11回复人: hygougou
对于Client/Server方式下的编程,不可避免地有并发操作处理的问题。为了说明问题,举一个不够恰当的例子:如果有两个用户A和B都试图访问同一员工记录并同时要求修改该员工工资时,会有什么情况发生呢?假设该员工的工资为1000元,两台机器修改记录之前读出用户工资均正确。A用户为此员工加本月奖金200元,查询到原来薪水为1000,加上200后变为1200,而此时B用户在不同的机器上扣除此员工的水电费50元,系统将salary字段置为950,显然这种修改是不能接受的,实际的结果应该是1150元。
二、背景知识
DataWindow是PowerBuilder中一个独特的对象,功能强大,是Sybase的专利技术,它可以方便而快速地处理数据。通过数据窗口,我们无需编写复杂的SQL语句,就可以实现对数据库的读写操作。
实际上DataWindow 在更新数据时,会根据用户对 DataWindow 中的数据进行的各种操作自动地转换成 SQL 语句,然后再执行。例如:用户新增了一条记录,也就是脚本执行了InsertRow() 函数,输入数据后保存(调用 Update() 函数),此时 PB会将其自动转换成 SQL 语句,发送到数据库服务器。对于转换后的SQL语句,我们可以在datawindow的sqlpreview事件中,加脚本:
MessageBox('SQL语句',sqlsyntax)
来查看。
这里有一点需要注意,如果数据库连接的binding参数设定为enable,则sqlsyntax返回将不完整,插入一条记录时sqlsyntax呈如下形式:
INSERT INTO "personnel" ( "id", "name", "birthday", "technical_post", "salary", "notes" ) VALUES ( ?, ?, ?, ?, ?, ? )
为了正确返回sqlsyntax,需将binding参数设为disabled, 设置方法是在dbprofile对话框中,将transaction标签页的Disable Bind选项勾上,或者是在personnel.ini文件中DbParm改为:
DbParm=Connectstring='DSN=database_server',DisableBind=1
则sqlsyntax完整返回如下:
INSERT INTO "personnel" ( "id", "name", "birthday", "technical_post", "salary", "notes" ) VALUES ( 100, '令狐冲', '1975-05-01', '工程师', 1000, '软件开发' )
三、PowerBuilder中的并发控制
PowerBuilder中可以通过数据窗口的更新属性(Update Properties)来实现并发控制。打开 DataWindow 画笔板,点击 Rows->Update Properties菜单,进入“Specify Updatae Properties”对话框,其中“Where Clause for Update/Delete”组合框中的三个选项就是三种处理数据并发问题的策略。
1、选项“Key Columns”:
这种情况是比较更新前后Table的关键字是否发生了变化,即当前数据库中关键字的实际值和最初查询的值做比较,如果没有改变,则可以更新,反之不能更新。
如用户A将员工号为100的职员的salary字段值改为1200并保存后,B用户也将员工号为100的职员的salary字段值改为950并点击“存盘”按钮,我们可以看到数据窗口sqlpreview事件中的sqlsyntax返回如:
UPDATE "personnel" SET "salary" = 950 WHERE "id" = 100
因为关键字id=100没有发生变化,Where条件成立,更新成功,将A用户的修改覆盖,salary值变为950元,员工损失了200元。显然这样没有达到并发控制的目的,未能保证数据的完整性。
2、选项“Key and Updateable Column”:
这种情况是比较更新前后Table的关键字和可修改(更新)的列值是否发生了变化,如果没有一项发生改变,更新成功;反之,若数据库中当前值中若任一项与数据窗口最初检索出的值不一致,则更新失败。对于此例,因所有字段都是可修改(更新)的,即检测是否有任一字段变化。
同上,当用户A更新完后,B用户点击“存盘”按钮,我们可以看到sqlsyntax返回如:
UPDATE "personnel" SET "salary" = 950 WHERE "id" = 100 AND "name" = '令狐冲' AND "birthday" = '1975-05-01' AND "technical_post" = '工程师' AND "salary" = 1000 AND "notes" = '软件开发'
显然,id字段没有改变,而可修改(更新)列之一salary的值经A用户修改存盘后,已由1000变为了当前的1200,where条件不成立,因此更新失败,并弹出出错信息如下:
Row changed between retrieve and update.
No changes made to database.
UPDATE "personnel" SET "salary" = 950 WHERE "id" = 100 AND "name" = '令狐冲' AND "birthday" = '1975-05-01' AND "technical_post" = '工程师' AND "salary" = 1000 AND "notes" = '软件开发'
此时点击《刷新》按钮,我们可以看到,salary的值仍为1200,达到了并发控制的目的,保证数据的完整性。
3、选项“Key and Modified Columns”:
这种情况是比较更新前后Table的关键字和要修改(更新)的列值是否发生了变化,如果没有改变,更新成功,反之更新失败。对于本例,即判断关键字id和将要修改字段salary是否发生变化。
同上,当用户A更新完后,B用户点击“存盘”按钮,我们可以看到sqlsyntax返回如:
UPDATE "personnel" SET "salary" = 950 WHERE "id" = 100 AND "salary" = 1000
这里id字段没有改变,而此次将要修改的列salary值已由1000变为了1200,where条件不成立,因此更新失败,并弹出出错信息如下:
Row changed between retrieve and update.
No changes made to database.
UPDATE "personnel" SET "salary" = 950 WHERE "id" = 100 AND "salary" = 1000
此时我们点击《刷新》按钮,我们可以看到,salary的值仍为1200,也达到了并发控制的目的。
再举一个例子:
如果A用户更新的是备注notes字段,而B用户更新的是薪水salary字段,按照业务,这种操作是允许的,而在PB中会如何处理呢?
1、对于选项“Key Columns”: 因为关键字没有改变,更新成功。
2、对于选项“Key and Updateable Column”:
当用户A更新完后,B用户点击“存盘”按钮,我们可以看到sqlsyntax返回如:
UPDATE "personnel" SET "salary" = 950 WHERE "id" = 100 AND "name" = '令狐冲' AND "birthday" = '1975-05-01' AND "technical_post" = '工程师' AND "salary" = 1000 AND "notes" = '软件开发'
这里,id字段没有改变,salary字段也没有改变,但可修改(更新)列之一notes的值经A用户的修改,已由“软件开发”变为了“硬件维护”,where条件不成立,因此更新失败,系统将报出错信息。
此时点击《刷新》按钮,可以看到,salary的值仍为1200,notes的值为“硬件维护”。
3、对于选项“Key and Modified Columns”:
当用户A更新完后,B用户点击“存盘”按钮,我们可以看到sqlsyntax返回如:
UPDATE "personnel" SET "salary" = 950 WHERE "id" = 100 AND "salary" = 1000
这里,id字段没有改变,而将要修改的列salary值也没有改变(A用户只是修改了notes字段),where条件成立,因此更新成功。
此时点击《刷新》按钮,可以看到,salary的值为950,notes的值为“硬件维护”。注意这里B用户只是修改salary字段,并不修改notes字段,因此notes保留了A用户修改后的值。
从上面例子中我们可以得出如下结论:
1、“Key Columns”选项在控制数据完整性方面最弱,它所允许的并发操作是最多的,所禁止的并发操作发生的可能性非常小,只有当主键被更改后才起并发控制作用,当一条记录的关键字改变了才进行控制,这显然没有多大意义。实际上这种方法一般只在单机版的应用程序中使用,而在Client/Server模式中是很少使用的。
2、“Key and Updateable Columns”的是PB的默认选项,控制最为严格,可以实现最安全的并发控制,充分保证数据的完整性,但它也会禁止我们做一些本当允许的并发修改(如上面所说的第二例),是并发能力最差的方法。
3、“Key and Modified Columns”选项可以说是前两者的折衷,在控制数据完整性和严格性方面比第一项强,比第二项弱,在允许的并发操作数量方面比第一项少,比第二项多。
至于在程序中选取哪一种控制比较合适,我们应该根据应用的具体情况来选择。
对于并发控制,我们还需要在程序中捕获 DBMS 的出错号,再显示相应的错误信息,否则PowerBuilder给出的那些出错信息,一般用户是看不懂的。这项功能可在数据窗口的dberror事件中编写代码实现。
(七)结束语
以上程序在以下环境中测试通过:
开发工具:PowerBuilder6.5
数据库:Sybase SQL Anywhere 5.0
操作系统:Windows98
网络:Windows98 局域网
分享到:
相关推荐
这个例子展示了如何在PowerBuilder中利用DataWindow的灵活性和事件驱动的编程模型,创建一个用户交互式的倒计时功能,为用户提供了一种直观的方式来追踪和管理时间。对于初学者和有经验的PB开发者来说,这是一个很好...
2. **事件驱动编程**:PB 使用事件驱动模型,开发者需要监听并响应特定事件,比如Timer事件,来定时更新文本位置,实现文字的滚动。 3. **字符串处理**:在PB中,可能需要使用字符串函数,如Substring、Right、Left...
- **简化开发流程**:提供了更简单的开发模型,使得创建复杂的应用和服务变得更加容易。 通过这些技巧和技术的应用,开发人员可以更高效地使用PowerBuilder来构建复杂的应用程序,特别是在Web开发领域。
在IT行业中,尤其是在软件开发领域,PowerBuilder(简称PB)是一种流行的企业级应用程序开发工具,以其强大的数据窗口(DataWindow)功能而闻名。数据窗口是PB的一个核心组件,用于显示和操作数据库中的数据,可以...
PB的核心特性之一是其数据窗口(DataWindow)组件,它能方便地进行数据展示、查询、编辑和报表制作。在PB中,数据窗口可以以多种格式显示数据,如表格、图表、网格等,并支持SQL语句的自定义编写,提供强大的数据...
4. **数据导入导出**:PB可以将DataWindow中的数据导入到Excel,或者将Excel数据加载到DataWindow中,这在数据迁移、报表生成中非常有用。 5. **事件处理**:PB可以监听Excel的事件,如工作簿打开、关闭事件,...
3. **DataWindow**:DataWindow是PB的核心组件,它负责与数据库交互。开发者可以通过可视化方式设计DataWindow,支持多种数据库查询、排序、过滤、分组等功能,还可以自定义报告和界面样式。 4. **Script语言**:PB...
通常,这样的代码会涉及对DataWindow对象的编程,使用DataWindow的API或者特定的Excel对象模型(如Microsoft Excel Object Library)来创建和填充新的Excel工作簿。 2. **license.txt**:这是一个许可协议文件,...
在PB编程中,熟练掌握数据窗口(DataWindow)、事件驱动编程、对象的创建与使用、脚本语法等是关键。数据窗口是PB的核心组件,用于展示和操作数据库中的数据。了解如何自定义数据窗口的列、过滤、排序和计算是提高...
开发者需要理解PB的打印模型,并能熟练使用DataWindow控件的相关API来实现这些功能。 为了充分利用这个资源,开发者需要导入pbl文件到他们的PB环境中,然后查看和运行pbt工程,理解代码逻辑并根据自己的需求进行...
9. **WDL文件**:"PB开发人员指南.wdl"可能是一个Web Datawindow的定义文件,用于描述在Web环境下的DataWindow行为。学习如何读取和编辑WDL文件,以适应Web应用程序的需求。 10. **学习资源与实践**:了解在哪里...
PB支持多种数据库,如Oracle、SQL Server、MySQL等,提供面向对象的编程模型,简化了数据库应用的开发流程。 2. PowerBuilder环境 在PB环境中,主要包括工作区(Workspace)、项目(Project)、库(Library)和数据...
4. **对象模型**:PB的对象模型包括窗口、菜单、按钮、数据窗口等,每个对象都有其属性、方法和事件。PB help可以提供这些对象的详细说明,帮助开发者理解和使用。 5. **数据窗口对象**:这是PB的核心组件,用于...
在PB VIP开发查询中,我们可能涉及到的技术包括:优化SQL查询语句以提高性能、使用DataWindow进行高效数据访问、利用PB的事件驱动编程模型来控制程序流程、以及集成外部代码库以增强功能。同时,PB的脚本语言PBL...
PB支持多种数据库系统,如Oracle、SQL Server、MySQL等,提供了一种面向对象的编程模型,使得开发人员可以高效地编写应用程序。 二、PB编程环境 PB的集成开发环境(IDE)提供了丰富的功能,包括代码编辑器、设计器...
开发者可能还会利用PB的事件驱动模型,当数据发生变化时自动更新显示,以实时反映生产状态。 关于排序,PB提供了两种基本的排序方式:在SQL语句中指定排序(ORDER BY子句)和在DataWindow中进行排序。在SQL中排序是...
PB是由Sybase公司(现已被SAP收购)开发的一种集成开发环境(IDE),它提供了强大的数据窗口(DataWindow)组件,使得数据库操作变得简单。PB支持事件驱动编程模型,允许开发者通过图形化界面设计应用程序,大大...
这个"PB模型实例"压缩包可能是包含了一系列使用PowerBuilder编写的程序示例,旨在帮助学习者理解并掌握PB的编程技巧和最佳实践。 PowerBuilder的核心特性包括其强大的数据窗口(DataWindow)组件,该组件允许开发者...
在编程工具为PB9的情况下,开发者可能使用了PB9提供的对象模型和API,比如DataWindow对象来显示图片,或者使用Event处理函数来响应用户的鼠标操作。为了获取摄像头数据,他们可能使用了DirectShow或Windows Media ...
PB采用事件驱动编程模型,可以监听打印相关的事件,如`BeforePrint`和`AfterPrint`,在这些事件处理函数中实现打印机的切换逻辑。 7. **错误处理**: 在自动选择和切换打印机的过程中,可能遇到各种问题,如...