SQL参数为何传不过去?(30分)

  • 主题发起人 主题发起人 wtiebo
  • 开始时间 开始时间
W

wtiebo

Unregistered / Unconfirmed
GUEST, unregistred user!
下面的程序在传参数时,总是传不过去:
with MyDataModule.Query2 do
begin
parambyname('P_field').AsString:=String(ComboBox1.Text);
parambyname('P_operator').AsString:=String(ComboBox2.Text);
if ComboBox1.Text='序号' then
parambyname('P_value').AsInteger:=StrToInt(Edit1.Text)
......
SQL语句在设计时定义如下:
Select *
From sale1
Where :P_field :P_operator :P_value
请问各位大虾,这是为何?
还有,在SQL语句中,多个参数之间怎样分隔(上面的三个参数是否正确)?
 
老兄,你为什么就不听我的劝告跟踪一下程序呢?
这样做根本不行的。

当你用parambyname('P_field').AsString的时候,
这个值就被自动加上了引号,因此你的SQL语句最终会变为:

select * from sale1 where "myfield" ">" "100";
这怎么行呢?

想实现这种功能,只能动态生成SQL语句,
怎么,你那个问题还没解决,又搞出新问题来了?
 
象此类的SQL动态查询,就必须动态生成SQL语句,以前在Foxpro下很容易实现,
其实在Delphi下也不难,如下:

Var
SQLText:String;
begin
SQLText:='select * from "char.dbf" where %s%s%s';
Query1.SQL.Text:=Format(SQLText,['bm','=','"10"']);
Query1.Open;
end;

其要点是根据参数对字符串进行格式化,如果要查询数值型的话,要把%s换成%d.
 
dwwang,您可冤枉我了.其实我是跟踪了的.可等号右边的值老是传不过去.
SQL.Text为:
select * from sale1 where ???;
不过,就冲您这份耐心(我自己都觉得我很烦),我就该谢谢您.
烦归烦,问题还是要解决.我在程序中动态生成以上SQL语句,运行报告:
找不到那三个参数,Why?
 
对不起,我前面所说的可能有一些问题,
跟踪对于含参数的SQL不是好办法.

但有一点要明确:
你想实现的功能用参数肯定不行,理由见上面,
SQL最终会变成:select * from sale1 where "myfield" ">" "100";

另外,传参数我还从来没遇到过问题,你的语句
和给参数赋值的方法都是对的
 
我不喜欢 Params,所以一般会直接写SQL:
Query1.SQL.Clear;
Query1.SQL.Add('select * from sale1 where')
Query1.SQL.Add(Combobox1.Text + Combobox2.Text + Edit1.Text);
Query1.Open;

也可以
Query1.SQL[1] := 'where '+ Combobox1.Text + Combobox2.Text + '"' + Edit1.Text + '"';
Query1.Open;
 
你试一时
parambyname('P_field').value:=String(ComboBox1.Text);
parambyname('P_operator').value:=String(ComboBox2.Text);
if ComboBox1.Text='序号' then
parambyname('P_value').value:=StrToInt(Edit1.Text)
看看行不行
 
根本原因, 是你对Tquery参数使用方发,理解的不对.
TQuery的参数是用于传递动态的值, 在参数只可以用在
where子句中对查询值的定义, 不可以用类似宏替换的方
法.
例如: 在SQL中可以用
where Field1 = :Field1Vale
而不能用
where :a_dy_field = "Field value"
同理,也不能对操作符进行参数传递.

如果, 你需要用类似宏参数的方式运作. 你可以使用RxLib2.5控件库
中的TRxQuery, 该控件支持宏参数, 该类参数用 "%"或自定义字符
作为 宏变量的标记.
我想版主的控件库中 一定有 Rxlib250.zip.


 
请教yyun,如果不用params, 怎么用sql去insert一条带blob字段的记录?
 
Another_eYse,
实际运用中,我还真未操作过Blob字段,想当然,可以用:
TBlobField.LoadFromStream

但是Memo/Text字段用sql插入记录会有问题的,给您举个例子:
就是本论坛,开张一周内,aimingoo大虾老是说输不进大段程序,
我只当是网络速度太慢,实际上是因为sql语句中有了‘或者“
把解释sql的数据库弄糊涂了 :)
 
Another_eyes :
这个问题, 我知道, 但我马上要上课去. please wait a minutes.
 
答案是, 最通用的方法是用TParams,
query1.sql.clear;
query1.SQL.add('insert into TT ');
query1.SQL.add(' (F1,BMP,TEXT) ');
query1.SQL.add(' values(:F1, :BMP, :TEXT) ');
query1.ParamByName('F1').AsString := 'Tname';
query1.ParamByName('BMP').ParamType := ptInput;
query1.ParamByName('BMP').DataType := ftBlob;
query1.ParamByName('BMP').Assign(Image1.Picture);
query1.ParamByName('TEXT').DataType := ftBlob;
query1.ParamByName('TEXT').Assign(Memo1.Lines);
query1.ExecSQL ;
如果用, 一些SQL/Server, 你需要了解它对于Blob类型的字段, 实际的SQL
命令如何写,各类有各类的写法, 它不是标准的SQL语句. 对于程序编写可能
会添加麻烦.
 
虽然直接拼SQL语句非常灵活,但是使用参数可以使SQL语句清晰易懂.
此外,使用参数还把数据类型的转换透明化了,所以我推荐尽可能使用参数方式.

至于对BLOB字段的操作,同意SeaSky的观点,总之是令人头疼的事情

 
问题解决.
但方法不同.为了节约分数,我只好对不起各位了.下面又有新问题:
当Query中有计算字段时,如何更改查询结果(简单一点的)?
是否非的用Query的Insert不可?
 
更改应该用update
添加才用insert
 
用TUpdataSQL 构件
 
用TUpdataSQL 构件
 
How to use it? Thank you first!
 
我同意dubhe 的做法,虽然写param 有点麻烦,
但是程序结构清晰,严谨,并且方便维护,代码可移植性也高,
直接写SQl弊端多多,起码当参数过多时,数单引号老数不清楚
 

Similar threads

回复
0
查看
978
不得闲
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部