我在http://community.csdn.net/Expert/topic/3180/3180084.xml?temp=.3381006中提到的一个问题,
 zzllabc(抱朴子--清心释累,绝率忘情) 解决了这个问题,但是又有新的问题出现。原文如下:
**********************************************************************************
q为TClientDataSet,
log表为Sql Server数据库中的一个表,其中name为nvarchar字段,edi为varchar字段
    q.Close;
    q.CommandText:='Insert into log(name,edi) values(:c,:b)';
    q.Params.ParamByName('c').Value:='我们朋友';
      q.Params.ParamByName('b').Value:='我们';    try
       q.Execute;
       showMessage('ok');
    finally
       q.Close;
    end;
这样存入数据库中后,name 字段的内容为“我们”,edi字段的内容为“我”。
如果存入的字符为汉字,就只能存入一半。如果存入的字符为英文字母就能够存完整。
我在oracle数据库中使用没有这个问题。
如果不用三层结构也没有这个问题。
现在不知道是Sql server的问题还是三层结构的问题,在sql server 中怎么解决这个问题?
不知道大家有没碰到过这个问题
**********************************************************************************
解决办法:不用参数,直接写SQL语句,例如:
q.Close;
q.CommandText:='Insert into log(name,edi) values('''+'我们朋友'+''''+','''+'我们'+''''+')';
就可以了。……………………………………………………………………………………………………………………………现在的问题是:
q.Close;
q.CommandText:='Insert into log(name,edi) values('''+'Edit1.text+''''+','''+'我们'+''''+')';
在Edit1.text文本中内容含有单引号,这势必会报错。
不知道各位大侠有没什么高见,谢谢了

解决方案 »

  1.   

    对Edit1.text用两个单引号替换一个单引号
      

  2.   

    语句改为
    q.CommandText:='Insert into log(name,edi) values ('''+Edit1.text+''','''+Edit2.text+''')';
    若是"我们"为字符串则为
    q.CommandText:='Insert into log(name,edi) values ('''+Edit1.text+''','我们')';
      

  3.   

    var str_tmp:string;
    str_tmp := ''''; // str_tmp = "'"''''为一个引号"'"即一个字符
      

  4.   

    楼主这样会出现sql注入漏洞的
    建议用Parameters取代拼凑SQL
      

  5.   

    楼上的你说清楚啊 ,怎么用两个单引号替换一个单引号,你把代码写出来好不好?你的意思是下面这样吗?这样根本就不行,我测试过了
    q.Close;
    q.CommandText:='Insert into log(name,edi) values('''''+Edit1.text+''''''+','''+'我们'+''''+')';
      

  6.   

    ps:可以用QuotedStr
    这个函数很方便的
      

  7.   

    q.CommandText:='Insert into log(name,edi) values('''''+Edit1.text+''''''+','''+'我们'+''''+')';
    showmessage(q.sql[0]);//这样你就看清楚了
      

  8.   

    lw549(那个孩子他爹)你有没看过http://community.csdn.net/Expert/topic/3180/3180084.xml?temp=.3381006
    这样是有bug的啊,方法不可取
      

  9.   

    foxe(火狐) 你好象没明白我的意思
    我是说Edit1.text中含有引号,编译时会出错的
      

  10.   

    回复人: halfdream(哈欠) ( ) 信誉:135  2004-9-7 18:42:25  得分: 20  
     
     
       
    以前记得谁在论坛上提到过这个BUG,跟踪了一下,把它找出来了.
    ADODB.PAS单元
    //-----------------------------------------------------
    function VarDataSize(const Value: OleVariant): Integer;
    begin
      if VarIsNull(Value) then
        Result := -1
      else if VarIsArray(Value) then
        Result := VarArrayHighBound(Value, 1) + 1
      else if TVarData(Value).VType = varOleStr then
      begin
        Result := Length(PWideString(@TVarData(Value).VOleStr)^);
                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~这句的问题,
        if Result = 0 then
          Result := -1;
      end
      else
        Result := SizeOf(OleVariant);
    end;//---------------------------------------------------
    也真是的,这个BUG在DELPHI6,DELPHI7都存在.哈欠老大都告诉你问题的所在了,改一下不就可以了?
      

  11.   

    Result := Length(PWideString(@TVarData(Value).VOleStr)^);Result := Result * 2;//最懒的办法,如果想完全正确,把WideString转换一下
      

  12.   

    //这样就好了
    Result := Length(PAnsiString(@TVarData(Value).VOleStr)^);
      

  13.   

    楼上的意思是‘用Parameters取代拼凑SQL’吗?Result := Result * 2;//这样是不行的,如果没有汉字,那不是多出好多空格了吗?
    如果想完全正确,把WideString转换一下,请教怎么转换?直接修改函数function VarDataSize(const Value: OleVariant): Integer;吗?麻烦写出具体修改代码
      

  14.   

    看完楼上所云,是不是有点离题了?这是我第一反应。
    我想如果 Edit1.Text 中有引号的话,就算是:
        q.Params.ParamByName('c').Value:=Edit1.Text;
          q.Params.ParamByName('b').Value:='我们';
    这句也应该会有问题吧,我想这不应该是用那种方式的问题,而是我们应该作输入检测。
      

  15.   

    Result := Result * 2;//这样是不行的,如果没有汉字,那不是多出好多空格了吗?
    是的,所以我说是偷懒的做法
      

  16.   

    var
      a: String;
    begin
      a :='我';
      showmessage(vartostr(Length(WideString(a))));//1
      showmessage(vartostr(Length(AnsiString(a))));//2
    end;
      

  17.   

    to:  lw549(那个孩子他爹) ,特别感谢你,你的意思我已经很明白了。但不懂ADODB.PAS单元中function VarDataSize(const Value: OleVariant): Integer;
    这个函数为什么要用widestring,开发delphi的应该不是傻子,我想我改成了AnsiString,可能会影响到其他什么地方
    to:wychero(高天) ,其实大家说的一点都不离题,你仔细看看就明白了
    我测试是通过了,最后还是决定用用Parameters取代拼凑SQL,只是我以前是用的parameters的方法,现在改成拼凑SQL,现在又要改过来,又要花一天的时间了为了减少修改
    我想最后大家再讨论一下到底两种写SQL语句方法哪个好,“Parameters”   or   “拼凑SQL”,相信大家也都碰到这个问题
      

  18.   

    拼凑sql,如果你能保证不出现sql注入问题就可以用。