关于in条件的动态SQL的参数问题(300分)

  • 主题发起人 主题发起人 onedot
  • 开始时间 开始时间
O

onedot

Unregistered / Unconfirmed
GUEST, unregistred user!
我在程序中指定
a1:="one";
a2:="two";
sql:='select * from table1 where f1 in ('+a1+','+'a2)';
TQUERY.sql.add(sql);
运行结果正确,但是我觉得每次动态去生成SQL不方便也容易写错,尤其是你程序中你无法
知道a1,a2等值,如果当a1,a2的值里包含'或者"可能非常容易错.因此我希望把TQUERY里的SQL
写成select * from table1 where f1 in :domain
然后每次程序中只需要动态对domain这个参数赋值。
我不知道这种参数该设置成什么类型,程序中怎么对它赋值?
//BTW:我尝试了很多中,不是报错就是结果不对(常把你赋的集合值看作一个整个的值看待)
所以希望哪位大虾自己用过或者自己尝试过再回答,分不是问题,呵呵!
然后
 
我刚刚查看了以前的答案,似乎大家都没有什么好的方法。
所以希望这次有人有好的办法。
 
不好意思,我刚好在做同样的事,好象还是很简单的哦!!
先定义:
var
S:STRING;
实现:
SQL.Clear;
SQL.Add(select * from table1 where f1 in :domain');
Parameters.ParamByName('domain').Value := S; //赋值
OPEN;
 
用select嵌套,mssql支持的。
'select * from table1 where f1 in (select * from table2 where .....)
 
试试下面的方法,我测试通过:

procedure tform1.button1click(sender:tobject);
var
a,b:longint;
begin
a:=1111111111;
b:=2000000000;
with query1 do
begin
close;
sql.clear;
sql.add('select * from table1 as a where a."ziduanming" in '+
'('+inttostr(a)+','+inttostr(b)+')');
open;
end;
end;
注:table1 是表名,ziduanming是表中的字段名
界面上有一个 Tquery组建,Tdatasource组建,TDbgrid组建
 
to surpass:
你说的我不是很明白,首先你定义的参数它的类型是什么?其次S赋值的时候是加()还是没有?
如果你真的用过,请给个比较详细的例子好吗?
to truestzhou:
你的我知道可以,我已经用过,只是现在讨论是参数传递如何处理。
to chenlili:
不好意思,你的首先SQL语句就有问题。//而且我讨论的问题和这个无关。
 
同意surpass
to onedot :
var
S:STRING;
实现:
SQL.Clear;
SQL.Add(select * from table1 where f1 in '+s);
OPEN;

 
好像可以使用吗?
 
var s:string;
begin
s:='(13900,114524)';
query1.SQL.clear;
query1.SQL.Add (format('select * from country where area in %s',));
query1.open;
end;
这样可以,和参数形式差不多
 
a1:='one';
a2:='two';
sql:=format('select * from table1 where f1 in (%s,%s)',[a1,a2]);
query1.SQL.clear;
query1.SQL.Add (sql);
query1.open;


 
建议用两个参数。
 
做一个函数来生成你要的:domain
function GetParams(strParams : TStrings) : string;
var
strTmp : string;
iLoop : integer;
begin
strTmp := '(';
if strParams.Count=0 then
strTmp := strTmp +'""';
iLoop := 0 to strParams.Count -1 do
strTmp := strTmp + '"'+strParams[iLoop] + '",'
SetLength(strTmp,Length(strTmp)-1);
strTmp := strTmp + ')'
result := strTmp;
end;
 
看我的全部程序,很简单的:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, DBCtrls, Grids, DBGrids, Db, ADODB, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
ADOQ: TADOQuery;
ADOConnection1: TADOConnection;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
DBNavigator1: TDBNavigator;
Edit1: TEdit;
Edit2: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
with adoq do
begin
Close ;
SQL.clear;
SQL.Add ('SELECT * FROM tbnote where Tb_name in (:n1,:n2)');
Parameters .ParamByName ('n1').Value :=edit1.text;
Parameters .ParamByName ('n1').Value :=edit2.text;
Open;
end; // withith
end;

end.
 
to onedot:
SQL语句中的Inttostr(a),inttostr(b)其中的a,b就是变量
 只要把变量转化为相应的字符串就行
 
各位还是没明白我意思么?
我希望是用一个参数就可以方便传递IN的范围集合。因为更多时候IN的范围集合的值个数
并不可知。我提这个问题不在于解决问题本身,因为每次写SQL的方法我已经用过,可以。
而且我个人觉得TQUERY里的参数的类型很多都不常用,不知道是否里面有一个
是用来处理这种情况的。
 
用我的函数生成不是就行了吗
 
对字符型可以这样赋值!
Parameters .ParamByName ('n1').Value :='one';
Parameters .ParamByName ('n1').Value :='two';
 
to:mataijin
你说的方法我在提出这个问题前就使用过了。我再次申明我提这个问题是想知道是否可以
直接使用TQUERY里的参数,就象其他SQL一样将参数简单赋值,既方便又不容易错!
我希望借此了解更多的关于DELPHI处理动态SQL语句的内容

 
应该没有,DELPHI中PARAMETER的TYPE都是针对单个数据的,没有针对一个集合的
 
这个问题已经是老生常谈了,我好像也“回答”过几次
--回答二字加引号的原因就是因为没有结果 ...

我以前曾经建议过,应该给query加上MacroByName这类的东东,
专门解决各种这类问题...
 
后退
顶部