一个带参数插入语句的写法问题探讨

hujinger 2004-12-13 10:20:47
很简短的一段代码:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TQuery *q1=new TQuery(NULL);
try
{
if ( dbDiary->Connected ==false)
{
dbDiary->Params->Values["USER NAME"] = "sa";
dbDiary->Params->Values["PASSWORD"] = "";
dbDiary->Connected = true;
}
q1->DatabaseName="MyDatabase";
q1->Close();
q1->SQL->Clear();

AnsiString strSql=" insert into Table1 values(:v1,:v2:,v3) ";
for(int i=1;i<11;i++)
{
q1->SQL->Add(strSql);
q1->Params->Items[0]->AsInteger=i;
q1->Params->Items[1]->AsString="Li'u";
q1->Params->Items[2]->AsString="s'econd";
}
q1->ExecSQL();
delete q1;
}
catch(const Exception &E)
{
delete q1;
throw;
}
}

大家应该也能够看懂我的意思。我是想插入10条不同的sql语句,但是执行结束后查询table1表(没有设置主键)中发现插入的10条sql语句居然是相同的。
不带参数的sql语句执行直接用insert into table1 values(i,'liu','tan') 是没有问题的。

有没有人能够帮忙分析一下带参数的插入语句怎样批量执行呢?跪谢啦!!
...全文
202 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
wt_sanlian 2004-12-17
  • 打赏
  • 举报
回复
滚吧,你
本来就是小题大做的问题,自已根本都不动脑筋!

说话还这么刻薄!
hujinger 2004-12-17
  • 打赏
  • 举报
回复
看样子是没有人能够解决这么复杂的问题啦!

to:阿华,你根本没有看我的问题所在。单引号变双引号方案是绝对不行的!我一分解字符串就完蛋!


就这样揭贴真的有点于心不忍!不知道说csdn什么好!
wg961423 2004-12-16
  • 打赏
  • 举报
回复
我不用参数的。
AnsiString Str1,Str2;
Str1="X";
Str2="'x'";
if(xx)
{
Str1+=",XX";
Str2+=",'xx'";
}
if(xxx)
{
Str1+=",XXX";
Str2+=",'xxx'";
}
Query1->Close();
Query1->SQL->Clear();
Query1->SQL->Add("insert into YYYY ("+Str1+") values("+Str2+")");
Query1->ExecSQL();
ntahua 2004-12-16
  • 打赏
  • 举报
回复
奇怪第二次的回复没了???
我的意思是不要用参数了,直接在SQL里写变量值
AnsiString strSql=" insert into Table1 values(";
AnsiString sql;

for(int i=1;i<11;i++)
{
sql=sql+strSql+IntToStr(i)+",'li''u',"+"'s''econd')";
}
q1->SQL->Add(strSql);

q1->ExecSQL();
ntahua 2004-12-16
  • 打赏
  • 举报
回复
不知道你有没有看到我上面的解答。希望你试一下。
hujinger 2004-12-15
  • 打赏
  • 举报
回复
to:雷电,你的写法本身就有一些问题,应该写成这样:
strSql.sprintf(" insert into Table2 values(%d,'%s','%s') ", i , "wa''ng","fi''rst");
这样将单引号分开成双引号是可以实现的。
但是我上面讲的很清楚,需要分割5000byte内容为20个字段。也就是说单引号变双引号时可能被隔开!这还是会造成写库失败!所以还是不能解决问题。
不管怎样,谢谢先!

to:铁翅膀,也非常感谢你哦! 你自己也知道sql过长。5000Byte的日志*200条语句=1M,肯定死瞧瞧。

to:大家,我已经想到了一个更好一点的办法。就是将单引号先自己用空格符替换掉。不过这个方案老大们正在讨论是否可行。

还有没有哪位高手愿意试试呀?
metalwing 2004-12-14
  • 打赏
  • 举报
回复
再次修改:AnsiString temp;的定义放在前面。
metalwing 2004-12-14
  • 打赏
  • 举报
回复
改一下:

...
// 最后多了一个UNION删除它
sql -= "\nUNION\n";
Query->Add(sql);
...

但这样的话可能会有一个问题,sql可能过长。
metalwing 2004-12-14
  • 打赏
  • 举报
回复
那你是要构造一个一次插入多条记录的SQL语句了.我想只能是Select into语句了。 jinhaiwu(※读毒※) 的试试吧,应该可以的。稍微改一下
// 构造SQL语句
AnsiString sql = "INSERT INTO t (f1, f2, f3) \n";
for (int i = 1;i < recordcount;i ++)
{
AnsiString temp;
sql += "SELECT ";
for(int j = 1;j <= colcount; j++)
{
temp = "v" + IntToStr(i) + IntToStr(j);
sql += ":" + temp;
}
sql += "\nUNION\n";
}
Query->Add(sql);
// 参数赋值
for (int i= 1;i <= recordcount;i ++)
{
for (int j = 1;j <= colcount;j ++)
{

Query->Params->ParamByName("v"+IntToStr(i)+IntToStr(j))->Value = YourValue;
}
}
metalwing 2004-12-14
  • 打赏
  • 举报
