在PB中动态修改SQL语句
数据库应⽤程序通常进⾏⼀项确定的⼯作,在编写和编译时就可以确定完整的SQL语句,但是在编译时不能确定SQL语句的具体格式和参数时,只能在程序运⾏过程中构造SQL语句,需要使⽤动态SQL语句。以Format 4 动态SQL语句为例,使⽤格式如下:
DECLARE Cursor | Procedure
DYNAMIC CURSOR | PROCEDURE
sql语句替换表中内容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)
ieve()
---- 使⽤SetSQLSelect有⼀定的要求和限制,更改后的SELECT语句在结构上必须与原先的语句匹配,在执⾏SetSQLSelect函数之前必须⽤SetTrans或SetTransObject函数设置DataWindow控件的内部事务对象。另外, DataWindow对象的数据源必须是⼀个不带参数的SELECT语句,如果需要使⽤检索参数,可以在程序代码中修改SQL Select语句。
(要求按开始和结束时间查询相应⽤户所拥有的表)--我们的数据表是以操作员为所有者的,不同的操作员所拥有的数据表也不相同,这样查询时还要动态设置,表的所属者.
⽐如操作员s02所拥有的表为:s02.data_cfjl⽽s07拥有同样结构的表,但是他的表名为:s07.
先按⾃⼰的要求做⼀个数据窗⼝,不必设置检索条件,做完后可以看到这个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>='"++"' and"+strzh+"data_brjl.cfjlsj<='"++"'"
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)
ieve()
//这样就实现了以em_1为开始时间和em_2为结束时间以及strzh为表所有者的条件查询.
我在做根据⽤户输⼊的查询条件产⽣查询结果时,在窗⼝上放置数据窗⼝,放置⼀些输⼊查询条件的控件,在"查询"按钮中使⽤如下⽅法:
采⽤sqlselect()取得SQL语句,然后根据查询条件加上⼦句,⽤dw_1.setsqlselect()实现,现在的问题是:当⽤户第⼀次输⼊查询条件时,点击"查询"按钮可以查询到记录或出现没有记录的提⽰,这是正确的.但当⽤户输⼊新的查询条件时,点击"查询"按钮时,这时
sqlselect()取得的SQL语句就不会和第⼀次取得的值⼀致(因为setsqlselect()使数据窗⼝已转变),我想问有没有什么办法,能够使第⼆次取得的值和第⼀次⼀样?谢谢!
------华软⽹友回答------

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。