动态sql???

abstruse 2003-08-05 11:35:46
需要从配置文件中读取表名table_n和该表名中的某个字段field_n.然后需要把该字段(该表中所有行)根据业务修改后再写回表table_n.应该如何做呀?我看动态sql好象不支持update啊(当然直接使用declare cursor xxxselect field_n from table_n ...., update table_n set field_n=...显然也是不行的)
...全文
110 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
abstruse 2003-08-08
  • 打赏
  • 举报
回复
用游標是为了测试啊,呵呵
我觉得动态语句是不支持selectblob的(至少在pb6.5下)
谢谢各位了哈
abstruse 2003-08-07
  • 打赏
  • 举报
回复
请问Garner06(加纳) , 你'试了一下'是什么意思啊? 做了什么,成功还是失败呢?
我的表,字段都正确,也定义了blob变量,
我的实验代码如下: (体现了四种情况,就动态select blob失败)
int li_blobitems, i
string tabname,colname,ls_temp
blob lb_temp

li_blobitems = ProfileInt("BlobColumns.INI", "BlobItems", "items", 1)

for i = 1 to li_blobitems
tabname = ProfileString("BlobColumns.INI", "BlobColumns", 'tabname' + string(i), "None")
colname = ProfileString("BlobColumns.INI", "BlobColumns", 'colname' + string(i), "None")
IF MessageBox("attention", '将转换表'+tabname+'中的列'+colname, &
Exclamation!, OKCancel!, 2) <> 1 THEN
return;
END IF
int li_temp
//测试表是否存在
SELECT count(*) INTO :li_temp FROM user_tables WHERE table_name = :tabname;
IF (sqlca.SQLCode <>0) or (li_temp = 0) THEN
MessageBox('tablename error', 'table '+ tabname+' does not exist! please modify BlobColumns.INI')
END IF
//测试列名是否存在user_tab_columns
SELECT count(*) INTO :li_temp FROM user_tab_columns
WHERE table_name = :tabname and column_name = :colname;
IF (sqlca.SQLCode <>0) or (li_temp = 0) THEN
MessageBox('columnname error', 'column '+ colname +' does not exist! please modify BlobColumns.INI')
END IF
//表名列名都合法
string ls_sql_all
int li_rownums = 0
ls_sql_all="select max(rownum) FROM " + tabname;//获得表中总的行数
DECLARE c_all DYNAMIC CURSOR FOR SQLSA;
PREPARE SQLSA FROM :ls_sql_all;
OPEN DYNAMIC c_all;
FETCH c_all INTO :li_rownums;
close c_all;
if li_rownums = 0 and isnull(li_rownums) then
messagebox('error', '表中没有数据或表错误')
return
end if
messagebox('li_rownums', '表中数据条数: '+string(li_rownums))
/*以上动态select执行正确*/
int li_rownum = 1
//以下的do while循环, 对一个表的所有列进行操作
do while li_rownum <= li_rownums
string ls_sql_getblob, ls_sql_setblob, ls_sql_gettxt, ls_text

//动态selectblob
colname = ' BRIEF_HISTORY '//该句加上或去掉结果一样
ls_sql_getblob = "SELECTBLOB " + colname + " from " &
+ tabname + " where rownum = ?"
/*目前colname为"BRIEF_HISTORY",由配置文件决定*/
DECLARE c_getblob DYNAMIC CURSOR FOR SQLSA;
PREPARE SQLSA FROM :ls_sql_getblob ;
messagebox('sqlerrtext --before open', sqlca.sqlerrtext+' '+string(sqlca.sqlcode)+' '+ls_temp)
OPEN DYNAMIC c_getblob using :li_rownum;
messagebox('sqlerrtext --before fetch', sqlca.sqlerrtext+' '+string(sqlca.sqlcode)+' '+ls_temp)
/*显示‘ORA-00900: 无效sql语句 -1’*/
FETCH c_getblob INTO :lb_temp;
messagebox('sqlerrtext --after fetch', sqlca.sqlerrtext+' '+string(sqlca.sqlcode)+' '+ls_temp)
/*显示‘cursor is not open -1’*/
close c_getblob;

