pb9和sqlserver 2000中游标的应用问题,附有源码和错误信息,请高手帮我看看,谢谢:)

singing2003 2003-08-19 09:35:04
pb9+sqlserver2000。
一、在函数里面定义游标为何不能打开。定义及出错信息如下。
DECLARE cur_noright CURSOR FOR
SELECT yldmenu.menuid
FROM yldmenu
WHERE (yldmenu.menuid not in (:gs_menuidall))
ORDER BY yldmenu.menuid ASC ; //('10300','10300','10000','10400','10500','10700','10800','10900','11100','11300','11600','11700','11800','12000','20000')
open cur_noright;
错误信息为:Bind parameter value for '?' is too big (119)

二、为数据窗口的列定义了有效性规则后,为什么当出现错误时会出现两次提示?如何只让它出现一次?

三、关于使用游标的又一怪事。编译不出错,运行时,sql有注释中的错误。
//我打算将syscolumns系统表中我所创建的表的字段抽出来放到自己的表中,然后再用其它办法加上中文说明,想通过下面的方式来做,结果出现一个错误***********
String ls_table,ls_column,ls_filter,ls_sql
Long ll_tableid,ll_c,ll_t

DECLARE cur_table CURSOR FOR
SELECT sysobjects.name,
sysobjects.id
FROM sysobjects
WHERE ( sysobjects.xtype = 'U' ) AND
( Left(sysobjects.Name,1) = 'c' ) ;
DECLARE cur_column DYNAMIC CURSOR FOR sqlsa;

DELETE FROM ctablecolumnname;
ls_sql = "SELECT syscolumns.name FROM syscolumns WHERE syscolumns.id=?"
PREPARE sqlsa FROM :ls_sql;
OPEN cur_table;
FETCH cur_table INTO :ls_table,:ll_tableid;

//出错行?????????????????????????
OPEN DYNAMIC cur_column USING :ll_tableid; //SQLSTATE = S1004[Microsoft][ODBC SQL Server Driver]无效的 SQL 数据类型
//sqlca.sqlcode=-1,sqldbcode=999.
//sql server中int为4byte,pb中long才为4型。而我将系统表sysobjects与syscolumns用id关联后采用表名时,同样也出类似的错误,怪哉,救救我。


IF sqlca.SQLCode = 0 THEN
DO UNTIL sqlca.SQLCode = 100
ll_t++
FETCH cur_column INTO :ls_column;
DO UNTIL sqlca.SQLCode = 100
ll_c++
INSERT INTO ctablecolumnname
( tablename,
columnname,
columnnamecn )
VALUES ( :ls_table,
:ls_column,
Null ) ;
FETCH cur_column INTO :ls_column;
LOOP
FETCH cur_table INTO :ls_table,:ll_tableid;
LOOP
END IF

IF sqlca.SQLCode = 100 THEN
COMMIT;
MessageBox('提示','信息生成'+String(ll_c)+'/'+String(ll_t)+'条记录,操作成功!')
ELSEIF sqlca.SQLCode < 0 THEN
MessageBox('提示','信息生成失败!~r~n错误信息为:'+sqlca.SQLErrText)
ROLLBACK;
END IF

CLOSE cur_table;
CLOSE cur_column;

四、而将上面出错的游标改用datastore来实现归却又有如下的错误:只有最后一条记录不会出错,而其它所有的记录在retrieve时,返回值均为-1,请问是为什么?附datastroe代码如下:

String ls_table,ls_column,ls_filter
Long ll_tableid,ll_rc,ll_cr,ll_c,ll_t
datastore lds_column
DECLARE cur_table CURSOR FOR
SELECT sysobjects.name,
sysobjects.id
FROM sysobjects
WHERE ( sysobjects.xtype = 'U' ) AND
( Left(sysobjects.Name,1) = 'c' ) ;

DELETE FROM ctablecolumnname;
lds_column = CREATE datastore
lds_column.DataObject = 'dw_systablecolumn'
ll_cr = lds_column.SetTransObject(sqlca)
ll_cr = lds_column.Retrieve(ll_tableid) //此时ll_tableid为0竟然不出错,返回值为0,是对的。
OPEN cur_table;
FETCH cur_table INTO :ls_table,:ll_tableid;

IF sqlca.SQLCode = 0 THEN
DO UNTIL sqlca.SQLCode = 100
ll_t++
ll_rc =lds_column.Retrieve(ll_tableid) //此行出错,只有所有记录中的最后一条是对的,其它前面的所有记录明明有内容,返回也是-1。注:此数据窗口对像需要一个number型的参数。
IF ll_rc < 1 THEN
MessageBox('提示','检索数据出错。')
return
ELSE
FOR ll_cr = 1 TO ll_rc
ls_column = Trim(lds_column.GetItemString(ll_cr,'name'))
if ls_column<>'' then ll_c++
INSERT INTO ctablecolumnname
( tablename,
columnname)
VALUES ( :ls_table,
:ls_column) ;
NEXT
END IF

FETCH cur_table INTO :ls_table,:ll_tableid;
LOOP
END IF
IF sqlca.SQLCode = 100 THEN
COMMIT;
MessageBox('提示','信息生成'+string(ll_c)+'/'+string(ll_t)+'条记录,操作成功!')
ELSEIF sqlca.SQLCode < 0 THEN
ROLLBACK;
MessageBox('提示','信息生成失败!~r~n错误信息为:'+sqlca.SQLErrText)
END IF

CLOSE cur_table;
...全文
108 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
singing2003 2003-08-22
  • 打赏
  • 举报
