SQlite3 Database Error Saving String to TEXT Field with CRLF lazarus / 16-Databases ---------------------------------------------------------------------- nugax · 2022-02-12 22:50 Hi, I am having what I consider a very strange issue. I have a database, that is a simple message db. It has a field called message that is TEXT in Sqlite3. here is the code that creates that table: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   'CREATE TABLE localmail (mailid integer not null primary key autoincrement, to_id varchar(255), from_id varchar(255), subject varchar(255), date varchar(255), read integer, message TEXT)');         The issue I am having is that I create a string (ANSISTRING) and write data to it. If I add CRLF by Append(sString, #10#13); it adds the new lines and the text is write, but the sql statement fails. If I do not add a second line, just type 1 line, it saves fine. Anyone have any idea. I have posted code for your review. Excuse the working areas. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit LineEditor; {$mode objfpc}{$H+} interface uses  Classes, SysUtils, strutils, cyberio, ansi, Fidonet, programinfo; procedure StartLineEditor(iQuoteMSGID: integer; sTypeMsg: string);//function LineEditor(sTo, sSubject, sMsgArea: string): fidonet.Msg;function GetMsgHeader(): TStringList; implementation uses  userhandler, sqlite, sqlite_mail, messagetools; //Run The Line Editorprocedure StartLineEditor(iQuoteMSGID: integer; sTypeMsg: string);var  lstHeader: TStrings;  sPostArea: string;  iCnt: byte;  byteTmp: byte;  sMessage: ansistring;  byInput: byte;  byUpdateLine: byte;  sControlGiven: string;  sToID: string;  sFromID: string;  sToHandle: string;  sFormattedMessage: string; begin   //Get Message Headers  lstHeader := GetMsgHeader();   case uppercase(sTypeMsg) of    'LOCALMAIL':    begin      sPostArea := 'localmail';      //Get User IDs      sToHandle := lstHeader[0];      sToId := sqlite.get_userid_from_handle(sToHandle);      sFromID := userhandler.recCurrentUser.UserID.ToString;     end;   end;     if (sPostArea <> 'localmail') then  begin    //Get Current User Area    sPostArea := userhandler.recCurrentUser.LastConference;    if (lstHeader[0] = '') then    begin      lstHeader[0] := 'ALL';  //Set To: field to ALL if nothing is given    end;   end;    //Print The Header  cyberio.PipeWriteCRLF;  cyberio.PipeWriteCRLF;   //Print Top Line  ansi.DrawDoubleLine('|15', 80);  cyberio.PipeWriteLnString('[CyberBBS Simple Line Editor V. ' + programinfo.sProgVersion + ']');  cyberio.PipeWriteLnString('   To: ' + lstHeader[0]);  cyberio.PipeWriteLnString(' Subj: ' + lstHeader[1]);  cyberio.PipeWriteLnString(' Date: ' + lstHeader[2]);    ansi.DrawDoubleLine('|15', 80);  cyberio.PipeWriteCRLF;    cyberio.GotoXY(cyberio.GetY, 15);  byUpdateLine := cyberio.GetY;  cyberio.PipeWriteLnString('|11[CTL-S | Save] [CTL-A | Abort]                   0/4096 ch');  cyberio.PipeWrit eLnString('|140---|----|----|----|----|----|----|----|----|----|----|- ---|----|----|----|---80');  cyberio.GotoXY(cyberio.GetY, 0);   iCnt := 0;  sMessage := '';  repeat    byInput := cyberio.PipeReadByte();  case chr(byInput) of      ^S: sControlGiven := 'ctl-s';      ^A: sControlGiven := 'ctl-a';      #8, #127:      begin         Delete(sMessage, length(sMessage), 1); //Delete 1 space        cyberio.AnsiMoveLeft1;        cyberio.PipeWriteString(' ');        cyberio.AnsiMoveLeft1;       end;      #10:      begin        cyberio.PipeWriteCRLF;        AppendStr(sMessage, #10#13);      end     else      begin        ansi.SetForeColor(BrightGreen);        cyberio.PipeWriteByte(byInput);        sMessage := sMessage + chr(byInput);        byInput := 0;      end;     end;      //  cyberio.GotoXY(15, 70);    // cyberio.PipeWriteString(iCnt.ToString);    until ((sControlGiven = 'ctl-s') or (sControlGiven = 'ctl-a'));   case sControlGiven of    'ctl-s': begin       cyberio.PipeFlushBuffer1B;      cyberio.PipeFlushWriteBuffer1B;      cyberio.PipeWriteCRLF;      cyberio.PipeWriteLNString('|10Message sent.');        //sFormattedMessage := messagetools.AddFTNTag(arrayMessage, sPostArea);      // sFormattedMessage := arrayMessage;       if (sPostArea = 'localmail') then      begin        sqlite_mail.addLocalMessage(sToId, sFromID, lstHeader[1], lstHeader[2], sMessage);      end;     end;     'ctl-a': begin      cyberio.PipeFlushBuffer1B;      cyberio.PipeFlushWriteBuffer1B;      cyberio.PipeWriteCRLF;      cyberio.PipeWriteLNString('|12Message aborted.');      wait(1);      cyberio.PipeWriteLNString('Press any key');      cyberio.GetAnyKey();    end;   end;end;  //Get The Message Header Informationfunction GetMsgHeader(): TStringList;var  sTo: string;  sFrom: string;  sSubject: string;  sDate: string;  lstHeader: TStringList; begin  //Move cursor to 1st char/next line  cyberio.PipeWriteCRLF;   //Get Data  cyberio.PipeWriteString('|15To: |11');  sTo := cyberio.PipeReadString();  cyberio.PipeWriteCRLF;  cyberio.PipeWriteString('|15Subject: |11');  sSubject := cyberio.PipeReadString();  cyberio.PipeWriteCRLF;   //Create Header  sDate := messagetools.MsgDateStamp;  //cyberio.PipeWriteString('|15Date: |11' + sDate);  sleep(250);   //Construct The Header  lstHeader := TStringList.Create;  lstHeader.Add(sTo);  lstHeader.Add(sSubject);  lstHeader.Add(sDate);   //Return TStrings List Of Header Info  GetMsgHeader := lstHeader;end; end.   Here is an example of the SQL statement generated: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i sql_add: INSERT INTO localmail (to_id, from_id, subject, date, read, message) VALUES ('1', '1', 'test2', '12 Feb 22 16:40:56', '0', 'line1line2') ---------------------------------------------------------------------- paweld · 2022-02-13 04:50 use parametresL https://wiki.lazarus.freepascal.org/SqlDBHowto#How_to_ use_parameters_in_a_query.3F eg. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i SQLQuery1.SQL.Clear;SQLQuery1.SQL.Add(' INSERT INTO localmail (to_id, from_id, subject, date, read, message) ');SQLQuery1.SQL.Add(' VALUES (:to, :from, :subject, :date, :read, :message) ');SQLQuery1.ParamByName('to').AsInteger := 1;SQLQuery1.ParamByName('from').AsInteger := 1;SQLQuery1.ParamByName('subject').AsString := 'test2';SQLQuery1.ParamByName('subject').AsString := '12 Feb 22 16:40:56';SQLQuery1.ParamByName('read').AsInteger := 0;SQLQuery1.ParamByName('subject').AsString := 'line1' + LineEnding + 'line3';SQLQuery1.ExecSQL; ---------------------------------------------------------------------- Zvoni · 2022-02-14 07:50 Shouldn't line 7 be 'date' and Line 9 'message'? ---------------------------------------------------------------------- nugax · 2022-02-14 14:42 I tried adding LineEnding (#10) your suggestion. It did the same thing and did not save. The SQL will run if you manually enter it into Sqlite. I am collecting the text as chars. Any other idea? Quote from: paweld on February 13, 2022, 05:50:29 amuse parametresL ht tps://wiki.lazarus.freepascal.org/SqlDBHowto#How_to_use_parameters_in_ a_query.3F eg. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i SQLQuery1.SQL.Clear;SQLQuery1.SQL.Add(' INSERT INTO localmail (to_id, from_id, subject, date, read, message) ');SQLQuery1.SQL.Add(' VALUES (:to, :from, :subject, :date, :read, :message) ');SQLQuery1.ParamByName('to').AsInteger := 1;SQLQuery1.ParamByName('from').AsInteger := 1;SQLQuery1.ParamByName('subject').AsString := 'test2';SQLQuery1.ParamByName('subject').AsString := '12 Feb 22 16:40:56';SQLQuery1.ParamByName('read').AsInteger := 0;SQLQuery1.ParamByName('subject').AsString := 'line1' + LineEnding + 'line3';SQLQuery1.ExecSQL; ---------------------------------------------------------------------- nugax · 2022-02-14 14:55 Here is the code I tried. It failed as well. Where am I going wrong? Seems simple enough... Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function addLocalMessage(sTo_Id, sFrom_Id, sSubject, sDate: string; sMessage: ansistring): boolean;var  Connect: TSQLite3Connection;  Trans: TSQLTransaction;  SQLQuery1 : TSQLQuery;  db_name: string;  sql_add: ansistring;  iRead: integer; begin   SQLQuery1 := TSQLQuery.Create(nil);   //Set DB Name  db_name := programinfo.cbbsInfo.sLocalMailDB;   //User DB   //Set Read  iRead := 0;   //sql_add := '';  //Set SQL Command To Add User  //sql_add := 'INSERT INTO localmail (to_id, from_id, subject, date, read, message) VALUES (''' + sTo_Id + ''', ''' +  //  sFrom_Id + ''', ''' + sSubject + ''', ''' + sDate + ''', ''' + iRead.ToString + ''', ''' + sMessage + ''')'; SQLQuery1.SQL.Clear;SQLQuery1.SQL.Add(' INSERT INTO localmail (to_id, from_id, subject, date, read, message) ');SQLQuery1.SQL.Add(' VALUES (:to, :from, :subject, :date, :read, :message) ');SQLQuery1.ParamByName('to').AsString := sTo_ID;SQLQuery1.ParamByName('from').AsString := sFrom_ID;SQLQuery1.ParamByName('subject').AsString := sSubject;SQLQuery1.ParamByName('date').AsString := sDate;SQLQuery1.ParamByName('read').AsInteger := 0;SQLQuery1.ParamByName('message').AsString := sMessage;     //Write('sql_add: ' + sql_add);  //Code to Add User  Connect := TSQLite3Connection.Create(nil);  Trans := TSQLTransaction.Create(Connect);  Connect.Transaction := Trans;  Connect.DatabaseName := db_name;  SQLQuery1.ExecSQL;  Trans.StartTransaction;  // opens Connect, EInOutError if SQLite not installed  try  //  Connect.ExecuteDirect(sql_add);  finally  end;   sleep(500);  SQLQuery1.close;  SQLQuery1.free;  Trans.Commit;  Trans.Free;  Connect.Free;  write('Added msg');  //Return Boolean result as sql finished. | Assume it entered if no errors. Sqlite3 likes to error if it didnt work.  exit(True); end;               Quote from: paweld on February 13, 2022, 05:50:29 amuse parametresL ht tps://wiki.lazarus.freepascal.org/SqlDBHowto#How_to_use_parameters_in_ a_query.3F eg. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i SQLQuery1.SQL.Clear;SQLQuery1.SQL.Add(' INSERT INTO localmail (to_id, from_id, subject, date, read, message) ');SQLQuery1.SQL.Add(' VALUES (:to, :from, :subject, :date, :read, :message) ');SQLQuery1.ParamByName('to').AsInteger := 1;SQLQuery1.ParamByName('from').AsInteger := 1;SQLQuery1.ParamByName('subject').AsString := 'test2';SQLQuery1.ParamByName('subject').AsString := '12 Feb 22 16:40:56';SQLQuery1.ParamByName('read').AsInteger := 0;SQLQuery1.ParamByName('subject').AsString := 'line1' + LineEnding + 'line3';SQLQuery1.ExecSQL; ---------------------------------------------------------------------- nugax · 2022-02-14 15:00 Also, Here is the table we are trying to write to: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i sqlite> .schemaCREATE TABLE localmail (mailid integer not null primary key autoincrement, to_id varchar(255), from_id varchar(255), subject varchar(255), date varchar(255), read integer, message TEXT);CREATE TABLE sqlite_sequence(name,seq);sqlite> Quote from: paweld on February 13, 2022, 05:50:29 amuse parametresL ht tps://wiki.lazarus.freepascal.org/SqlDBHowto#How_to_use_parameters_in_ a_query.3F eg. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i SQLQuery1.SQL.Clear;SQLQuery1.SQL.Add(' INSERT INTO localmail (to_id, from_id, subject, date, read, message) ');SQLQuery1.SQL.Add(' VALUES (:to, :from, :subject, :date, :read, :message) ');SQLQuery1.ParamByName('to').AsInteger := 1;SQLQuery1.ParamByName('from').AsInteger := 1;SQLQuery1.ParamByName('subject').AsString := 'test2';SQLQuery1.ParamByName('subject').AsString := '12 Feb 22 16:40:56';SQLQuery1.ParamByName('read').AsInteger := 0;SQLQuery1.ParamByName('subject').AsString := 'line1' + LineEnding + 'line3';SQLQuery1.ExecSQL; ---------------------------------------------------------------------- nugax · 2022-02-14 15:01 Also, here is the collection routine that runs the editor that collects sMessage and other variables and then calls the database unit to add them to the database... Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit SimpleLineEditor; {$mode objfpc}{$H+} interface uses  Classes, SysUtils, strutils, cyberio, ansi, Fidonet, programinfo; procedure StartLineEditor(iQuoteMSGID: integer; sTypeMsg: string);//function LineEditor(sTo, sSubject, sMsgArea: string): fidonet.Msg;function GetMsgHeader(): TStringList; implementation uses  userhandler, sqlite, sqlite_mail, messagetools; //Run The Line Editorprocedure StartLineEditor(iQuoteMSGID: integer; sTypeMsg: string);var  lstHeader: TStrings;  sPostArea: string;  iCnt: byte;  byteTmp: byte;  sMessage: ansistring;  byInput: byte;  byUpdateLine: byte;  sControlGiven: string;  sToID: string;  sFromID: string;  sToHandle: string;  sFormattedMessage: string;  chCharInput: char; begin   //Get Message Headers  lstHeader := GetMsgHeader();   case uppercase(userhandler.recCurrentUser.LastConference) of    'LOCAL.SYSTEM_MAIL':    begin      //Get User IDs      sToHandle := lstHeader[0];      sToId := sqlite.get_userid_from_handle(sToHandle);      sFromID := userhandler.recCurrentUser.UserID.ToString;     end;   end;   //Add Check For ALl   //Print The Header  cyberio.PipeWriteCRLF;  cyberio.PipeWriteCRLF;   //Print Top Line  ansi.DrawDoubleLine('|15', 80);  cyberio.PipeWriteLnString('[CyberBBS Simple Line Editor V. ' + programinfo.sProgVersion + ']');  cyberio.PipeWriteLnString('   To: ' + lstHeader[0]);  cyberio.PipeWriteLnString(' Subj: ' + lstHeader[1]);  cyberio.PipeWriteLnString(' Date: ' + lstHeader[2]);    ansi.DrawDoubleLine('|15', 80);  cyberio.PipeWriteCRLF;    cyberio.GotoXY(cyberio.GetY, 15);  byUpdateLine := cyberio.GetY;  cyberio.PipeWriteLnString('|11[CTL-S | Save] [CTL-A | Abort]                 0/4096 ch');  cyberio.PipeWriteLnString('|140---|----|----|--- -|----|----|----|----|----|----|----|----|----|----|----|---80');  cyberio.GotoXY(cyberio.GetY, 0);   iCnt := 0;  sMessage := '';  repeat    //byInput := cyberio.PipeReadByte();    chCharInput := cyberio.PipeReadAllChar();    // case chr(byInput) of    case chCharInput of       chr(19) : sControlGiven := 'ctl-s';      chr(1)  : sControlGiven := 'ctl-a';      #8, #127:      begin         Delete(sMessage, length(sMessage), 1); //Delete 1 space        cyberio.AnsiMoveLeft1;        cyberio.PipeWriteString(' ');        cyberio.AnsiMoveLeft1;       end;      #10, #13:      begin        AppendStr(sMessage , system.LineEnding);        cyberio.PipeWriteCRLF;      end;        #32.. #126:      begin        ansi.SetForeColor(BrightGreen);        //cyberio.PipeWriteByte(byInput);        cyberio.PipeWriteChar(chCharInput);        //AppendStr(sMessage, chr(byInput));        AppendStr(sMessage, chCharInput);        byInput := 0;      end;     end;    until ((sControlGiven = 'ctl-s') or (sControlGiven = 'ctl-a'));   case sControlGiven of    'ctl-s': begin       //cyberio.PipeFlushBuffer1B;      // cyberio.PipeFlushWriteBuffer1B;      //   cyberio.PipeWriteCRLF;      cyberio.PipeWriteLNString('|10Message sent.');        // sFormattedMessage := messagetools.AddFTNTag(sMessage);      //sFormattedMessage := sMessage;       if (userhandler.recCurrentUser.LastConference = 'local.System_Mail') then      begin        sqlite_mail.addLocalMessage(sToId, sFromID, lstHeader[1], lstHeader[2], sMessage);      end;     end;     'ctl-a': begin      cyberio.PipeFlushBuffer1B;      cyberio.PipeFlushWriteBuffer1B;      cyberio.PipeWriteCRLF;      cyberio.PipeWriteLNString('|12Message aborted.');      wait(1);      cyberio.PipeWriteLNString('Press any key');      cyberio.GetAnyKey();    end;   end;end;  //Get The Message Header Informationfunction GetMsgHeader(): TStringList;var  sTo: string;  sFrom: string;  sSubject: string;  sDate: string;  lstHeader: TStringList; begin  //Move cursor to 1st char/next line  cyberio.PipeWriteCRLF;   //Get Data  cyberio.PipeWriteString('|15To: |11');  sTo := cyberio.PipeReadString();  cyberio.PipeWriteCRLF;  cyberio.PipeWriteString('|15Subject: |11');  sSubject := cyberio.PipeReadString();  cyberio.PipeWriteCRLF;   //Create Header  sDate := messagetools.MsgDateStamp;  //cyberio.PipeWriteString('|15Date: |11' + sDate);  sleep(250);   //Construct The Header  lstHeader := TStringList.Create;  lstHeader.Add(sTo);  lstHeader.Add(sSubject);  lstHeader.Add(sDate);   //Return TStrings List Of Header Info  GetMsgHeader := lstHeader;end; end.   Quote from: paweld on February 13, 2022, 05:50:29 amuse parametresL ht tps://wiki.lazarus.freepascal.org/SqlDBHowto#How_to_use_parameters_in_ a_query.3F eg. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i SQLQuery1.SQL.Clear;SQLQuery1.SQL.Add(' INSERT INTO localmail (to_id, from_id, subject, date, read, message) ');SQLQuery1.SQL.Add(' VALUES (:to, :from, :subject, :date, :read, :message) ');SQLQuery1.ParamByName('to').AsInteger := 1;SQLQuery1.ParamByName('from').AsInteger := 1;SQLQuery1.ParamByName('subject').AsString := 'test2';SQLQuery1.ParamByName('subject').AsString := '12 Feb 22 16:40:56';SQLQuery1.ParamByName('read').AsInteger := 0;SQLQuery1.ParamByName('subject').AsString := 'line1' + LineEnding + 'line3';SQLQuery1.ExecSQL; ---------------------------------------------------------------------- Zvoni · 2022-02-14 15:06 second code-block Line 7 should be 'date', and line 9 should be 'message'? You're inserting the LineEnding into the "Subject"-Column....... ---------------------------------------------------------------------- nugax · 2022-02-14 15:12 I changed it to the correct values... Here is my code: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function addLocalMessage(sTo_Id, sFrom_Id, sSubject, sDate: string; sMessage: string): boolean;var  Connect: TSQLite3Connection;  Trans: TSQLTransaction;  SQLQuery1 : TSQLQuery;  db_name: string;  sql_add: ansistring;  iRead: integer; begin   SQLQuery1 := TSQLQuery.Create(nil);   //Set DB Name  db_name := programinfo.cbbsInfo.sLocalMailDB;   //User DB   //Set Read  iRead := 0;   //sql_add := '';  //Set SQL Command To Add User  //sql_add := 'INSERT INTO localmail (to_id, from_id, subject, date, read, message) VALUES (''' + sTo_Id + ''', ''' +  //  sFrom_Id + ''', ''' + sSubject + ''', ''' + sDate + ''', ''' + iRead.ToString + ''', ''' + sMessage + ''')'; SQLQuery1.SQL.Clear;SQLQuery1.SQL.Add(' INSERT INTO localmail (to_id, from_id, subject, date, read, message) ');SQLQuery1.SQL.Add(' VALUES (:to, :from, :subject, :date, :read, :message) ');SQLQuery1.ParamByName('to').AsString := sTo_ID;SQLQuery1.ParamByName('from').AsString := sFrom_ID;SQLQuery1.ParamByName('subject').AsString := sSubject;SQLQuery1.ParamByName('date').AsString := sDate;SQLQuery1.ParamByName('read').AsInteger := 0;SQLQuery1.ParamByName('message').AsString := sMessage;     //Write('sql_add: ' + sql_add);  //Code to Add User  Connect := TSQLite3Connection.Create(nil);  Trans := TSQLTransaction.Create(Connect);     Connect.Open;  Connect.Transaction := Trans;  Connect.DatabaseName := db_name;   SQLQuery1.DataBase := Connect;  SQLQuery1.ExecSQL;  Trans.StartTransaction;  // opens Connect, EInOutError if SQLite not installed  try  //  Connect.ExecuteDirect(sql_add);  finally  end;   sleep(500);  SQLQuery1.close;  SQLQuery1.free;  Trans.Commit;  Trans.Free;  Connect.Free;  write('Added msg');  //Return Boolean result as sql finished. | Assume it entered if no errors. Sqlite3 likes to error if it didnt work.  exit(True); end;                                 Quote from: Zvoni on February 14, 2022, 04:06:35 pmsecond code-block Line 7 should be 'date', and line 9 should be 'message'? I You're inserting the LineEnding into the "Subject"-Column....... ---------------------------------------------------------------------- nugax · 2022-02-14 15:13 Im not even adding LineEnding in the SQL. I am adding that in the routine that collects the data that goes into creating the sMessage variable Quote from: Zvoni on February 14, 2022, 04:06:35 pmsecond code-block Line 7 should be 'date', and line 9 should be 'message'? You're inserting the LineEnding into the "Subject"-Column....... ---------------------------------------------------------------------- paweld · 2022-02-14 19:37 @Zvoni - thank you for your vigilance @nugax - sample in attachment