//对比测试1
messagebox('对比测试1', '动态select')
colname = ' INSTITUTION_ID '
ls_sql_gettxt = "SELECT " + colname + " from " &
+ tabname + " where rownum = ?"
DECLARE c_gettxt DYNAMIC CURSOR FOR SQLSA;
PREPARE SQLSA FROM :ls_sql_gettxt ;
messagebox('sqlerrtext --before open', sqlca.sqlerrtext+' '+string(sqlca.sqlcode)+' '+ls_temp)
OPEN DYNAMIC c_gettxt using :li_rownum;
messagebox('sqlerrtext --before fetch', sqlca.sqlerrtext+' '+string(sqlca.sqlcode)+' '+ls_temp)
FETCH c_gettxt INTO :ls_temp;
messagebox('sqlerrtext --after fetch', sqlca.sqlerrtext+' '+string(sqlca.sqlcode)+' '+ls_temp)
close c_getblob;
/*对比测试1无错误信息输出*/

//对比测试2
messagebox('对比测试2', '静态selectblob')
selectblob BRIEF_HISTORY into :lb_temp from BRIEF_HISTORY where rownum = 1;
messagebox('sqlerrtext --after selectblob', sqlca.sqlerrtext+' '+string(sqlca.sqlcode))
ole_1.objectdata = lb_temp
ole_1.GetData( ClipFormatText!, ls_text)
if ls_text <> '' and not isnull(ls_text) then
mle_1.Text = ls_text //for debug
messagebox('test', ls_text)
/*对比测试2结果正确*/
end if
li_rownum ++
loop //do while li_rownum <= li_rownums
next
欣萱好米 2003-08-07
  • 打赏
  • 举报
回复
暈﹗用了這麼多的游標﹗
在統計行數時﹐有必要用游標碼﹖我不知道﹗就算是有多個表﹐用
ls_sql_all='select count(*) from'+ tabname
execute immediate :ls_sql_all using sqlca; 也是可以統計出來的吧!

我作了什么啊﹗
我試出來表里面要是沒有大二進制數據﹐操作就會沒用結果。
看你的測試代碼﹐也就是說表里面是有大二進制數據的﹗
至于動態語句支不支持selectblob﹐我就沒有數據取測試了﹗
我還是祝你好運﹗

欣萱好米 2003-08-06
  • 打赏
  • 举报
回复
我剛才試了一下﹐大二進制數的選取有差別﹐你可以試試
selectblob和updateblob語句是針對大二進制數據進行處理的﹗
你的表里面要是沒有大二進制數據﹐你是取不出來的﹗
另外﹐我上面說的﹗你的接受變量的類型要注意﹗
你再試試﹗祝你好運﹗
欣萱好米 2003-08-06
  • 打赏
  • 举报
回复
你的接受變量ls_sql_getblob的類型對不對﹖
它應是blob型變量﹗
loseweight2002 2003-08-06
  • 打赏
  • 举报
回复
同意楼上
abstruse 2003-08-05
  • 打赏
  • 举报
回复
流程大致如下:
配置文件的内容:
表名 列名
mytrans sum
myswitch price
hiscomm spec
........ ....
1:循环读配置文件,把表名,列名读入变量mytable, mycolumn;
2:把列选出(如select sum into :temp from mytrans)因为要把所有列选出,所以可能要用到游标
3: 对选出的数据进行变换。(该变换逻辑与选出的数据本身有关)
4:把变换后的数据写入表中,如update mytrans set sum = :temp where ...
5: 重复1,2,3,4步骤
问题:
1: 表名,列名都在配置文件中,所以不能直接用语句select mycolumn from mytable或者语句update mytable set mycolumn= ...
2:变换逻辑与选出的数据有关,所以不能直接用insert table_tmp(select 变换逻辑(field) from table)做转换
3:配置文件中的表很多,所以最好不要把具体的表名写入代码中
gcg_cumt 2003-08-05
  • 打赏
  • 举报
回复
不太明白你的意思,你看使用execute immediate :ls_sql using sqlca;可以吗?
abstruse 2003-08-05
  • 打赏
  • 举报
回复
你的概念上没有错,但是目前讨论的重点在于动态sql是否支持selectblob和updateblob语句
suziniren 2003-08-05
  • 打赏
  • 举报
回复
string ls_sql


ls_sql = 动态SQL语句
execute immediate :ls_sql using sqlca;
呵呵就是这样了,至于动态SQL语句怎么形成我想楼主...
abstruse 2003-08-05
  • 打赏
  • 举报
