在PB中动态修改SQL语句

数据库应用程序通常进行一项确定的工作,在编写和编译时就可以确定完整的SQL语句,但是在编译时不能确定SQL语句的具体格式和参数时,只能在程序运行过程中构造SQL语句,需要使用动态SQL语句。以Format 4 动态SQL语句为例,使用格式如下:

 

DECLARE Cursor | Procedure

    DYNAMIC CURSOR | PROCEDURE

    FOR DynamicStagingArea ;

 

PREPARE DynamicStagingArea FROMSQLStatement

    {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语句。

 

(要求按开始和结束时间查询相应用户所拥有的表)--我们的数据表是以操作员为所有者的,不同的操作员所拥有的数据表也不相同,这样查询时还要动态设置,表的所属者.

比如操作员s02所拥有的表为:s02.data_cfjl而s07拥有同样结构的表,但是他的表名为:s07.data_cfjl.....

 

先按自己的要求做一个数据窗口,不必设置检索条件,做完后可以看到这个DW的SQL语句如下:

 

SELECT s02.data_brjl.ghmc,  

        code_cwfl.cwflmc,  

        s02.data_cfjl.gjje,  

        s02.data_cfjl.jzje 

   FROM s02.data_brjl,  

        s02.data_cfjl,  

        code_cwfl 

  WHERE ( s02.data_brjl.xlh = s02.data_cfjl.xlh ) and 

        ( s02.data_cfjl.cwflbm = code_cwfl.cwflbm ) and 

        ( ( 1 = 2 ) )   

 

然后在窗口上加上两个设置时间的EDITMASK控件,分别命名为:em_1,em_2

格式为:yyyy-mm-dd hh:mm:ss

 

然后再增加一个按钮cb_search,在它的clicked事件里加入代码:

 

//其它代码略,只列出SETSQLSELECT()相关的语句.

......

string str_sqlselect,str_sqlwhere

str_sqlwhere=" and "+strzh+".data_brjl.cfjlsj>='"+em_1.text+"' and"+strzh+"data_brjl.cfjlsj<='"+em_2.text+"'"

 

str_sqlselect="SELECT"+strzh+".data_brjl.ghmc, code_cwfl.cwflmc, "+strzh+".data_cfjl.gjje,"+strzh+".data_cfjl.jzjeFROM "+strzh+".data_brjl, "+strzh+".data_cfjl, code_cwflWHERE ( "+strzh+".data_brjl.xlh = "+strzh+".data_cfjl.xlh )and ("+strzh+".data_brjl.cfzxsj is null)  and  ("+strzh+".data_cfjl.cwflbm = code_cwfl.cwflbm ) and  ( ( "+strzh+".data_brjl.xlh ="+strzh+".data_cfjl.xlh ) AND ( "+strzh+".data_cfjl.cwflbm = code_cwfl.cwflbm ) )"+str_sqlwhere

 

dw_1.setsqlselect(str_sqlselect)

dw_1.retrieve()

 

//这样就实现了以em_1为开始时间和em_2为结束时间以及strzh为表所有者的条件查询.

 

我在做根据用户输入的查询条件产生查询结果时,在窗口上放置数据窗口,放置一些输入查询条件的控件,在"查询"按钮中使用如下方法:

采用dw_1.getsqlselect()取得SQL语句,然后根据查询条件加上where...子句,用dw_1.setsqlselect()实现,现在的问题是:当用户第一次输入查询条件时,点击"查询"按钮可以查询到记录或出现没有记录的提示,这是正确的.但当用户输入新的查询条件时,点击"查询"按钮时,这时dw_1.getsqlselect()取得的SQL语句就不会和第一次取得的值一致(因为setsqlselect()使数据窗口已转变),我想问有没有什么办法,能够使第二次取得的值和第一次一样?谢谢!

------华软网友回答------

在窗口的OPEN事件中就先取好sql放在一个实例变量中,每次查询用该实例变量再加上你新的条件
--------------------- 
版权声明:本文为CSDN博主「sunoqm」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sunoqm/article/details/60566622

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值