2015-12-14 44 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

意想不到的惡意輸入可能會更糟...... –