2015-12-14 45 views
0

比方说,我有一个字符串是这样的:德尔福 - 重新拆分字符串数组?

string1 := 'me,email1,you,email2,him,email3,them,email4'; 

把它变成一个字符串数组我只是做:

array1 := SplitString(string1,','); 

这工作得很好。

但后来,我得到这样一个数组:

array1[0] -> me 
array1[1] -> email1 
array1[2] -> you 
array1[3] -> email2 
array1[4] -> him 
array1[5] -> email3 
array1[6] -> them 
array1[7] -> email4 

我搜索了半天怎么插入这个SQLite的,但没有使用

for i:= 0 to length(array1) -1 
SQLExecute('INSERT INTO table(name,email) VALUES("'+array1[i]+'","'+array1[i+1]+'"'); 

因为指数0会作为名称插入索引1作为电子邮件,但在下一回合中,索引1将作为名称插入索引2作为电子邮件,索引1是电子邮件时,索引2是名称...您是否看到问题?

我考虑重新劈裂所述第一阵列到第二个通过改变初始字符串格式转换成:

string1 := 'me-email1,you-email2,him-email3,them-email4'; 

对第一时间上'和第二时间分割 - ,要获得一个2维数组,但似乎这个概念是在我的知识此刻:)

只是为了记录,我使用的Delphi RAD是相当新的,目前只有一些功能/工具可用。

你将如何插入到SQL?你会保留原始的字符串格式,还是将其更改为获取2维数组?

+0

你真正想要做的是解析成一组记录,与具有每个记录交易名称字段和电子邮件名称。 –

+0

对任何语言来说都是一个非常糟糕的主意。 Delphi PHP,Python - 无论如何!!!请使用可靠的方法! http://bobby-tables.com/ –

回答

2

迭代成对:

for i := 0 to length(array1) div 2 - 1 do 
    SQLExecute('INSERT INTO table(name,email) VALUES("'+array1[i*2]+'","'+array1[i*2+1]+'"'); 
0

你刚才不应该每INSERT使用FOR循环在这里。 它不适合它,如果你的字符串有3个或7个或任何其他奇数个元素是危险的。

将随机数据直接拼接到SQL命令中是非常不可靠和脆弱的。 http://bobby-tables.com/

您应该使用带滑动抓取器的WHILE循环或以每个字符串FOR-loop摆动的tick-tock(有限状态机)。

var q: TQuery; 
// some Query-component of any library, 
// including DBX, AnyDAC/ FireDAC mORMot or any other library you would use 

var sa_OK, sa_err1, sa_err2: TArray<string>; 

// common preparations for both methods 
q.ParamCheck := True; 
q.SQL.Text := 'INSERT INTO table(name,email) VALUES(:PName, :PMail)'; 
q.Prepared := True; 

sa_OK := TArray<string>.Create('me','email1','you','email2','him','email3','them','email4'); 
// eeeaaasy example 

sa_err1 := TArray<string>.Create('me','email1','you','email2','him'); 
// check this out-of-sync error too - it can happen! you should be pre-aware! 

sa_err2 := TArray<string>.Create('Sarah O''Connor','email1','"Bobby F. Kennedy"','email2','him'#0'again','email3'); 
// not the letters you expected - but they can come too 

Procedure Method1_Fetcher(const sa: array of string); 
var i: integer; 
    s: string; 
    function Fetched: Boolean; 
    begin 
    Result := i <= High(sa); 
    if Result then begin 
     s := sa[i]; 
     Inc(i); 
    end; 
    end; 
Begin 
    i := Low(sa); 
    while true do begin 
    if not Fetched then break; 
    q.Params[1].AsWideString := s; 

    if not Fetched then break; 
    q.Params[2].AsWideString := s; 

    // ...you can easily add more parameters for more columns 
    // if not Fetched then break; 
    // q.Params[3].Value := s; 
    // ... or you can make a loop 
    // FOR j := 0 to q.Params.Count - 1 DO ... q.Params[j] :=... 

    // only executing insert if ALL the columns were filled 
    q.ExecSQL; 
    end; 

    q.Transaction.CommitWork; 
End; 

Procedure Method2_TickTock(const sa: array of string); 
var i, FSM: integer; 
Begin 

    FSM := 0; 
    for i := Low(sa) to High(sa) do begin 

    if FSM = 0 then begin 
     q.ParamByName('PName').AsWideString := sa[i]; 

     FSM := 1; // next mode of tick-tock 
     Continue; 
    end; 
    if FSM = 1 then begin 
     q.ParamByName('PMail').AsWideString := sa[i]; 
     q.ExecSQL; 
    // only executing insert after the last column was filled 

     FSM := 0; // next mode of tick-tock 
     Continue; 
    end; 

    /// would only come here if we made some mistake above 
    /// and FSM got impossible value - so no "Continue" was executed 
    /// show error and exit 

    raise EInvalidOperation.CreateFmt('FSM = %d', [FSM]); 
    end; 

    q.Transaction.CommitWork; 
End; 

Procedure Method3_SimplifiedFSM(const sa: array of string); 
// this method is actually are streamlined method #2 
// it can be made because all our steps are TOTALLY identical 
// (sans optional insert execution) 
var i, FSM: integer; 
Begin 

    FSM := 0; 
    for i := Low(sa) to High(sa) do begin 

    q.Params[ FSM ].AsWideString := sa[i]; 
    Inc(FSM); 
    if FSM >= q.Params.Count then begin 
     q.ExecSQL; // only after (if) last of all columns filled! 
     FSM := 0; 
    end; 

    end; 
    q.Transaction.CommitWork; 
End; 

现在,您可以调试像Method1(sa_OK)Method2(sa_err1)电话,看看它是如何工作的,以及它如何与错误

+0

我喜欢这个解决方案,但对于我来说这太复杂了。 谢谢你花时间回答我,并对不起,我花了很长时间才回答。 – Mathmathou

+0

意想不到的恶意输入可能会更糟...... –