回复
这是主要问题的最终结果,运行OK,版权所有,可以随意拷贝:)

string ls_sql1,ls_syn1,ls_error1,ls_sql2,ls_syn2,ls_error2 //two datastore of objects and columns
string ls_tableid,ls_column,ls_table
datastore lds_objects,lds_columns
long ll_rc1,ll_cr1,ll_rc2,ll_cr2,ll_tableid,ll_column

if messagebox('提示','提取列名操作,将花费大约半分钟时间,继续吗?',question!,yesno!,2)=2 then return
DELETE FROM ctablecolumnname;
lds_objects = create datastore
lds_columns = create datastore

ls_sql1='SELECT sysobjects.name,' + &
' sysobjects.id' + &
' FROM sysobjects' + &
" WHERE ( sysobjects.xtype = 'U' ) AND" + &
" ( Left(sysobjects.Name,1) = 'c' )"
ls_syn1 = SQLCA.SyntaxFromSQL(ls_sql1,'Style(Type=Form)', ls_error1)
if len(ls_error1)>0 then
messagebox('提示','创建数据存储的语法1出错。将返回。',information!,ok!)
return
else
lds_objects.create(ls_syn1,ls_error1)
if len(ls_error1)>0 then
messagebox('提示','创建数据存储1出错。将返回。',information!,ok!)
return
end if
end if

lds_objects.settransobject(sqlca)
ll_rc1=lds_objects.retrieve()
if ll_rc1>0 then
for ll_cr1=1 to ll_rc1
ll_tableid=lds_objects.getitemnumber(ll_cr1,'id')
ls_table=trim(lds_objects.getitemstring(ll_cr1,'name'))
ls_tableid=string(ll_tableid)
ls_sql2='SELECT syscolumns.name FROM syscolumns WHERE syscolumns.id = '+ ls_tableid

ls_syn2 = SQLCA.SyntaxFromSQL(ls_sql2,'Style(Type=Form)', ls_error2)
if len(ls_error2)>0 then
messagebox('提示','创建数据存储的语法2出错。将返回。',information!,ok!)
return
else
lds_columns.create(ls_syn2,ls_error2)
if len(ls_error2)>0 then
messagebox('提示','创建数据存储2出错。将返回。',information!,ok!)
return
end if
end if

lds_columns.settransobject(sqlca)
ll_rc2=lds_columns.retrieve()
if ll_rc2>0 then
for ll_cr2=1 to ll_rc2
ll_column++
ls_column=trim(lds_columns.getitemstring(ll_cr2,'name'))
INSERT INTO ctablecolumnname
( id,
tablename,
columnname )
VALUES ( :ll_tableid,
:ls_table,
:ls_column ) ;
if sqlca.sqlcode<0 then messagebox('提示','向表:ctablecolumname插入数据出错。',stopsign!,ok!)
next
end if
next
if sqlca.sqlcode=0 then messagebox('提示','列名存取成功!~r~n共操作表格/列的数量为:'+string(ll_rc1)+'/'+string(ll_column),information!,ok!)

destroy lds_columns
end if
destroy lds_objects
dotnba 2003-08-21
  • 打赏
  • 举报
回复
一、把IN改成OR看看
二、你可能在不同的地方加了验证语句,检查一下。
三和四改成DS是比较好的办法。
string error_syntaxfromSQL, error_create

string new_sql, new_syntax

datastore lds_Dynamic

lds_Dynamic = create datastore

new_sql = 'SELECT sysobjects.name,' + &
' sysobjects.id' + &
' FROM sysobjects' + &
' WHERE ( sysobjects.xtype = "U" ) AND' + &
' ( Left(sysobjects.Name,1) = "c" )'

new_syntax = SQLCA.SyntaxFromSQL(new_sql,'Style(Type=Form)', error_syntaxfromSQL)

IF Len(error_syntaxfromSQL) > 0 THEN

// Display errors

ELSE

// Generate new DataStore

lds_Dynamic.Create(new_syntax, error_create)

IF Len(error_create) > 0 THEN

// Display errors

END IF

END IF

lds_Dynamic.SetTransObject(SQLCA)

lds_Dynamic.Retrieve()

destroy lds_Dynamic
runsoft 2003-08-20
  • 打赏
  • 举报
回复
四、而将上面出错的游标改用datastore来实现归却又有如下的错误:只有最后一条记录不会出错,而其它所有的记录在retrieve时,返回值均为-1,请问是为什么?附datastroe代码如下:

PB当中 游标少用,游标运行的中间,不能使用INSERT语句,这样回改变SQLCODE ,导致出现错误,
runsoft 2003-08-20
  • 打赏
  • 举报
回复
为数据窗口的列定义了有效性规则后,为什么当出现错误时会出现两次提示?如何只让它出现一次?
在触发了ITEMCHANGEDE,建议不要在列里面定义,这个好像是PB的BUG.我也碰到过
runsoft 2003-08-20
  • 打赏
  • 举报
回复
DECLARE cur_noright CURSOR FOR
SELECT yldmenu.menuid
FROM yldmenu
WHERE (yldmenu.menuid not in (:gs_menuidall))
ORDER BY yldmenu.menuid ASC ;
这样写应该有问题,in 后面的是跟着的是集合
singing2003 2003-08-19
  • 打赏
  • 举报
回复
没来得及修改分数,再者分数特别重要吗?
polugen 2003-08-19
  • 打赏
  • 举报
回复
分太少了

752

社区成员

发帖
与我相关
我的任务
社区描述
PowerBuilder 数据库相关
社区管理员
  • 数据库相关社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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