回复
//以下的do while循环, 对一个表的所有列进行操作
li_rownums = select max(rownum) from.... //动态语句取得表的所有行,执行ok
do while li_rownum <= li_rownums
string ls_sql_getblob, ls_sql_setblob, ls_text, ls_getid
ls_sql_getblob = "selectblob " + colname + " from " &
+ tabname + " where rownum = ?"
DECLARE c_getblob DYNAMIC CURSOR FOR SQLSA;
PREPARE SQLSA FROM :ls_sql_getblob USING SQLCA;
OPEN DYNAMIC c_getblob using :li_rownum;
FETCH c_getblob INTO :lb_temp;
/*这里取不出数据,实际上用语句selectblob 具体的字段 into :lb_temp from 具体的表名where rownum=1 是能够取出数据的
ls_sql_getid = "select " + colname + " from " & //colname='institution_id'
+ tabname + " where rownum = ?"
DECLARE c_getid DYNAMIC CURSOR FOR SQLSA;
PREPARE SQLSA FROM :ls_sql_getid USING SQLCA;
OPEN DYNAMIC c_getid using :li_rownum;
FETCH c_getblob INTO :ls_temp;
就可以正确的取出数据.
是否再次证明了动态sql不支持selectblob和updateblob语句???还是我有什么错误?
abstruse 2003-08-05
  • 打赏
  • 举报
回复
按照Garner06(加纳)的方式也不行的,我觉得不应该是引號 雙引號和波浪號的问题吧.表名和字段名也是经过测试的,ok
如下语句
ls_sql_all="select max(rownum) FROM " + tabname;
DECLARE c_all DYNAMIC CURSOR FOR SQLSA;
PREPARE SQLSA FROM :ls_sql_all;
OPEN DYNAMIC c_all;
FETCH c_all INTO :li_rownums;
close c_all;
结果正确.与
ls_sql_getblob = "selectblob " + colname + " from " &
+ tabname + " where rownum = ?"
/*或者ls_sql_getblob = "~'selectblob~' " + colname + "~' from~' " &
+ tabname + "~'where rownum = ?~'"
*/
DECLARE c_getblob DYNAMIC CURSOR FOR SQLSA;
PREPARE SQLSA FROM :ls_sql_getblob USING SQLCA;
OPEN DYNAMIC c_getblob using :li_rownum;
FETCH c_getblob INTO :lb_temp;
相比差别就在对blob字段进行了操作.
欣萱好米 2003-08-05
  • 打赏
  • 举报
回复
是可以實現的
我覺得你的代碼問題出在sql語句的組織上﹐在組織動態語句時﹐要非常小心單引號 雙引號和波浪號組合使用.
在你代碼這一段﹐你改過來試一下﹗
ls_sql_getblob = "~'selectblob~' " + colname + "~' from~' " &
+ tabname + "~'where rownum = ?~'"
如果不行﹐你在看看是不是你在讀取ini文件時出錯。測試一下讀取的表名和字段名是不是對的。

abstruse 2003-08-05
  • 打赏
  • 举报
回复
//以下的do while循环, 对一个表的所有列进行操作
li_rownums = select max(rownum) from.... //动态语句取得表的所有行,执行ok
do while li_rownum <= li_rownums
string ls_sql_getblob, ls_sql_setblob, ls_text
ls_sql_getblob = "selectblob " + colname + " from " &
+ tabname + " where rownum = ?"
DECLARE c_getblob DYNAMIC CURSOR FOR SQLSA;
PREPARE SQLSA FROM :ls_sql_getblob USING SQLCA;
OPEN DYNAMIC c_getblob using :li_rownum;
FETCH c_getblob INTO :lb_temp;
/*这里取不出数据,实际上用语句selectblob 具体的字段 into :lb_temp from 具体的表名where rownum=1 是能够取出数据的,是不是动态sql不支持selectblob和updateblob语句啊*/
close c_getblob;
ole_1.objectdata = lb_temp
ole_1.GetData( ClipFormatText!, ls_text)
mle_2.Text = ls_text //for debug
lb_temp = blob(ls_text)
//change back ---把word的格式去掉,成为纯文本ls_sql_setblob="updateblob "+tabname+" set "+colname+"=? " +" where rounum = ?";
PREPARE SQLSA FROM :ls_sql_setblob USING SQLCA;
EXECUTE SQLSA USING :lb_temp, :li_rownum;
li_rownum ++
loop
commit;

/*这里更新不了数据,实际上用语句updateblob 具体的表名 set 具体的字段= :lb_temp where rownum=1 是能够更新数据的,是不是动态sql不支持selectblob和updateblob语句啊*/
yl_yz 2003-08-05
  • 打赏
  • 举报
回复
同 gcg_cumt(gcg) 说的。
你读ini文件转换成相应的字符串后用execute
ls_sql="update "+mytable+" set "+ls_str
execute immediate :ls_sql;

1,108

社区成员

发帖
与我相关
我的任务
社区描述
PowerBuilder 相关问题讨论
社区管理员
  • 基础类社区
  • WorldMobile
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