一个Tquery的怪问题,已经困扰我两天了。 (100分)

  • 主题发起人 主题发起人 jghuang
  • 开始时间 开始时间
J

jghuang

Unregistered / Unconfirmed
GUEST, unregistred user!
我的程序中出现这样一个问题,query在Open时,出现Access vilation或者
是Invaliad Pointer Operation。
后台数据库是MS SQL SERVER.
那位大虾能帮我解决。
 
最好把出错的代码贴上来。我这里有环境测试。
 
wuyi: 代码太长不好贴啊。
我对Query主要做了:
循环
begin
Close;
赋参数;
open;
子循环
begin
first;

MoveBy(某一位置);
end;
end;
错误出现在第二次循环时,open不了。
不知这里有何错误。
 
我好象遇到过类似的问题,忘记是怎么解决的。你把这个循环中的代码贴上来看一看。
 
Wuyi,赶快想啊,这么能忘记啊... 8(
具体关于数据库的操作就是这样了,其它就应该没问题了。
会不会是Query太多而占用了太多的内存,但十几个应该不多吧。
 
检查看是否是MOVEBY出问题.
请把子循环说明一下
 
打不开应该是付参数的问题,仔细查查,提示中已明确说明了是指针错误,
应该是字符串或数组的问题。
 
不知道你的Query的参数是否有输出参数?
若有在第二次Open前用ParamByName('XXX').Clear;

若没有参数,不妨在Open前强制用Prepare(迷信做法 xixi)
 
Open语句应在循环外!
 
xixi:没有输出参数,只有输入参数,所以clear没有用啊。
另外,Prepare也没用。
准备试试UnPrepare,下午再来吧。
 
zhaoyipeng:参数是整数,好像没错,还有什么其他可能吗?
 
建议你贴上CODE来看看
 
问题肯定出在你的参数赋值上,建议你跟踪一下那里的SQL语名的结果,您也可以
将该SQL在赋值后ShowMessage出来嘛。
 
yanghaijun:你的方法好像没办法跟踪SQL,不过我换了SQL语句,动态改它的值,
参数改用inttostr加上,还是有错。
 
没办法跟踪SQL的值,不会吧。不管怎么说,你不如将这一小段代码贴上来,否则
纸上谈兵,有点没头没脑。
 
function selectQuestion():boolean; //选题
var i,i1,i2,i3,i4,i5,p,p1,s1,s:integer;
var iTemp:integer;
var OldAnswerCount:integer;
var flag:integer;
var IsSelectQuestion:boolean;
var dlgresult:integer;
begin
OptionDlg:=TOKRightDlg.Create(form1);

i2:=0;
i4:=0;
repeat dlgresult:=OptionDlg.ShowModal;
flag:=0;
result:=false;
if dlgresult=mrOK then
begin
setlength(PaperInarray,length(EditArray) div 2);
s:=0;
flag:=0;
try
for i:=0 to length(EditArray) div 2 -1 do
begin
PaperInarray[i,0]:=strtoint(trim(EditArray[2*i].Text));
PaperInarray[i,1]:=strtoint(trim(EditArray[2*i+1].Text));
S:=S+PaperInArray[i,0]*PaperInArray[i,1];
end;
if strtoint(trim(optiondlg.Edit1.Text))<=0 then
if MessageBox(form1.Handle, '对不起,总分应大于零!'+#13+'按确定重新输入,按取消放弃。', '错误', MB_OKCANCEL)=IDOK then
flag:=1
else flag:=2
else
if strtoint(trim(OptionDlg.Edit1.Text))<>s then
if MessageBox(form1.Handle, '对不起,您填入的各题分数总和与总分不符!'+#13+'按确定重新输入,按取消放弃。', '错误', MB_OKCANCEL)=IDOK then
flag:=1
else flag:=2;
except
on EConvertError do
if MessageBox(Form1.Handle, '错误,请确认填入的应是数字!'+#13+'按确定重新输入,按取消放弃。', '错误', MB_OKCANCEL)=IDOK then
flag:=1;
else flag:=2;
end;
if flag=0 then
begin //开始选题
s1:=0;
DM1.StyleQuery1.Close;
DM1.StyleQuery1.Open;
DM1.StyleQuery1.First;
for i:=0 to length(PaperInarray)-1 do
s1:=s1+PaperInArray[i,0];
SetLength(QuestionArray,s1);
Setlength(AnswerArray,0);
for i:=0 to length(PaperInarray)-1 do
begin
dm1.QuestionQuery1.Close;
//DM1.QuestionQuery1.ParamByName('CPoint').AsInteger:=i+1;
DM1.QuestionQuery1.SQL.Clear;
DM1.QuestionQuery1.SQL.Text:='select id,AnswerIDPosition from questiontable where style='
+inttostr(i+1);

DM1.QuestionQuery1.Open;
if PaperInArray[i,0]>dm1.QuestionQuery1.RecordCount then
begin
if MessageBox(Form1.Handle, '对不起,题库中没有足够题目!'+#13+'按确定重新输入,按取消放弃。', '错误', MB_OKCANCEL)=IDOK then
flag:=1
else flag:=2;
break;
end
else
begin
if dm1.StyleQuery1.FieldByName('Title').AsString='选择题'
then IsSelectQuestion:=true
else IsSelectQuestion:=false;
dm1.StyleQuery1.Next;
for i1:=1 to PaperInArray[i,0] do //PaperInArray[i,0]为试卷中i题型题数
begin
repeat
randomize;
dm1.QuestionQuery1.First;
p:=random(dm1.QuestionQuery1.RecordCount);
dm1.QuestionQuery1.MoveBy(p);

setlength(temparray1,length(QuestionArray));
for itemp:=0 to length(QuestionArray)-1 do
tempArray1[itemp]:=QuestionArray[itemp,0];

until Iterant(dm1.QuestionQuery1.FieldByName('ID').AsInteger,TempArray1)<0;
QuestionArray[i2,0]:=dm1.QuestionQuery1.FieldByName('ID').AsInteger;
if IsSelectQuestion then
begin //是选择题
QuestionArray[i2,1]:=length(answerArray);
OldAnswerCount:=QuestionArray[i2,1];
DM1.AnswerQuery1.close;
// DM1.AnswerQuery1.ParamByName('CPoint').AsInteger:=QuestionArray[i2,0];
// showmessage(DM1.AnswerQuery1.sql.Text);
DM1.AnswerQuery1.sql.Clear;
DM1.AnswerQuery1.SQL.Text:='Select * from AnswerTable where OwnerQuestionID='+inttostr(QuestionArray[i2,0]);
DM1.AnswerQuery1.Open;
//if DM1.AnswerQuery1.IsEmpty then
// MessageBox(self.Handle, '对不起,'+strtoint(QuestionArray[k,0])+'号题目没有答案!'+#13+'按OK重新输入,按Cancel放弃。', '错误', MB_OKCANCEL)=IDOK then
for i3:=1 to 4 do
begin
repeat
randomize;
DM1.AnswerQuery1.First;
p1:=random(DM1.AnswerQuery1.RecordCount);
dm1.AnswerQuery1.MoveBy(p1);

setlength(temparray2,length(AnswerArray));
for itemp:=0 to length(AnswerArray)-1 do
tempArray2[itemp]:=AnswerArray[itemp,0];
until Iterant(dm1.answerQuery1.FieldByName('ID').AsInteger,TempArray2)<0;

SetLength(AnswerArray,i4+1);
Answerarray[i4,0]:=dm1.answerQuery1.FieldByName('ID').AsInteger; //id
Answerarray[i4,1]:=dm1.AnswerQuery1.fieldByName('Position').AsInteger; //位置
Answerarray[i4,2]:=0; //不是正确答案
i4:=I4+1;
end;

setlength(temparray3,i4-OldAnswerCount);
for itemp:=oldAnswercount to i4 do
tempArray3[itemp-oldanswercount]:=AnswerArray[itemp,1];


if Iterant(dm1.QuestionQuery1.FieldByName('AnswerIDPosition').AsInteger,TempArray3)<0 then
begin
randomize;
p1:=random(i4-oldAnswerCount); //i4+1-oldAnswerCount 选项数
Answerarray[OldAnswerCount+p1,0]:=dm1.answerQuery1.FieldByName('ID').AsInteger; //id
Answerarray[OldAnswerCount+p1,1]:=p1; //位置不变

Answerarray[oldAnswerCount+p1,2]:=1; //是正确答案
end
else Answerarray[Iterant(dm1.QuestionQuery1.FieldByName('AnswerIDPosition').AsInteger,TempArray3)+oldAnswerCount,2]:=1;
for i5:=oldAnswerCount to i4 do
AnswerArray[i5,1]:=i5-oldAnswercount; //调整Position
end
else //不是选择题
begin
DM1.AnswerQuery1.First;
repeat
SetLength(AnswerArray,i4+1);
Answerarray[i4,0]:=dm1.answerQuery1.FieldByName('ID').AsInteger;
Answerarray[i4,1]:=dm1.AnswerQuery1.FieldByName('position').AsInteger;
Answerarray[i4,2]:=1; //是正确答案
i4:=I4+1;
DM1.AnswerQuery1.Next;
until DM1.AnswerQuery1.Eof;
end;
i2:=i2+1;
end; //
end;
end; result:=true; //所有题都取完。
end;
if flag<>1 then flag:=0;
end;
until flag=0;
end;

这是我的全部伪代码,要调的话还得建数据库,恐怕不好办。
如果能看出什么破绽的话,快发言吧,多谢了!
 
with query1 do
begin
Close;
赋参数;
open;
if not isempty then
begin
子循环
begin
first;

MoveBy(某一位置);
end;
end;
...
 

dm1.QuestionQuery1.Close;
//DM1.QuestionQuery1.ParamByName('CPoint').AsInteger:=i+1;
DM1.QuestionQuery1.SQL.Clear;
之间加上‘dm1.QuestionQuery1.prepare'试试。
 
if flag=0 then begin //开始选题 s1:=0; DM1.StyleQuery1.Close;
DM1.StyleQuery1.Open;

在你的第一层循环的语句中(如上),因为dm1的sql.text 被你的子循环中clear
了,所以第二次打开时,没有sql语句了。
 
sonie:早就试过了,没用啊。
李京:这个Query没问题啊,而且子循环没有用到它。
 
后退
顶部