Delphi Tstringlist,将字符串作为引号,逗号分隔的字符串?

时间:2015-11-18 12:27:38

标签: delphi csv tstringlist

我有一个Tstringlist,其中包含数据库表中使用的键列表。 我想要一种简单的方法来生成一个包含所有键的字符串,每个键用逗号分隔并用单引号括起来。 这样它就可以在SQL'IN'语句中使用 例如 WHERE FieldX IN('One','Two','Three')

我尝试过使用quotechar,但在读取逗号时忽略了它。 例如以下代码

procedure junk;
var
  SL : Tstringlist;
  s : string;
begin
 SL := Tstringlist.Create;
 SL.Delimiter :=','; //comma delimiter
 SL.QuoteChar := ''''; //single quote around strings
 SL.Add('One');
 SL.Add('Two');
 SL.Add('Three');
 try
   s :=  SL.commatext;
   showmessage(s);
 finally
   SL.Free;
 end; //finally
end; //junk

显示消息一,二,三 - 没有任何引号。

我知道我可以在很长一段时间内完成,如

procedure junk;
var
  SL : Tstringlist;
  s : string;
  i : integer;
begin
 SL := Tstringlist.Create;
 SL.Delimiter :=','; //comma delimiter
 SL.Add('One');
 SL.Add('Two');
 SL.Add('Three');
 try
 s := '';
 for I := 0 to SL.Count - 1 do
    begin
    s := s +  ',' + '''' + SL[i] + '''';
    end;
 delete(s,1,1);
 showmessage(s);
 finally
   SL.Free;
 end;//finally
end;

但使用Tstringlist本身的属性有一种更简单的方法吗?

5 个答案:

答案 0 :(得分:3)

如果您使用的是D2006或更高版本,则可以使用CLASS HELPER:

USES Classes,StrUtils;

TYPE
  TStringListHelper = CLASS HELPER FOR TStrings
                        FUNCTION ToSQL : STRING;
                      END;

FUNCTION TStringListHelper.ToSQL : STRING;
  VAR
    S : STRING;

  FUNCTION QuotedStr(CONST S : STRING) : STRING;
    BEGIN
      Result:=''''+ReplaceStr(S,'''','''''')+''''
    END;

  BEGIN
    Result:='';
    FOR S IN Self DO BEGIN
      IF Result='' THEN Result:='(' ELSE Result:=Result+',';
      Result:=Result+QuotedStr(S)
    END;
    IF Result<>'' THEN Result:=Result+')'
  END;

此代码:

SL:=TStringList.Create;
SL.Add('One');
SL.Add('Two');
SL.Add('Number Three');
SL.Add('It''s number 4');
WRITELN('SELECT * FROM TABLE WHERE FIELD IN '+SL.ToSQL);
然后

将输出:

SELECT * FROM TABLE WHERE FIELD IN ('One','Two','Number Three','It''s number 4')

答案 1 :(得分:1)

使用sl.DelimitedText代替sl.CommaText,使其符合您的设置。 CommaText会暂时将DelimiterQuoteChar更改为某些硬编码值。

答案 2 :(得分:0)

不能依赖CommaText(显然也是DelimitedText)来添加引号,因为它们对单字和多字字符串的处理方式不同。

  

检索CommaText时,列表中包含空格的任何字符串,   逗号或引号将包含在双引号和任何双引号中   字符串中的引号将重复出现。

似乎没有任何与TStringList的组合,所以我建议你使用QuotedStr添加字符串。 以下设置可以按照您的意愿工作,无论字符串是单个单词还是多个单词:

 SL := Tstringlist.Create;
 SL.Delimiter :=','; //comma delimiter
 SL.StrictDelimiter := True;
// SL.QuoteChar := ''''; //single quote around strings
// SL.Add('One');
// SL.Add('Two words');
// SL.Add('Three');
 SL.Add(QuotedStr('One'));
 SL.Add(QuotedStr('Two words'));
 SL.Add(QuotedStr('Three'));
 s := SL.CommaText; // or SL.DelimitedText;
 showmessage(s);

输出是:

  

'一个','两个字','三个'

答案 3 :(得分:0)

TStrings.DelimitedText方法仅在需要时引用字符串:当链接O'ne时,这将打印为'O''ne' - 即它将引号加倍。

您可以实现您想要的设置方便分隔符和QuoteChar属性到#0值,然后用引号替换分隔符。

procedure junk;
var
  sl : Tstringlist;
  s: string;
begin
  sl := Tstringlist.Create;
  try
    sl.Delimiter := '|';
    sl.QuoteChar := #0;//no quote
    sl.Add('On''e');
    sl.Add('Two');
    sl.Add('Three');

    //escape the single quotes
    s := StringReplace(sl.DelimitedText, '''', '''''', [rfReplaceAll]);

    //replace the delimiters and quote the text
    s := '''' +  StringReplace(s, sl.Delimiter, ''',''', [rfReplaceAll]) + '''';

    WriteLn(s);

  finally
    sl.Free;
  end;
end;

答案 4 :(得分:0)

我已经用类似的方法解决了类似的问题:

  s := ''' + StringReplace(sl.CommaText, ',', ''',''', [rfReplaceAll]) + '''