Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7583975
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 30, 20262026-05-30T18:48:41+00:00 2026-05-30T18:48:41+00:00

I’m migrating an old Delphi application (using ZeosDB) to Delphi XE2. I want to

  • 0

I’m migrating an old Delphi application (using ZeosDB) to Delphi XE2. I want to use dbExpress as a ZeosDB replacement for database access to Firebird 2.5 or MS-SQL.
There are a lot of sql scripts for creating tables, view and stored procedures I need to run. The Firebird script commands are seperated with ^, MS-SQL script commands with “GO”.

How can I run these scripts on the database using a dbexpress connection? ZeosDB provides a TZSqlProcessor, but I can’t find any equivalent component for dbExpress.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-30T18:48:43+00:00Added an answer on May 30, 2026 at 6:48 pm

    I do not use DBExpress but as far as I am aware, you can execute (either by Execute or ExecuteDirect) only one SQL command at a time. In other words you cannot put the whole script into the Execute method.

    This is not related to different command syntax used by FireBird and MS SQL (^ vs. GO). You have to understand the ‘^’ sign or ‘GO’ command is not a “TSQL Command”! Both are specific command delimiters used by respective application used to execute commands against the SQL engines. Instead it is difference between “Firebird Manager” (or how it’s called) and “SQL Query Profiler” (or “SQL Server Management Studio”).

    The solution is to use some kind of parser, split the script into a list of single commands, and TSQLConnection.Execute these commands one-by-one.

    Something like this pseudocode:

    var
      DelimiterPos: Integer;
      S: String;
      Command: String;
    begin
      S:= ScriptFile; // ScriptFile: String - your whole script
      While True Do
      begin
        DelimiterPos:= Pos('^', ScriptFile);
        if DelimiterPos = 0 then DelimiterPos:= Length(S);
        Command:= Copy(S, 1, DelimiterPos - 1);
        SQLConnection.Execute(Command);
        Delete(S, 1, DelimiterPos);
        if Lengh(S) = 0 Then Exit;
      end;
    end;
    

    Please note that the sample above will work correctly only in cases that the ‘^’ sign is not used anywhere in the script but a command separator.

    As a sidenote, I am sure there are some already built components that will do that for you (like TZSQLProcessor). I am not aware of any to point you to.

    Sidenote 2: I am pretty sure, that you’ll have to modify your scripts to be fully compatible with MS SQL. Eventhough Firebird and MS SQL are both SQL servers there is always difference in DML/DDL syntax.

    Edit:

    1. If you can “rewrite” the SQL script into the code, you could use Jedi VCL jvStringHolder component. Put each separate command as one item (of type TStrings) in jvStringHolder.

    2. Creating the parser is rather complicated, but not undoable. With the inspiration from SynEdit i made these clases to exactly what you need: Load the script with TSQLScript.ParseScript, then iterate through Command[index: integer] property. The SQLLexer is not full SQL Lexer, but implements keywords separation with respec to comments, brackets, code folding etc. I’ve also added a special syntax into comments ($ sign in comment block) that helps me put titles into the script.
      This is full copy-paste from one of my projects. I’m not giving any more explanation, but I hope you can get the idea and make it running in your project.

    unit SQLParser;

    interface
    
    type
    
      TTokenKind = (tkUknown, tkEOF, tkComment, tkKeyword, tkIdentifier,
                    tkCommentParam, tkCommentParamValue, tkCommandEnd, tkCRLF);
    
      TBlockKind = (bkNone, bkLineComment, bkBlockComment);
    
      TSQLLexer = class
      private
        FBlockKind: TBlockKind;
        FParseString: String;
        FPosition: PChar;
        FTokenKind: TTokenKind;
        FTokenPosition: PChar;
        function GetToken: String;
        procedure Reset;
        procedure SetParseString(Value: String);
      protected
        procedure ReadComment;
        procedure ReadCommentParam;
        procedure ReadCommentParamValue;
        procedure ReadCRLF;
        procedure ReadIdentifier;
        procedure ReadSpace;
      public
        constructor Create(ParseString: String);
        function NextToken: TTokenKind;
    
        property Position: PChar read FPosition;
        property SQLText: String read FParseString write SetParseString;
        property Token: String read GetToken;
        property TokenKind: TTokenKind read FTokenKind;
        property TokenPosition: PChar read FTokenPosition;
      end;
    
    
    
    implementation
    
    uses SysUtils;
    
    { TSQLLexer }
    
    constructor TSQLLexer.Create(ParseString: string);
    begin
      inherited Create;
      FParseString:= ParseString;
      Reset;
    end;
    
    function TSQLLexer.GetToken;
    begin
      SetString(Result, FTokenPosition, FPosition - FTokenPosition);
    end;
    
    function TSQLLexer.NextToken: TTokenKind;
    begin
      case FBlockKind of
        bkLineComment, bkBlockComment: ReadComment;
        else
          case FPosition^ of
          #0: FTokenKind:= tkEOF;
          #1..#9, #11, #12, #14..#32:
            begin
              ReadSpace;
              NextToken;
            end;
          #10, #13: ReadCRLF;
          '-':
            if PChar(FPosition +1)^ = '-' then
              ReadComment
            else
              Inc(FPosition);
          '/':
            if PChar(FPosition +1)^ = '*' then
              ReadComment
            else
              Inc(FPosition);
          'a'..'z', 'A'..'Z': ReadIdentifier;
          ';':
            begin
              FTokenPosition:= FPosition;
              Inc(FPosition);
              FTokenKind:= tkCommandEnd;
            end
          else
            Inc(FPosition);
          end;
      end;
      Result:= FTokenKind;
    end;
    
    
    procedure TSQLLexer.ReadComment;
    begin
      FTokenPosition:= FPosition;
      if not (FBlockKind in [bkLineComment, bkBlockComment])  then
      begin
        if FPosition^ = '/' then
          FBlockKind:= bkBlockComment
        else
          FBlockKind:= bkLineComment;
        Inc(FPosition, 2);
      end;
      case FPosition^ of
        '$': ReadCommentParam;
        ':': ReadCommentParamValue;
      else
        while not CharInSet(FPosition^, [#0, '$']) do
        begin
          if FBlockKind = bkBlockComment then
          begin
            if (FPosition^ = '*') And (PChar(FPosition + 1)^ = '/') then
            begin
              Inc(FPosition, 2);
              FBlockKind:= bkNone;
              Break;
            end;
          end
          else
          begin
            if CharInSet(Fposition^, [#10, #13]) then
            begin
              ReadCRLF;
              FBlockKind:= bkNone;
              Break;
            end;
          end;
          Inc(FPosition);
        end;
        FTokenKind:= tkComment;
      end;
    end;
    
    procedure TSQLLexer.ReadCommentParam;
    begin
      Inc(FPosition);
      ReadIdentifier;
      FTokenKind:= tkCommentParam;
    end;
    
    procedure TSQLLexer.ReadCommentParamValue;
    begin
      Inc(FPosition);
      ReadSpace;
      FTokenPosition:= FPosition;
      while not CharInSet(FPosition^, [#0, #10, #13]) do
        Inc(FPosition);
      FTokenKind:= tkCommentParamValue;
    end;
    
    procedure TSQLLexer.ReadCRLF;
    begin
      while CharInSet(FPosition^, [#10, #13]) do
        Inc(FPosition);
      FTokenKind:= tkCRLF;
    end;
    
    procedure TSQLLexer.ReadIdentifier;
    begin
      FTokenPosition:= FPosition;
      while CharInSet(FPosition^, ['a'..'z', 'A'..'Z', '_']) do
        Inc(FPosition);
    
      FTokenKind:= tkIdentifier;
    
      if Token = 'GO' then
        FTokenKind:= tkKeyword;
    end;
    
    procedure TSQLLexer.ReadSpace;
    begin
      while CharInSet(FPosition^, [#1..#9, #11, #12, #14..#32]) do
      Inc(FPosition);
    end;
    
    procedure TSQLLexer.Reset;
    begin
      FTokenPosition:= PChar(FParseString);
      FPosition:= FTokenPosition;
      FTokenKind:= tkUknown;
      FBlockKind:= bkNone;
    end;
    
    procedure TSQLLexer.SetParseString(Value: String);
    begin
      FParseString:= Value;
      Reset;
    end;
    
    end.
    

    The parser:

    type
      TScriptCommand = class
      private
        FCommandText: String;
      public
        constructor Create(ACommand: String);
        property CommandText: String read FCommandText write FCommandText;
      end;
    
      TSQLScript = class
      private
        FCommands: TStringList;
        function GetCount: Integer;
        function GetCommandList: TStrings;
        function GetCommand(index: Integer): TScriptCommand;
      protected
        procedure AddCommand(AName: String; ACommand: String);
      public
        Constructor Create;
        Destructor Destroy; override;
        procedure ParseScript(Script: TStrings);
    
        property Count: Integer read GetCount;
        property CommandList: TStrings read GetCommandList;
        property Command[index: integer]: TScriptCommand read GetCommand;
      end;
    
    { TSQLScriptCommand }
    
    constructor TScriptCommand.Create(ACommand: string);
    begin
      inherited Create;
      FCommandText:= ACommand;
    end;
    
    { TSQLSCript }
    
    constructor TSQLScript.Create;
    begin
      inherited;
      FCommands:= TStringList.Create(True);
      FCommands.Duplicates:= dupIgnore;
      FCommands.Sorted:= False;
    end;
    
    destructor TSQLScript.Destroy;
    begin
      FCommands.Free;
      inherited;
    end;
    
    procedure TSQLScript.AddCommand(AName, ACommand: String);
    var
      ScriptCommand: TScriptCommand;
      S: String;
    begin
      if AName = '' then
        S:= SUnnamedCommand
      else
        S:= AName;
      ScriptCommand:= TScriptCommand.Create(ACommand);
      FCommands.AddObject(S, ScriptCommand);
    end;
    
    function TSQLScript.GetCommand(index: Integer): TScriptCommand;
    begin
      Result:= TScriptCommand(FCommands.Objects[index]);
    end;
    
    function TSQLScript.GetCommandList: TStrings;
    begin
      Result:= FCommands;
    end;
    
    function TSQLScript.GetCount: Integer;
    begin
      Result:= FCommands.Count;
    end;
    
    procedure TSQLScript.ParseScript(Script: TStrings);
    var
      Title: String;
      Command: String;
      LastParam: String;
      LineParser: TSQLLexer;
      IsNewLine: Boolean;
      LastPos: PChar;
    
      procedure AppendCommand;
      var
        S: String;
      begin
        SetString(S, LastPos, LineParser.Position - LastPos);
        Command:= Command + S;
        LastPos:= LineParser.Position;
      end;
    
      procedure FinishCommand;
      begin
        if Command <> '' then
          AddCommand(Title, Command);
        Title:= '';
        Command:= '';
        LastPos:= LineParser.Position;
        if LastPos^ = ';' then Inc(LastPos);
      end;
    
    begin
      LineParser:= TSQLLexer.Create(Script.Text);
      try
        LastPos:= LineParser.Position;
        IsNewLine:= True;
        repeat
          LineParser.NextToken;
          case LineParser.TokenKind of
            tkComment: LastPos:= LineParser.Position;
            tkCommentParam:
              begin
                LastParam:= UpperCase(LineParser.Token);
                LastPos:= LineParser.Position;
              end;
            tkCommentParamValue:
              if LastParam = 'TITLE' then
              begin
                Title:= LineParser.Token;
                LastParam:= '';
                LastPos:= LineParser.Position;
              end;
            tkKeyword:
                if (LineParser.Token = 'GO') and IsNewLine then FinishCommand
                else
                  AppendCommand;
            tkEOF:
              FinishCommand;
            else
              AppendCommand;
          end;
          IsNewLine:= LineParser.TokenKind in [tkCRLF, tkCommandEnd];
        until LineParser.TokenKind = tkEOF;
      finally
        LineParser.Free;
      end;
    end;
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I want use html5's new tag to play a wav file (currently only supported
link Im having trouble converting the html entites into html characters, (&# 8217;) i
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I want to count how many characters a certain string has in PHP, but
I am trying to understand how to use SyndicationItem to display feed which is
I have a French site that I want to parse, but am running into
I'm using v2.0 of ClassTextile.php, with the following call: $testimonial_text = $textile->TextileRestricted($_POST['testimonial']); ... and
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
We're building an app, our first using Rails 3, and we're having to build
We are using XSLT to translate a RIXML file to XML. Our RIXML contains

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.