在PB中动态修改SQL语句
- 格式:docx
- 大小:17.28 KB
- 文档页数:2
PB获取或操作数据窗⼝语句的⽅法1、setsqlselect⽤法:ls_select=getsqlselect //通过getsqlselect取得当前数据窗⼝的查询语句ls_where=" " //给变量ls_where赋值,将所要添加的限定条件赋给此变量,但应考虑到select⼦句与where⼦句之前的空格dw_1.setsqlselect(ls_select+ls_where) //通过setsqlselect将⽣成的查询语句更新⾄数据窗⼝dw_1.event ue_retrieve()2、dw_1.modify⽤法:Old_Select=dw_1.Describe("DataWindow.Table.SQLSelect ")ls_select=getsqlselectls_where=" "dw_1.modify("DataWindow.Table.Select='" + ls_select+ls_where + " ' ")dw_1.settransobject(SQLCA)dw_1.retrieve()dw_1.object.DataWindow.Table.Select=Old_Select更新完后可⽤以下语句取出select语句查看并调试messagebox("",string(dw_1.Describe("DataWindow.Table.SQLSelect ")))⽹上有贴⼦说此语句只能更改DW查询语句中的where⼦句,暂未证实3、dw_1.object.DataWindow.Table.Select=" " ⽤法:此种⽤法与dw_1.modify()基本相同,只是使⽤dw_1.modify()时,在()中需要使⽤双引号把其中的DataWindow.Table.Select以及其后的变量引起来,需要考虑引号的对应关系问题,⽽此种⽤法则相对简单⼀些Old_Select=dw_1.Describe("DataWindow.Table.SQLSelect ")ls_select=" select …… from ……"ls_where=" ……"ls_having=" …… "ls_groupby=" …… "dw_1.object.DataWindow.Table.Select=ls_select+ls_where+ls_having+ls_groupbydw_1.settransobject(SQLCA)dw_1.retrieve()dw_1.object.DataWindow.Table.Select=Old_Select感觉此语句最为强⼤,⽤起来也顺⼿,我喜欢注意:在动态修改sql语句时,select段可以修改,但应确保select后⾯跟随的字段个数以及类型应与建⽴数据窗⼝时选择的字段个数和类型相同,否则报错。
在PB中动态修改SQL语句数据库应用程序通常进行一项确定的工作,在编写和编译时就可以确定完整的SQL语句,但是在编译时不能确定SQL语句的具体格式和参数时,只能在程序运行过程中构造SQL语句,需要使用动态SQL语句。
以Format 4 动态SQL语句为例,使用格式如下:DECLARE Cursor | ProcedureDYNAMIC CURSOR | PROCEDUREFOR DynamicStagingArea ;PREPARE DynamicStagingArea FROM SQLStatement{USING TransactionObject} ;DESCRIBE DynamicStagingAreaINTO DynamicDescriptionArea ;OPEN DYNAMIC Cursor | ProcedureUSING DESCRIPTOR DynamicDescriptionArea} ;EXECUTE DYNAMIC Cursor | ProcedureUSING DESCRIPTOR DynamicDescriptionArea ;FETCH Cursor | ProcedureUSING DESCRIPTOR DynamicDescriptionArea ;CLOSE Cursor | Procedure ;---- 在使用动态SQL语句时,需准备DynamicStagingArea对象(全局对象SQLSA)和DynamicDescriptionArea对象(全局对象SQLDA)。
定义游标或过程,读取PREPARE语句中的SQL语句以及语句中说明的参数和类型,执行FETCH语句后,调用相关的函数逐条读取并处理检索结果。
---- 动态SQL语句虽然解能够在程序运行过程中构造SQL语句,但在实际应用中较少使用。
若SELECT语句的结果序列一定,可以通过重新指定DataWindow对象的SELECT语句的方法,达到动态修改SQL语句的功能。
PB动态SQL语句PowerBuilder的嵌入式SQL语句只能支持一些固定的标准的SQL语句,即在进行程序代码编译处理时这些SQL语句必须是确定的,另外这种方式也不能执行像Creat Table,Creat Database等这些数据库定义的语句(DDL)。
因此这种嵌入式SQL语句在实际应用中有一定的局限性。
为克服这种方式的局限性,可以使用动态SQL语句,这种方式可以完成嵌入式SQL语句无法实现的功能。
如建库、建表这一类的数据库定义语句(DDL);其次,由于动态SQL语句允许在执行时才确定到底要执行怎样的SQL语句,因此使用动态SQL语句可以使程序实现参数化设计,具有很大的灵活性和通用性。
一、动态SQL语句的应用分析 PowerBuilder提供了四种格式的动态SQL语句,每种格式都有自己不同的特点和作用。
(一)第一种格式当执行没有输入参数并且没有返回结果集的SQL语句时可以使用这种格式,这种格式使用比较简单,其实现的操作也比较少。
1 语法EXECUTE IMMEDIATE SQLStatement{USING TransactionObject};其中SQLStatement是要执行的SQL语句,可以直接用引号将要执行的SQL 引起来用,或者用字符串变量的形式提供SQL语句。
通过使用字符串变量可以在具体执行的时候才指定要执行什么样的SQL语句。
TransactionObject是用户所使用的事务对象,缺省为SQLCA。
2 应用实例①建立一张数据库表(base),SQL语句的表述用引号引起来直接使用。
EXECUTE IMMEDIATE‘CREATE TABLE base(code char(6),name char(30))’USING SQLCA;②执行对数据库记录的操作,在表base中插入一条记录,SQL语句通过字符串变量传递执行语句。
STRING lsSQLLsSQL=”INSERT INTO TABLE base VALUES(’320201’,’市中区支行’)”EXECUTE IMMEDIATE :lsSQL;(二)第二种格式当执行带输入参数但没有返回结果集时的SQL语句可以采用第二种格式。
1.插入数据在数据库中插入一条数据使用INSERT语句,格式如下:INSERT INTO 表名(字段列表)VALUES (值列表){USING 事务对象};不同的字段使用逗号(“,”)分隔,并且不包含blob类型的字段;值列表中不同的值之间用逗号分隔,和字段列表中字段的类型对应兼容(最好类型相同),并且字符型和日期型取值用引号引起来。
省略事务对象时使用默认的全局事务对象SQLCA。
下面是一个向表中增加记录的SQL语句:insert into dept (deptno,deptname,workers) values (:ls_deptno, "销售部",10);该例子向表dept中插入一条记录,给该表中的字段deptno赋值为变量ls_deptno的取值,给字段deptname赋值为“销售部”,给字段workers赋值为10。
可能该表中还包含其他的字段,但是一般情况下,这三个字段中最起码应该有主键,除非使用了Identify类型的字段,因为主键肯定是不允许为空的。
如果该表就包含这三个字段,上面的SQL语句可以简写成:insert into dept values (:ls_deptno, "销售部",10);2.删除数据SQL语句删除数据是以行为单位删除的,不能删除某行中某字段的数据。
删除数据的SQL 语句格式是:DELETE FROM 表名WHERE 条件表达式{USING 事务对象};删除游标中和当前数据对应的记录可以使用下面格式的语句:DELETE FROM 表名WHERE CURRENT OF 游标名称;例如,下面的例子删除表dept中workers=10的所有记录:delete from dept where workers=10;再如,下面的例子是删除和光标中当前数据对应的记录:delete from dept where current of dept_cur;3.修改数据使用修改语句可以修改数据表中的一条或多条记录中的一个或多个字段的取值。
[PB]-动态数据窗口〓创建动态数据窗口若要动态创建数据窗口,需要使用函数Create,该函数的语法如下:dw_1.Create(syntax{,errorbuffer})其中,dw_1是数据窗口控件的名称,该数据窗口控件要和新创建的数据窗口对象相关联。
syntax是用来描述创建数据窗口对象的确切语法的字符串。
errorburrer是可选项,用来保存创建数据窗口对象过程中发生的错误信息。
如果不指定该参数,就会在发生错误时显示一个错误信息的提示窗口。
如果创建成功该函数返回1,否则返回-1,如果参数为null则函数返回null。
由于Create函数成功创建数据窗口对象后,要改变dw_1数据窗口控件所关联的数据窗口对象,因此,需要重新为数据窗口设置事务对象(使用函数SetTransObject或者SetTrans)。
获取创建数据窗口的语法有多种方法,可以对相关的SQL语句使用SyntaxFromSQL函数,也可以使用对已经创建好的数据窗口对象使用LibraryExport函数。
因为创建数据窗口的语法比较复杂,即使使用了LibraryExport输出已有数据窗口对象的语法,操作起来也相当费劲。
所以,更为通用的是前面一种方法。
这种方法配合一定的编程技巧,让用户指定要创建的数据窗口对象的SQL语句,使用户有更多的自由和选择。
使用这种方法,肯定用到函数SyntaxFromSQL,它的语法是:transaction.SyntaxFromSQL(SQLselect,presetation,err)其中,transaction是事务对象的名称,该事务对象必须正确地设置了相关参数,并且和数据库建立了联结。
SQLselect是用来创建数据窗口的SQL语句,为String 类型。
presentation是要创建的数据窗口对象的显示风格,为String类型。
简单的格式是:Style(Type=presentationstyle)其中Style和Type都是保留字,presentationstyle的取值有Tabular,Grid,Form,Graph,Group,Label和Nup,其中Tabular是缺省类型。
Q: 如何在PB5中自动生成行号A1:自动生成行号的方法很多,你可以看看PB的例子就知道了。
目前我用的方法是,先用SQL语句统计表中最大的行号,把结果保存到一个变量中去,然后再对此变量进行加1不就可以了吗?但这种做法只是从最大的行号开始产生行号,产生最小的行号也是类似的。
--------------------------------------------------------------------------------Q: delelte数据窗口中若干行,然后update,出现: “rows changed between retrieve and update No changes made to database... Delete from table where ...." 请教是何缘故,该数据窗口是updatable 的,未设置关键字。
A1 : 试试更改数据窗口的Update Properties中的'Where Clause for Update/Delete'中的选项。
--------------------------------------------------------------------------------Q: 如何能够作到,在打印一个DataWindows后不自动换页,而继续打印下一个DataWindows?谢谢A1:在PrintPage事件中返回0--------------------------------------------------------------------------------Q:我在table中改了一个字段的类型,回来一看,相应的datawindow字段在运行时再也无法输入东西了,请问哪位大虾帮我分析一下.Thanks.A1: datawindow具有自己的SQL语法,该语法和数据库后台中的变化不能时时响应,因此,当后台的数据库发生修改后,应该手工修改datawindow中的列定义,如:将变化的列删除,再次添加就可以了。
PB数据窗口技巧大全PB数据窗口是PowerBuilder语言中的一种常用控件,用于显示和操作数据。
在实际项目开发中,掌握一些PB数据窗口的技巧能够提高开发效率和用户体验。
下面是一些常用的PB数据窗口技巧的详细介绍,包括动态数据源、处理数据更新、格式化数据、控制数据窗口行为等方面。
1. 动态数据源:PB数据窗口支持通过修改SQL语句和参数实现动态查询。
可以通过修改dw_1.sqlsyntax和dw_1.settransobject等属性实现动态数据源切换或过滤。
2. 处理数据更新:PB数据窗口提供了一些方法来处理数据的插入、更新和删除。
可以使用dw_1.insertrow、dw_1.updaterow和dw_1.deleterow等方法来实现数据的增删改操作。
3. 格式化数据:PB数据窗口提供了一些格式化数据的方法,可以通过修改数据窗口列的format属性来实现对数据的格式化。
例如,可以使用dw_1.modify表示列的format属性来自定义数据的显示格式。
4. 排序和过滤数据:PB数据窗口提供了排序和过滤数据的功能。
可以通过修改dw_1.setsort和dw_1.setfilter等方法实现对数据的排序和过滤。
5. 控制数据窗口行为:PB数据窗口提供了一些属性和方法来控制数据窗口的显示效果。
例如,可以使用dw_1.retrieve来重新检索数据,使用dw_1.setitemstatus来设置数据窗口的状态等。
6.多表连接查询:PB数据窗口支持多表连接查询,可以通过在SQL 语句中使用连接符号和条件来实现多表连接查询的功能。
7.数据窗口插入计算列:PB数据窗口支持插入计算列,可以通过在SQL语句中使用函数和表达式来插入计算列实现对数据的计算和处理。
8.数据窗口多级分组:PB数据窗口支持多级分组,可以通过在数据窗口中设置分组列和聚合函数来实现数据的分组和统计。
9.数据窗口嵌套:PB数据窗口支持嵌套,可以在一个数据窗口中插入另一个数据窗口,实现数据的嵌套显示和处理。
这是刚毕业时在某一“大”公司使用PB6.5开发联通营帐系统时的笔记虽然好久没有也许以后也不会再使用pb开发程序了但这算是我使用过的唯一一个前端专业开发工具把笔记记录下来权当作纪念吧_ //PB中标准调用sql语句ls_sql quotselectroad_name from bb_data_wide_bus_temp_t where register_number quotls_register_number quotquot declare cur_get dynamic cursor for sqlsa prepare sqlsa from :ls_sql open dynamic cur_get fetch cur_get into :ls_value if sqlca.sqlcode ltgt 0 then messagebox操作信息提取失败exclamation end if close cur_get //PB中标准循环调用sql语句DECLARE cur_sql DYNAMIC CURSOR FOR SQLSA PREPARE SQLSA FROM :ls_sql OPEN DYNAMIC cur_sql do while sqlca.sqlcode 0 FETCH cur_sql INTO :ls_register_number:ls_complete_note ll_sqlcode sqlca.sqlcode if ll_sqlcode lt 0 then CLOSE cur_sql af_disconnect messagebox错误提示检索受理编号错误StopSign return elseif ll_sqlcode 100 then exit end ifddlb_register_number.additemtrimls_register_number ls_complete_note loop CLOSE cur_sql //窗口open事件通用脚本//置窗口居中af_center_windowthis //连接数据库af_connect //定义变量dataWindowChild dwc //获取城市代码下拉列表并取值dw_city_code.getChildcity_codedwc dwc.setTransObjectsqlcadwc.Retrievegs_citycodegi_citylevel dw_city_code.setTransObjectsqlcadw_city_code.Retrieve dw_city_code.setItem1city_codedwc.getItemString1city_codeis_city_code dw_city_code.getItemStringdw_city_code.getRowcity_code //获取业务类型下拉列表并取值dw_service_kind.getChildservice_kinddwcdwc.setTransObjectsqlca dwc.Retrieve dw_service_kind.setTransObjectsqlcadw_service_kind.Retrieve dw_service_kind.setItem1service_kind10 ii_service_kinddw_service_kind.getItemNumberdw_service_kind.getRowservice_kind //获取申请事项下拉列表并取值dw_apply_event.getChildapply_eventdwc dwc.setTransObjectsqlca dwc.Retrieveii_service_kind dw_apply_event.setTransObjectsqlcadw_apply_event.Retrievedw_apply_event.setItem1apply_eventdwc.getItemNumber1apply_event ii_apply_event dw_apply_event.getItemNumberdw_apply_event.getRowapply_event //激发查询事件cb_query.TriggerEventclicked //断开数据库af_disconnect //查询按钮通用脚本//连接数据库af_connect //定义变量dataWindowChild dwc //dw_1检索数据dw_1.setTransObjectsqlca dw_1.Retrieveii_service_kind //dw_2检索数据intli_rowli_row_temp dw_2.getChildactiondwc dwc.setTransObjectsqlcadwc.Retrieveii_service_kind dw_2.setRowFocusIndicatorhand dw_2.setTransObjectsqlca li_row_temp dw_2.Retrieveii_apply_eventii_service_kindis_city_codedw_2.scrollToRowli_row_temp //如果未检索到数据插入一空行有数据就过滤string ls_filter int li_action if li_row_temp 0 then dw_2.insertRow0 else for li_row 1 todw_2.rowCount li_action dw_2.getItemNumberli_rowaction ls_filter action ltgt stringli_action dw_1.setFilterls_filter dw_1.filter next end if //断开数据库af_disconnect //增加按钮通用脚本//变量定义int li_stepli_actionli_auto_statusli_row //确认选择要增加的记录if dw_1.getSelectedRow0 0 then MessageBox提示信息请选择要添加的记录exclamation return end if //取出要增加的信息li_stepdw_2.getItemNumberdw_2.getRowstep li_actiondw_1.getItemNumberdw_1.getSelectedRow0action li_auto_statusdw_1.getItemNumberdw_1.getSelectedRow0auto_status //添加信息li_rowdw_2.insertRow0 dw_2.setItemli_rowstepli_step dw_2.setItemli_rowactionli_actiondw_2.setItemli_rowauto_statusli_auto_status dw_2.scrollToRowli_row //删除按钮通用脚本//删除前先确认IF dw_2.GetRow 0 THEN MessageBox提示信息请选择要删除的记录exclamation Return ELSE IF MessageBoxquot提示信息quotquot确实要删除指定的记录quotQuestionYesNo2 2 THEN Return dw_2.DeleteRowdw_2.getRow END IF //保存按钮通用脚本//连接数据库af_connect //定义变量stringls_city_codels_error int li_service_kindli_apply_eventli_rowli_step dataWindowChild dwc //检测数据是否发生变化dw_2.AcceptText IF dw_2.ModifiedCountdw_2.DeletedCount 0 THEN MessageBoxquot操作提示quotquot数据未发生变化无需保存quotexclamation return END IF //检测是否为空或零dw_2.setSortstep adw_2.sort FOR li_row 1 TO dw_2.RowCount li_stepdw_2.GetItemNumberli_rowstep IF IsNullli_step OR li_step 0 THEN MessageBox操作提示步骤不能为空或零请重新输入exclamation dw_2.setRowli_row Return END IF NEXT //保存dw_2.SetTransObjectsqlca if dw_2.update 1 then commit messageboxquot提示信息quotquot保存成功quot dw_2.ScrollToRowdw_2.RowCount else ls_error sqlca.sqlErrText rollback messageboxquot提示信息quotquot保存失败quot char13 ls_errorstopSign return end if //断开数据库af_disconnect //打印按钮通用脚本if dw_1.rowCount gt 0 then if PrintSetup -1 then messagebox提示信息打印机设置出错Exclamation return else if dw_1.printtrue 1 then //显示可以取消打印的对话框Messagebox提示信息quot打印成功quot else Messagebox提示信息quot打印失败quotstopSign end if end if else Messagebox提示信息quot没有数据可以打印请先查询数据quotexclamation return end if //导出按钮通用脚本if dw_1.rowcount lt 0 then messageBox提示信息没有数据可以导出请先查询exclamation return end if ifdw_1.SaveAStexttrue 1 then messageBox提示信息导出成功end if //导入按钮通用脚本//变量定义string ls_pathfilels_filels_titlels_extls_filter int li_posli_fileid longll_buffer //变量赋值ls_title quot请选择数据文件quot ls_ext quottxtquot ls_filter quot文本文件.txt.txt全部文件..quot li_fileidGetFileOpenNamels_titlels_pathfilels_filels_extls_filter ifli_fileid 0 or ls_file quotquot then return end if sle_file_name.text ls_pathfile cb_ok.enabled true //退出按钮通用脚本closeparent 或closeWithReturnparentreturnvalue //调用过程通用脚本if dw_wp.rowcount lt 0 then return //变量定义string ls_sqlls_err_info stringls_register_numberls_accept_cityls_departmentls_oper_person integerli_err_codeli_apply_event //变量赋值ls_register_numberdw_wp.getitemstring1register_number ls_accept_city gs_citycode li_apply_eventdw_wp.getitemnumber1apply_event ls_department gl_dealerid ls_oper_persongs_workerid //连接数据库af_connect //调用配号撤单过程ls_sql quotexecutebb_pstn_assign_no_repeal_pquot declare proc_assign_no_repeal dynamic cursor for sqlsa prepare sqlsa from :ls_sql open dynamic proc_assign_no_repealusing :ls_register_number:ls_accept_city:li_apply_event:ls_department:ls_oper_person if sqlca.sqlcode -1 then ls_err_info sqlca.sqlErrText close proc_assign_no_repeal Rollback Messageboxquot错误信息1quotquot执行异常quot ls_err_infostopSignaf_disconnect return End if fetch proc_assign_no_repeal into :li_err_code:ls_err_info if li_err_code lt 0 then close proc_assign_no_repeal Rollback Messageboxquot错误信息2quotquot执行异常quot ls_err_infostopSign af_disconnect return end if closeproc_assign_no_repeal commit //断开数据库af_disconnect //撤单成功后打印工单dw_wp.print //PB某些控件的中文显示问题假如PB 的ListView 不能正常显示中文则应该将ListView 的FontCharSet 属性设置成其他类型。
如何在PB中使用動態SQL語句執行沒有輸入參數並且沒有返回結果集的SQL語句。
1.語法其中SQLStatement是要執行的SQL語句,可以直接用引號將要執行的SQL引起來用,或者用字串變數的形式提供SQL語句。
通過使用字串變數可以在具體執行的時候才指定要執行什麼樣的SQL語句。
TransactionObject是用戶所使用的事務物件,缺省為SQLCA。
3.應用實例①建立一張資料庫表(base),SQL語句的表述用引號引起來直接使用。
②執行對資料庫記錄的操作,在表TEMP_TEST中插入一條記錄,SQL語句通過字串變數傳遞執行語句。
執行帶輸入參數但沒有返回結果集時的SQL語句。
1.語法其中:DynamicstagingArea是PowerBuilder提供的一種資料類型。
PowerBuilder本身提供了一個名字為SQLSA的DynamicstagingArea類型的總體變數,用於保存要執行的動態SQL語句資訊。
4.應用實例刪除TEMP_TEST表中的滿足一定條件的記錄。
執行有輸入參數並且返回結果集的格式在編譯時可以確定的SQL語句。
1.語法其中cursor是用戶所定義的游標的名字。
# 應用實例將表TEMP_TEST中的ID欄位大於1的所有記錄讀取出來並分別進行相應處理。
int li_idstring ls_sql,ls_name,ls_filterls_filter = 1ls_sql="SELECT id,name FROM temp_test WHERE id>?"DECLARE c1 DYNAMIC CURSOR FOR SQLSA;PREPARE SQLSA FROM :ls_sql;OPEN DYNAMIC c1 USING :ls_filter;FETCH c1 INTO :li_id,:ls_name;DO WHILE SQLCA.SQLCODE=0 . //對滿足條件的記錄根據要求分別進行處理 . FETCH c1 INTO :li_id,:ls_name;LOOPCLOSE c1;執行有輸入參數並且返回結果集的格式在編譯時無法確定的SQL語句。
PowerBuilder不仅支持在PowerScript中使用标准嵌入SQL语句,而且支持使用动态SQL语句。
动态SQL语句可以解决嵌入SQL语句不支持DDL语句的问题,还能够在运行时构成SQL语句以解决在编译时不知道语句的具体格式或参数的问题。
作者在“抚顺机动车辆管理信息系统”的开发过程中,对动态SQL语句的使用有了深刻的体会,车辆信息项目繁多而且组合条件复杂多变,使用该语句,不仅查询速度较高而且使用灵活可靠。
下面就各动态SQL语句的使用格式、方法及各自的特点给予简单介绍,然后以查找车辆为例介绍动态SQL语句(格式4)在组合查询中的应用。
一、态SQL语句格式PowerBuilder 有四种动态SQL格式,每种格式用于处理编译过程中的不同情况。
格式1:既没有输入参数,也没有输出结果集格式2:有输入参数,但没有输出结果集格式3:输入参数和结果集的列已知格式4:输入参数和结果集在编译时有一个或都未知1.动态SQL语句格式格式EXECUTE IMMEDIATE SQLStatement {USING TransactionObject} ;参数描述SQLStatement 是包括一条有效SQL语句的字符串。
该字符串可以是常量或者冒号后面跟PowerBuilder变量(如:mysql)。
该字符串必须只包括在一行上,且不能包含表达式。
TransactionObject(可选项)数据库的事务对象名执行这种格式的SQL语句没有结果集、也不需要输入参数。
这种格式可用来执行所有形式的数据定义语言(DDL)。
以下是一段建立车辆临时视图的例子:string sqlsql=“CREATE VIEW temp_vehicle AS SELECT code , master FROM vehicle ”EXECUTE IMMEDIATE :sql USING SQLDA;2. 动态SQL语句格式格式PREPARE DynamicStagingArea FROM SQLStatement {USING TransactionObject} ;EXECUTE DynamicStagingArea USING {ParameterList} ;参数描述DynamicStagingArea DynamicStagingArea变量名(通常为SQLSA)SQLStatement包含一条有效SQL语句的字符串。
在PB 中巧用下拉数据窗口---- PowerBuilder 作为目前比较流行的一种开发工具,有其独到之处,那就是数据窗口(DataWindow)。
可以说,数据窗口是PowerBuilder 的核心,在对数据库的开发过程中,无论是录入、查询、统计还是报表,都离不开数据窗口。
但是,除了数据窗口,PB 还提供了下拉数据窗口(DropDown DataWindow),下拉数据窗口的使用,使数据窗口更灵活,更方便,下面举例介绍在数据窗口中使用下拉数据窗口的一些技巧。
---- 在用数据窗口作数据录入时,经常用到代码录入,即对经常输入的某些值设置代码,录入时直接录入代码即可。
例如,有两个表,主表main_table 和代码表code_table,结构如下:main_table字段名类型长度描述Id integer 标识号Name char 8 姓名Sex char 4 性别City Varchar 30 城市Unit Varchar 40 单位---- 下面,详细讨论如何使用下拉数据窗口:一、静态设计下拉数据窗口---- 首先对主表和代码表设计两个数据窗口dw_main 和dw_code,其中dw_main 包括字段id,name,sex,city 和unit;dw_code 包括字段code 和data。
假设unit 字段有几个常用值可使用代码录入,则在设计dw_main 时,用鼠标右键点击字段unit,在下拉菜单中选择Properties...(属性),则系统会弹出unit 列的属性对话框,在其中选择Edit (编辑)项,并在Style(风格)下拉列表框中选择DropDownDW 项,然后在下面的Options(选项)框中作具体的选项配置:在DataWindow 下拉框中选择已设计好的代码数据窗口dw_code 作为下拉数据窗口;在DisplayColumn(显示列)下拉框中选择code 字段;在Data Column(数据列)下拉框中选择data 字段,这表示显示的是code 字段的内容,而实际存于表main_table 中的是data 字段的内容。
CSDN技术中心PB学习笔记之SQL语句任何对sql类数据库操作的语言必学的:),下面的是PB版本,有一些PB的特性.SQL语句sql语句以;结束,可写成多行形式而不用&1、SELECT注意:变量前加:一个例子:SELECT Employee.Emp_id,Employee.Emp_name,Employee.Emp_salary,Dept.Dept_nameFROM Employee,DeptWHERE (Emp_name like ‘张%‘)AND (Emp_sex=‘男‘)AND Employee.Dept_id=Dept.Dept_idORDER BY Employee.Emp_id;给变量的例子:Dec Emp_salarySELECT max(Emp_salary)INTO :Emp_salaryFROM Employee;2、INSERT一个例子:Int Emp_nbrString Emp_nameEmp_nbr=Integer(sle_number.Text)Emp_name=sle_name.TextINSERT INTO Employee(employee.Emp_nbr,employee.Emp_name)VALUES(:Emp_nbr,:Emp_name)USING Emp_tran;3、UPDATE一个例子:UPDATE Employee//表名SET emp_name=:sle_Name.T ext //修改WHERE Employee.emp_nbr=:Emp_nbr;//修改条件4、DELETE一个例子:DELETE FROM Employee //从表EmployeeWHERE Emp_nbr <100;删除条件满足的记录5、CONNECT和DISCONNECT执行DISCONNECT前自动执行COMMIT6、COMMIT和ROLLBACK7、使用游标(用来保存多条记录操作)DECLARE,OPEN,FECTH...INTO...:NAME,CLOSE,DELETE(删除游标指向的记录),UPDATE(修改游标指向的记录)利用游标打开多个记录的例子//声明powerscript变量,存放读出的雇员姓名String emp_cur CURSOR FORSELECT emp_name FROM EMPLOYEEWHERE emp_state=:sle_1.text;//打开游标,执行SELECT语句OPEN emp_cur;//从结果集中取第一条记录FETCH emp_cur INTO "emp_name_var;//判断FETCH语句执行情况IF SQLCA.SQLCode<0 THENMessageBox("Datebase Error",&//显示错误信息SQLCA.SQLErrText,Exclamation!)RETURNEND IF//如果FETCH语句执行正确,用循环语句逐条取结果集中的记录,到取完DO WHILE SQLCA.SQLCode=0 //是否取完数据//把取出的雇员姓名加入下拉列表框中dlbl_1.additem(emp_name_var)//继续从结果集中取下一符合条件的数据FETCH emp_cur INTO :emp_name_var;LOOP//关闭游标CLOSE emp_cur;8、处理BLOB型数据(大部分语句只能对一条记录进行操作,多余则出错)SELECTBLOB,一个例子://声明BLOB型变量Emp_id_pic,用语存放Emp_pic列的数据Blob Emp_picSELECTBLOB Emp_picINTO :Emp_id_picFROM EmployeeWHERE Employee.Emp_Id="001"USING Emp_tran;//如果执行正确,在pb_1中显示照片IF Emp_tran.SQLCode=0 THENpb1.SetPicture(Emp_id_pic)END IFUPDATEBLOB一个例子:Integer fhBlob Emp_id_pic//以读方式打开一个流模式文件fh=FileOpen("c:\emp_100.bmp",StreamMode!) //判断打开文件是否成功IF fh<>-1 THEN//从文件中读取图形数据存于Blob型变量FileRead(fh,emp_id_pic)//关闭文件FileClose(fh)//修改表的emp_pic列UPDATEBLOB EmployeeSET emp_pic=:Emp_id_picWHERE EMp-Id="001";END IFIF SQLCA.SQLNRows>0 THEN//判断是否返回结果 COMMIT;/提交事务ELSEROLLBACK;//回滚事务END IF9、动态SQL语句事务对象,动态描述区(SQLSA),动态描述区(SQLCA)示例1:String MysqlMysql ="CREAT TABLE Employee"&+"(emp_id char(6)not null,"&+"emp_hbr integer not null,"&+"dept_id integer not null,"&+"emp_fname char(10) not null,"&+"emp_lname char(20) not null)"EXCUTE IMMEDIATE :Mysql;实例2:EXCUTE IMMEDIATE "DROP TABLE Employee" USING My_trans;等价于:String MysqlMysql+"DROP TABLE Employee"EXCUTE IMMEDIATE :Mysql USING My_trans实例3://在表中插入记录Int Dept_id_var=156String Dept_name_varSetNull(Dept_name_var)CONNECT;//PREPARE SQLCA //prepare的作用FROM "INSERT INTO dept VALUES(?,?)";EXCUTE SQLCA USING :Dept_id_var,:Dept_name_var;。
PB数据窗口常用函数方法在PB(PowerBuilder)中,数据窗口是一种非常常用的控件,用于显示和处理数据。
以下是一些PB数据窗口常用的函数方法:1. SetItem(li_row, ls_column, ls_value): 可以用来设置指定行列位置的单元格的值。
2. GetItemString(li_row, ls_column): 返回指定行列位置的单元格的字符串值。
3. SetItemStatus(li_row, ls_column, lsb_update): 可以设置指定单元格的更新状态,lsb_update为TRUE表示有更新,FALSE表示没有更新。
5. Retrieve(: 用于从数据库中检索数据并在数据窗口中显示。
6. Modify("sql"): 可以修改数据窗口的检索SQL语句,并重新检索数据。
7. InsertRow(li_row): 插入一行数据。
8. DeleteRow(li_row): 删除指定行数据。
9. Update(: 保存对数据窗口中数据的修改到数据库。
10. ResetUpdate(: 取消对数据窗口中数据的修改。
11. Reset(: 清空数据窗口中的所有数据。
12. SelectRow(li_row, lsb_select): 可以选择或取消选择指定行。
13. SelectText(li_start, li_end): 可以选择指定行列范围的文本。
14. GetColumnName(li_column): 返回指定列索引的列名。
15. GetColumnCount(: 返回数据窗口中的列数。
16. GetRowCount(: 返回数据窗口的行数。
17. GetRow(: 返回当前选中行的索引。
18. Find("value"): 在数据窗口中查找指定值,并返回先找到的行索引。
19. FindNext("value"): 在数据窗口中继续查找指定值,并返回下一个找到的行索引。
<转>在PB中控制数据窗口列的修改属性在编制管理信息应用系统中,一般都会碰到一个一路问题,那就是如何按照不同情况去控制表中的数据列,比如对于同一DATAWINDOW不同的用户有不同的操作(如对于数据录入人员可以更改数据,而对于查询人员一般不能更改数据),下面就以一个简单的工资表为例来讲明利用PB如安在DATAWINDOW 中控制列的修改方式。
工资表基本列如下:代码姓名工作时间基础工资浮动工资岗位工资知识分子补贴其它工资code name workdata basesa movesa stationsa bt othersachar varchar char decimal decimal decimal decimal deciaml在PB中有两种方式可控制列属性,一是静态方式,另一种是动态方式实现。
所谓静态方式就是在列的属性上通过选项实现。
所谓动态方式就是利用编程实现。
现分别给予介绍:一、静态方法(1)在datawindow中选中某列后点MOUSE右键,选“properities”后系统弹出一标签,选中“Edit”标签,将“Display Only”选项制为有较;(2)或者选中“Expression”标签,在“Protect Express”中填入“1”; (3)或者选中“Expression”标签,在“Protect Express”中填入条件表达式,如工作时间不满一年的人员不能修改,则写入“if(daysafter(date(workdate),today()) <= 365,1,0)”;(4)在datawindow中,将某列的Tab Order 值制为0,则该列因得不到焦点而不能被修改;(5)在DataWindow Painter 状态下选取Rows菜单,再选取Update Properties,弹出Specify Update Properties对话框,将Allow Updates 设为空。
优化你的PB程序(深圳:独孤求败2003-05-27)一、处理 SQL 语句1、缓冲 SQL 语句在应用程序中,有时需要反复调用同一组 SQL语句,在这种情况下,可以通过在应用中为这些 SQL 建立缓冲区来提高执行性能。
在缺省情况下,SQL 语句的缓冲区是关闭的,你可以通过如下语句打开它:SQLCACHE = n n 表示装入缓冲区的 SQL 语句数量(缺省为0)。
例如:dw_1.SetTransObject(sqlca)SQLCA.dbParm = "SQLCache = 0"dw_1.retrieve()如果将上例的 "SQLCache = 0" 改为 "SQLCache = 25",此句的执行效率将提高五分之一左右。
但应注意缓冲区的大小,否则也将影响程序执行的性能。
注:此方法对用 ODBC 和 ORACLE 连接的数据库非常有效。
2、捆绑变量请看下例:SQLCA.DBPARM = "DISABLEBIND=1"INSERT INTO DA_DH value S("1","河南0")INSERT INTO DA_DH value S("2","河南1")INSERT INTO DA_DH value S("3","河南2")INSERT INTO DA_DH value S("4","河南3")INSERT INTO DA_DH value S("5","河南4")INSERT INTO DA_DH value S("6","河南5")这里未使用捆绑变量,在插入是 PB 将重新处理每个带有新值的SQL语句。
mybatis⾃定义插件动态修改sql语句step1:定义Interceptor实现org.apache.ibatis.plugin.Interceptorimport mons.logging.Log;import mons.logging.LogFactory;import org.apache.ibatis.executor.Executor;import org.apache.ibatis.mapping.BoundSql;import org.apache.ibatis.mapping.MappedStatement;import org.apache.ibatis.mapping.ParameterMapping;import org.apache.ibatis.mapping.SqlSource;import org.apache.ibatis.plugin.*;import org.apache.ibatis.session.ResultHandler;import org.apache.ibatis.session.RowBounds;import org.springframework.beans.factory.annotation.Value;import java.util.Properties;/*** code by me* <p>* Data:2017/8/10 Time:11:28* User:lbh*/@Intercepts({@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),})public class FDNSqlInterceptor implements Interceptor {private static Log logger = LogFactory.getLog(FDNSqlInterceptor.class);@Value("${fdn.open}")private boolean fdnOpen;static int MAPPED_STATEMENT_INDEX = 0;// 这是对应上⾯的args的序号static int PARAMETER_INDEX = 1;static int ROWBOUNDS_INDEX = 2;static int RESULT_HANDLER_INDEX = 3;@Overridepublic Object intercept(Invocation invocation) throws Throwable {if(!fdnOpen){return invocation.proceed();}final Object[] queryArgs = invocation.getArgs();final MappedStatement mappedStatement = (MappedStatement) queryArgs[MAPPED_STATEMENT_INDEX];final Object parameter = queryArgs[PARAMETER_INDEX];final BoundSql boundSql = mappedStatement.getBoundSql(parameter);String sql = boundSql.getSql();if(sql.contains("xx_pro")){sql = sql.replace("xx_pro","xx_pro_fdn");}// 重新new⼀个查询语句对像BoundSql newBoundSql = new BoundSql(mappedStatement.getConfiguration(), sql, boundSql.getParameterMappings(), boundSql.getParameterObject()); // 把新的查询放到statement⾥MappedStatement newMs = copyFromMappedStatement(mappedStatement, new BoundSqlSqlSource(newBoundSql));for (ParameterMapping mapping : boundSql.getParameterMappings()) {String prop = mapping.getProperty();if (boundSql.hasAdditionalParameter(prop)) {newBoundSql.setAdditionalParameter(prop, boundSql.getAdditionalParameter(prop));}}queryArgs[MAPPED_STATEMENT_INDEX] = newMs;return invocation.proceed();}@Overridepublic Object plugin(Object target) {return Plugin.wrap(target, this);}@Overridepublic void setProperties(Properties properties) {}private MappedStatement copyFromMappedStatement(MappedStatement ms, SqlSource newSqlSource) {MappedStatement.Builder builder = new MappedStatement.Builder(ms.getConfiguration(), ms.getId(), newSqlSource, ms.getSqlCommandType());builder.resource(ms.getResource());builder.fetchSize(ms.getFetchSize());builder.statementType(ms.getStatementType());builder.keyGenerator(ms.getKeyGenerator());if (ms.getKeyProperties() != null && ms.getKeyProperties().length > 0) { builder.keyProperty(ms.getKeyProperties()[0]);}builder.timeout(ms.getTimeout());builder.parameterMap(ms.getParameterMap());builder.resultMaps(ms.getResultMaps());builder.resultSetType(ms.getResultSetType());builder.cache(ms.getCache());builder.flushCacheRequired(ms.isFlushCacheRequired());eCache(ms.isUseCache());return builder.build();}public static class BoundSqlSqlSource implements SqlSource {private BoundSql boundSql;public BoundSqlSqlSource(BoundSql boundSql) {this.boundSql = boundSql;}public BoundSql getBoundSql(Object parameterObject) {return boundSql;}}}step2:在mybatis的配置⽂件中加⼊plugin <plugins><plugin interceptor="xx.interceptor.FDNSqlInterceptor"></plugin></plugins>。
Mybatis插件实现动态修改SQL语句功能描述:通过使⽤Mybatis插件功能,拦截SQL并且进⾏动态修改处理MybatisPlugin类插件执⾏类@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})public class MybatisPlugin implements Interceptor {@Overridepublic Object intercept(Invocation invocation) throws Throwable {StatementHandler statementHandler = (StatementHandler) invocation.getTarget();BoundSql boundSql = statementHandler.getBoundSql();String sql = boundSql.getSql();// 做⼀些处理SQL语句;String newSql = sql;ReflectionUtils.setFieldValue(boundSql, "sql", newSql);return invocation.proceed();}@Overridepublic Object plugin(Object target) {return target instanceof StatementHandler ? Plugin.wrap(target, this) : target;}@Overridepublic void setProperties(Properties properties) {}}ReflectionUtils类public class ReflectionUtils {/*** 通过反射将object转map** @param obj* @return*/public static Map<String, Object> object2Map(Object obj) {Map<String, Object> map;try {Field[] fields = obj.getClass().getDeclaredFields();int fieldSize = fields.length;if (fieldSize > 0) {map = new HashMap<>(fieldSize);for (int i = 0; i < fieldSize; i++) {Field field = fields[i];makeAccessible(field);map.put(field.getName(), field.get(obj));}return map;}} catch (IllegalAccessException e) {}map = new HashMap<>(16);return map;}/*** 直接设置对象属性值,忽视private/protected修饰符** @param object* @param fieldName* @param value*/public static void setFieldValue(final Object object, final String fieldName, final Object value) {Field field = getDeclaredField(object, fieldName);if (field == null) {throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");}makeAccessible(field);try {field.set(object, value);} catch (IllegalAccessException e) {}}/*** 取对象的DeclaredField** @param object* @param fieldName* @return*/protected static Field getDeclaredField(final Object object, final String fieldName) {for (Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) { try {return superClass.getDeclaredField(fieldName);} catch (NoSuchFieldException e) {}}return null;}/*** 设置属性的访问权限** @param field*/protected static void makeAccessible(final Field field) {if (!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers())) {field.setAccessible(true);}}}MapperConfig配置类项⽬使⽤配置类注⼊Mapper插件@Configuration@MapperScan({"com.test.dao"})public class MapperConfig {@Beanpublic MybatisLogPlugin myPlugin() {return new MybatisPlugin();}}。
在PB中动态修改SQL语句
数据库应用程序通常进行一项确定的工作,在编写和编译时就可以确定完整的SQL语句,但是在编译时不能确定SQL语句的具体格式和参数时,只能在程序运行过程中构造SQL语句,需要使用动态SQL语句。
以Format 4 动态SQL语句为例,使用格式如下:
DECLARE Cursor | Procedure
DYNAMIC CURSOR | PROCEDURE
FOR DynamicStagingArea ;
PREPARE DynamicStagingArea FROM SQLStatement
{USING TransactionObject} ;
DESCRIBE DynamicStagingArea
INTO DynamicDescriptionArea ;
OPEN DYNAMIC Cursor | Procedure
USING DESCRIPTOR DynamicDescriptionArea} ;
EXECUTE DYNAMIC Cursor | Procedure
USING DESCRIPTOR DynamicDescriptionArea ;
FETCH Cursor | Procedure
USING DESCRIPTOR DynamicDescriptionArea ;
CLOSE Cursor | Procedure ;
---- 在使用动态SQL语句时,需准备DynamicStagingArea对象(全局对象SQLSA)和DynamicDescriptionArea对象(全局对象SQLDA)。
定义游标或过程,读取PREPARE语句中的SQL语句以及语句中说明的参数和类型,执行FETCH语句后,调用相关的函数逐条读取并处理检索结果。
---- 动态SQL语句虽然解能够在程序运行过程中构造SQL语句,但在实际应用中较少使用。
若SELECT语句的结果序列一定,可以通过重新指定DataWindow对象的SELECT语句的方法,达到动态修改SQL语句的功能。
运用时首先用Describe函数读取DataWindow对象的SELECT 语句,用Replace等函数修改出符合要求的SELECT语句,并且可以增加检索条件,再用SetSQLSelect函数为DataWindow控件指定修改后的SELECT语句。
---- 程序代码:
string sql_string,sql_new
long start_pos=1
string old_str //select语句中需要替换的字符串
string new_str //替换字符串,可以是结构相同的表名
dw_1.settransobject(sqlca)
sql_string=dw_1.Describe("DataWindow.Table.Select")
// Find the first occurrence of old_str.
start_pos = Pos(sql_string, old_str, start_pos)
// Only enter the loop if you find old_str.
DO WHILE start_pos > 0
// Replace old_str with new_str.
sql_string = Replace(sql_string, start_pos, &
Len(old_str), new_str)
// Find the next occurrence of old_str.
start_pos = Pos(sql_string, old_str, &
start_pos+Len(new_str))
LOOP
sql_new=sql_string+" where ……" //增加where字句
//判断setsqlselect 函数调用是否成功,不成功则返回
if (dw_1.setsqlselect(sql_new)=-1) then
messagebox("错误","不能修改SQL语句!",Exclamation!)
return
end if
dw_1.settransobject(sqlca)
dw_1.retrieve()
---- 使用SetSQLSelect有一定的要求和限制,更改后的SELECT语句在结构上必须与原先的语句匹配,在执行SetSQLSelect函数之前必须用SetTrans或SetTransObject函数设置DataWindow 控件的内部事务对象。
另外,DataWindow对象的数据源必须是一个不带参数的SELECT语句,如果需要使用检索参数,可以在程序代码中修改SQL Select语句。