回复
修改也一样.拿到客户端,修改完毕后一次提交.
metalwing 2004-12-14
  • 打赏
  • 举报
回复
方法不同罢了,行得通的
ntahua 2004-12-14
  • 打赏
  • 举报
回复
我明白你的意思了,你试试看这样
int i;
for (i=1;i<11;i++)
{
……
hujinger 2004-12-14
  • 打赏
  • 举报
回复
to:楼上的,这种方法行不通吧?我是修改表记录呀!直接ExecSQL就完成了的。

to:kmfangxun() ,哈哈,自己也说意义不大了。我只是做了一个小小的循环,若实现大一点的循环(如200),然后表的字段有20个,总共就需要产生4000个参数!这种执行效果想必你也想不到是什么样的?

我实际的问题远比这复杂的多!
wt_sanlian 2004-12-14
  • 打赏
  • 举报
回复
嘿!我来试试~
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TQuery *q1=new TQuery(NULL);
try
{
if ( dbDiary->Connected ==false)
{
dbDiary->Params->Values["USER NAME"] = "sa";
dbDiary->Params->Values["PASSWORD"] = "";
dbDiary->Connected = true;
}
q1->DatabaseName="MyDatabase";
q1->Close();
q1->SQL->Clear();

AnsiString strSql;
for(int i=1;i<11;i++)
{
strSQl.sprintf(" insert into Table1 values(%d,%s:,%s) ",
i,"Li'u","s'econd");
q1->SQL->Add(strSql);
}
q1->ExecSQL();
delete q1;
}
catch(const Exception &E)
{
delete q1;
throw;
}
}
hujinger 2004-12-14
  • 打赏
  • 举报
回复
to:metalwing(铁翼) ,你都没有看明白我的问题所在!

我大致说一下我的问题吧。我坐服务端,接收各种业务发来的消息(实际上只是提供api函数供他们调用,自己封装一个dll发送消息,应用只需要将需要插入到数据库中的可能会有5000Byte长度的字符串传递过来就可以了)进行入库处理。而我都是采用bde访问数据库机制,我还有一个客户端需要查询我的数据库内容。

数据库中保存5000个字节分了20个字段,单个字段为255Byte长度。插入到数据库中时如果直接insert into就需要考虑客户端传递过来的单引号问题(无法处理!若我保存的只是一个字段5000byte长度,那我可以再他们传过来的内容中查找单引号,让单引号重复一个就可以直接用插入语句)。单引号问题导致我采用了参数的方式。但是批量插入又带来了新的问题。

不知道这次大家能否理解我的意思?很多人都说csdn的人的水平很好,但是没有人肯真正帮你!不知道是不是真的。不过到目前为止我看到的答案是肯定觉得大家没有怎么动脑经的。^_^ 当然,可能是因为我讲的不够详细了。
jinhaiwu 2004-12-13
  • 打赏
  • 举报
回复
INSERT INTO t
(f1, f2, f3)
SELECT '1', 'b', 'c'
UNION
SELECT '2', 'b', 'c'
UNION
SELECT '3', 'b', 'c'
UNION
SELECT '4', 'b', 'c'
laisf 2004-12-13
  • 打赏
  • 举报
回复
UP,批量没试过。
hujinger 2004-12-13
  • 打赏
  • 举报
回复
谢谢你的答复!

我想可能是我讲的还不是很清楚,我需要的是批量执行sql语句,减少sqlserver的频繁插入操作。
laisf 2004-12-13
  • 打赏
  • 举报
回复
你的q1->ExecSQL();必须放在循环里面。
q1->SQL->Add(strSql);
for(int i=1;i<11;i++)
{
q1->Params->Items[0]->AsInteger=i;
q1->Params->Items[1]->AsString="Li'u";
q1->Params->Items[2]->AsString="s'econd";
q1->ExecSQL();
}
metalwing 2004-12-13
  • 打赏
  • 举报
回复
先建立客户端结果集,然后对它进行插入操作,全部插入完成后,一次性提交给SQL Server

AnsiString sql = "SELECT * FROM Table1 WHERE"+condition;
ql->SQL->Clear();
ql->SQL->Add(sql);
ql->Open();
ql->Append();
......
ql->Post();
加载更多回复(3)

1,178

社区成员

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

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