Jump to content

FredS

Members
  • Content Count

    408
  • Joined

  • Last visited

  • Days Won

    4

Posts posted by FredS


  1. 57 minutes ago, dkprojektai said:

    Can you share ?

    I can show you an example but most of my code uses internal stuff.
    But let me make one thing clearer; the action after Beyond Compare is manual NOT automatic..

     

    In short, after comparing the prior db creation script with the new one methods within the Patching unit are called manually..

     

    This example increase the Size of a [N]Varchar Column using UniDAC, FB3/4 and SqlServer dbs:

    /// <summary>
    ///   Increase the Size of a [N]Varchar Column
    /// </summary>
    /// <param name="NullKind">
    ///   Must be given else some dbs default to allowing nulls when you make changes
    /// </param>
    class procedure TExecSqlPatch.IncVarChar(const Con: TUniConnection; const ATable, AColumn: string; const NewSize: Word; const NullKind: TNullKind);
    {$REGION 'History'}
    //  29-Aug-2018 - ExecuteSQL does not return any usefull count for these Block calls
    {$ENDREGION}
    var sql: string;
    begin
      case Con.DbProvider of
        dbFirebird: begin
            sql := 'EXECUTE block as BEGIN ' +
                   ' if (exists(select 1 from RDB$RELATION_FIELDS rf where rf.RDB$RELATION_NAME = :TableName and rf.RDB$FIELD_NAME = :ColumnName))' + CRLF +
                   ' then execute statement ' + 'ALTER TABLE :TableRaw ALTER COLUMN :ColumnRaw Type VARCHAR(:NewSize)'.ToQuoted + SEMICOLON + CRLF +
                   'END';
            sql.ReplaceParams([ATable.ToUpper, AColumn.ToUpper, ParamRaw + ATable.ToUpper, ParamRaw + AColumn.ToUpper, NewSize]).Error.Assert;
            Con.ExecuteSQL(sql);
            sql := 'EXECUTE block as BEGIN ' +
                   ' if (exists(select 1 from RDB$RELATION_FIELDS rf where rf.RDB$RELATION_NAME = :TableName and rf.RDB$FIELD_NAME = :ColumnName))' + CRLF +
                   ' then execute statement ' + 'ALTER TABLE :TableRaw ALTER :ColumnRaw :NullKind NOT NULL'.ToQuoted + SEMICOLON + CRLF +
                   'END';
            sql.ReplaceParams([ATable.ToUpper, AColumn.ToUpper, ParamRaw + ATable.ToUpper, ParamRaw + AColumn.ToUpper,  ParamRaw + cFB3NullKind[NullKind]]).Error.Assert;
            Con.ExecuteSQL(sql);
        end;
        dbSQLServer: begin
            sql := 'IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE [TABLE_NAME] = :Table AND [COLUMN_NAME] = :Column) ' + CRLF +
                   'BEGIN ' + CRLF +
                   '  ALTER TABLE :TableRaw ALTER COLUMN :ColumnRaw NVARCHAR(:NewSize) :NullKind  ' + CRLF +
                   'END ';
            sql.ReplaceParams([ATable.ToUpper, AColumn.ToUpper, ParamRaw + ATable.ToUpper, ParamRaw + AColumn.ToUpper, NewSize, ParamRaw + cMSSQLNullKind[NullKind]]).Error.Assert;
            Con.ExecuteSQL(sql);
        end;
        else raise ENotImplemented.Create('Not Implemented');
      end;
    end;

     

    • Like 1

  2. 7 hours ago, dkprojektai said:

    Asking for advice quicker solution.

    I wrapped most Alter statements into a 'SQL.Patching.pas' unit which fires what is needed depending on a version field at startup.

    Found the simplest way was to make all changes and then use Beyond Compare on the db creation script to generate an output which is used to call the methods in the Patching unit.


  3. 5 hours ago, Nasreddine said:

    will freeze the app waiting

    Not if you you code it to respond to the Classes.SyncEvent : https://stackoverflow.com/a/61022449

     

    2 hours ago, Nasreddine said:

    block current execution while pumping the message queue,

    I use both, in one case I have many threads collecting data and triggering updates to a form while getting ready to launch another Task I don't want to pause the updates so a call gets wrapped in an Async which uses the trick above.. but I try to only do that for single calls that are guaranteed to take a short time.


  4. 8 hours ago, Serge_G said:

    If it's a vote

    I use Flamerobin

     

    Always loved Flamerobin, one of the best functions in Flamerobin is their quick way to 'Generate rebuild script'..


  5. 2 hours ago, Der schöne Günther said:

    It is what happens when the application that called ShellExecute did not provide a HWND of a foreground window. What is the value of your

    I also ran a couple of tests and it made no diff; Zero, GetDesktopHandle, GetActiveWindow, Application.Handle and Mainform.handle all appeared as normal.

     

     

     

×