Revision History for AbaPerls – Details

This page lists all changes to the AbaPerls tools and documentation from the first public release L1.0.0009 and on. (OK, not all changes, but the level of detail is fairly high.) The horizontal lines divide external public releases from each other. For a compact history for the external releases, see this page.


The eleventh public release of AbaPerls.




AbaPerls now supports temporal tables. See the new manual page for temporal tables for details. Beware that to use temporal tables, the database must be upgraded to label L1.0.0400 of the ABAPERLS subsystem.

There are also some changes related to indexes:


A couple of fixes/changes:


AbaPerls did not handle the syntax for the trim() function correctly, so SELECT trim(@chars FROM string) would result in the error that the table source string was not found. This has been fixed.


Previously, if a file included another file multiple times, directly or indirectly through other include files, AbaPerls would attempt to load the include file multiple times into abahistsysobjects, with a risk that this would fail with a duplicate key. This has been changed so that AbaPerls only enters the file once.


The enhancement on 2021-02-22 introduced a bug. .fkey files failed to load if the constraints were defined in multiple ALTER TABLE statements. This has been fixed.

DBBUILD and DBUPDGEN had some special handling for types with name ending in _upduser. These specials have been removed.


The loading of files with foreign keys have been improved, so that keys that have not changed will not be dropped and recreated. If the definition is the same, but the name is different, AbaPerls will rename the existing constraint but not reload it. This can save significant amount of time when loading constraints for big tables. Note that this improvement only applies if the ABAPERLS subsystem is on at least label L1.0.0385, as it requires an new stored procedure, ap_compare_fkeys_sp.


An enhancement to the $DBPERM directive. If an object was dropped and reloaded, the permissions granted on the object through $DBPERM were lost. Now when you load an object, AbaPerls checks if there are permissions for the object stored in abaspecialperms, and in such case AbaPerls reruns the GRANT statements implied by the saved $DBPERM directives. That is, the permissions will be retained.


Fixed an error when loading a sequence object with a negative increment. The sequence could be restarted, although the current value was beyond the start value for the object.

Added a utility procedure ap_hso_purge_old_sp to permit a DBA to delete old entries from abahistsysobjects in a controlled way.


If you wanted to execute DDL from with an application stored procedure (typically signed with a certificate to package the permission) that was exceuted by a plain user, there were two permission issues in the DDL triggers that AbaPerls sets up: 1) permission was needed on the AbaPerls tables (because ownership chaining does not apply to DDL triggers) 2) the DDL triggers had statements that required the permission VIEW SERVER STATE. Both this issues have been addressed. The code for the DDL triggers is now in an SP wihch resolves the permissions on the table, and there are alternate solutions in place when the DDL is issued from within a stored procedure.


Sequences are now first-class citizens in AbaPerls. Sequences are stored in .seq files which you put in the TYPE directory. DBBUILD loads .seq files between .typ and .tbltyp files. When you load a .seq file into a database and the sequence already exists, AbaPerls will under some circumstances alter the current sequence to agree with the new definition. See the file-load page for details.


Previously, when you generated a patch script with DBUPDGEN and you specified an explicit version number for a file and that version number did not match a checkin for that file, you got an error. This has changed to that you only get a warning. Note, though, that DBUPDGEN does not really honour the version number, but will write a version number that matches the most recent checkin for the file at that version number.


Fixed an issue where a load of file from a different subsystem would fail, if the file originallly had been loaded from version control and now was loaded from a install kit created with ‑noexec ‑get or vice versa. The issue was due to that the MD5hash was computed differently in the two cases. AbaPerls now computes both hashes when comparing a file to a database, and accepts if one of them matches.


Bugfix: if there was a space in the path to the source file for a .NET file (.cs or .vb), compilation failed, since AbaPerls did not put quotes around the file path. This has been fixed.


Two bugfixes:


When you loaded a file in a subdirectory with ABASQL, and this file had an $INCLUDE or $DEPENDSON of a file in a different subsystem, AbaPerls incorrectly tacked on the subdirectory when looking up the included file, which caused the load to fail. This has been fixed.

AbaPerls did not detect the default schema if the default schema was defined through a Windows group. This has been fixed.

If you connected with permissions less than db_owner/CONTROL you got a error message about not being able to drop DDL triggers. This has been replaced with an explicit error message that you need to be member of db_owner or have CONTROL permission in the database.


INSFILGEN now applies "Freeze panes" when creating the Excel file, so that the header line will always remain visible when you scroll, and likewise, all columns defined as keys on the Config sheet are always visible when scrolling sideways. On the Values sheet the frozen pane also includes the %param column.


A change in INSFILGEN: if the column width is very narrow, INSFILGEN will not honour that, but restore the column to a default width. This avoids problems if someone saves the Excel file with some columns hidden.


There is a change in how AbaPerls determines whether a file in TFS is binary or not. Previously, AbaPerls relied on the encoding in TFS. Now AbaPerls looks at the file extension. If this is an extension known to AbaPerls (e.g. .sp), this determines whether the file is to be handled as binary. For file extensions unknown to AbaPerls, e.g. .ps1, AbaPerls still uses the encoding in TFS. This change mainly affects SSGREP, SSREPLACE and VCDBLOAD what would fail to read files hat mistakenly had been marked as binary in TFS.

A related change is that the table files created by VCDBLOAD now has a column isbinary which tracks if a file is considered binary, so that you can determine why a file has not been read when you expected it to be.


Fixed a bug in the library module used use by update scripts generated by DBUPDGEN. When reloading a table, the re-targeting of foreign keys could fail if they were defined with ON CASCADE. (This was due an akward way of moving the they keys that was needed in SQL 6.0!)


DBUPDGEN now includes an OPTION(RECOMPILE) in a table reload if there is a batch column. This can help to improve performance.


A couple of small fixes/changes:


Bugfix: When moving a table from one subsystem to another, and this table had one or more constraints defined within the file, you got a bogus message that OLDSUBSYSTEM!tbl.tbl needed to be reloaded. This has been fix.


Bugifx in INSFILGEN: Failed to detect that there were extraneous keys in the Macros sheet, but this only resulted in incomprehensible Perl warnings. INSFILGEN will now stop with an error message when there are keys in Macros that are not on the Definition sheet.


Bugfix with object checking: AbaPerls did not recognise CTEs in inline table-functions. It does now – but only if you do not enclose the query of the function in parentheses.


Bugfix: DBUPDGEN ‑checkedout would fail if there was a pending branch.

Bugfix: Loading of a table type would fail if a depending object had two parameters of this type, because two DROP commands where generated. This has been fixed.


The tenth public release of AbaPerls.


Bugfix in INSFILGEN: if consecutive keys in the Definition sheet had Delflag = 1, you could get bogus messages about extraneous rows in the Macros or Values sheets, and also lose rows from these sheets.


There was a problem to connecting to TFS from AbaPerls on a machine with only Visual Studio 2015, particularly if there had not been any earlier versions of VS installed. This was due to that the TFS assemblies in VS2015 are not stored in the GAC. This only caused an error if you tried to use the ‑VC option explicitly, but AbaPerls also failed to map you current directory to a folder in TFS. You may not have noticed, but if nothing else, things broke with references to other subsystems.

This has been addressed by bundling the TFS assemblies with the Perl executable, and AbaPerls now comes with a Perl installation that you are supposed and not your own Perl installation. Note however, that the current arrangement only supports VS2010 to VS2017. That is, later versions of VS are not supported with the current version, as that requires that AbaPerls bundles the assemblies for that new version of VS.


Fixed problem where AbaPerls yelled about a private type name when that pattern appeared inside a string literal when loading a file.


When loading an .ix file, AbaPerls did not write a row to abasysobjects and abahistsysobjects for indexes that were unchanged. This was intended to be a feature. However, this had the consequence that the md5hash column was not updated, which could lead to problems further down the road. So this "feature" has been removed, and abasysobjects is now updated, no matter whether the index definition has changed or not.


Fixed an issue that affected both DBUPDGEN and DBBUILD which prevented them for finding checked out files in TFS 2017. (Because a property that is supposed return a name, returns a GUID with TFS 2017.)


When applying server-level permissions for $SERVERPERM or a privileged assembly, AbaPerls now replicates the server-level commands to all nodes in any availability group the database is a member of.

DBBUILD now only respects ‑use_disk when you build from version control for subsystems where you are building without a label or you explicitly have specified LATEST. Note that if you are building from a config-file and all subsystems but one has a label, DBBUILD will respect ‑use_disk for that last subsystem. If no subsystem is built from latest and you specify ‑use_disk, you will get an error message.


Changed the pattern for how temporary schemas are named, to work around a bug in SQL 2014.


Bugfix in TBLFIX: line breaks in table constraints were lost. This has been fixed.


A new Preppis directive $DEPENDSON which is similar to $INCLUDE and $REQUIRE in that it requires a mirroring $USEDBY, but in difference to the other two, $DEPENDSON does not load the referred file, but only serve to check that $USEDBY is present  You use $DEPENDSON to state that a file A is dependent on another file B, in the sense that if B is changed, the object(s) in A must be dropped. The presence of $USEDBY makes it possible for DBUPDGEN to add A to the update script, if B has changed, but A is unchanged.

$DEPENDSON is mandatory in these cases:

These checks are error with ABASQL and update scripts generated with DBUPDGEN, but only warnings with DBBUILD and older update scripts.

A benefit of this change is that AbaPerls can now can reload a table type, even if the table type has changed and is in use. AbaPerls now drops all dependent objects and issues a warning that the stored procedures and functions in question must be reloaded. This warning is handled by LISTERRS which will not display the warning if the objects are indeed recreated. The same applies to objects that are referred to WITH SCHEMABINDING – AbaPerls will drop all referencing objects if needed. Note that in both cases, AbaPerls only drops objects listed in abasysobjects.

Similarly, this change removes the problems with triggers, indexes and foreign keys that are defined in different subsystems than the one of the table in the case the table is changed and reloaded in an update script. Previously, they could remain un-reloaded if no update script was created for the other subsystem. With the presence of $USEDBY, they are added to the update script for the subsystem of the table.

Change in DBBUILD: previously DBBUILD skipped a subsystem if it had an sql directory, but there were no objects. This has been changed, so that DBBUILD in this case creates an empty subsystem. If there is no sql directory for the subsystem, the subsystem is still skipped.

Bugfix in DBUPDGEN: if a file with an extension unknown to AbaPerls was deleted from source control, DBUPDGEN would put it into OBSOLETE-FILES whereupon abasqlfile would fail on processing it. This has been fixed, so that file is not entered into the update script.


$INCLUDE is now permitted across subsystems. Assume that the file caller_sp.sp in the subsystem BETA needs to include the file compute.sqlinc in the subsystem ALPHA. The following applies:

Beware that the feature is designed from the assumption that you are using a sysdef-file. If you are not using a sysdef-file, it may not always work that smoothly.

For more information, see the topics for Preppis and DBUPDGEN.

As part of the same development it is now possible to load a file from a different subsystem with ABASQL using the notation above, for instance:

abasql -d somedatabase -S someserver somefile.sp SUBSYS!someotherfile.sp


Bugfix for DBUPDGEN: table reloads were not correctly generated if there was a computed column or check constraint that splahed out over several lines and one of the lines ended with a comma.


A modification to the changes from 2016-06-28: setup_for_datamove does not attempt to set the database into bulk-logged recovery if the database is member of an availability group or configured for mirroring, since SQL Server will not permit this.


The way how DBUPDGEN generates code for data-move for table updates has been changed to improve performance:

These changes do not affect existing update scripts.

There where as a bug in aba_check_column which caused incorrectly to consider tables in any schema, not only dbo.

DBBUILD and the update scripts generated by DBUPDGEN now check when you connect that you have CONTROL permission on the database (which is implied if you have membership in the db_owner role).

Added a prefined macro, &SQL2016.


The description on how to suppress the name-clash check when an object has moved from one subsystem to another was incorrect with regards to stored procedures due to the buffering feature. This section has been updated and a check has been added so that update scripts now will abort if you attempt to change an AbaSql attribute in the SP section of an update script.


VCDBLOAD now printes a final message with how many files that were loaded in how long time. There is also a new option ‑progress n which permits you to get a progress message every load of n files.


Some small improvements to DBUPDGEN with regards to how the script is generated for tables:


Bugfix: if you followed the instructions for how to handle a data-type change, your reward was an error message, because AbaPerls had an incorrect check for the existence of the type. This has been fixed.


Bugfix for ABASQL: if you current directory on disk was a subdirectory to one of special directories in the AbaPerls SQL directory structure, for instance C:\Project\SQL\SP\Subdir and ABASQL was able to match that to a directory in version-control, ABASQL would nevertheless load the file from disk, even if you did not have the file checked out. This has been fixed. The fix does not affect DBBUILD and the update scripts generated from DBUPDGEN.


Small improvement how Pre-SQL Analysis handles SELECT INTO in triggers with regards to the tables inserted and deleted.


New option for ABASQL, ‑LoadRequire that permits you to force load of $REQUIREd files.

AbaPerls now prints a level 8 message if a file takes more than 60 seconds to load. The messsage includes the time elapsed and the current time. The intention is to make it easier to find slow operations in update scripts. The message is however generated with all tools, including ABASQL.

DBUPDGEN no longer generates code to set the property Time_calls, as this property has been superceded by the scheme above.


DBUPDGEN now prints the total execution time as well the time spent on retrieving files.


Added an improvement to handle the situation that different versions SQL Server may store the definition of a computed column differently. To take benefit of this improvement, you may need to change your table definition.


Added the option ‑batchmode for INSFILGEN to simplify mass runs.


Improvements to INSFILGEN. Now when you generate INSERT filea from your Excel booka, INSFILGEN also generates .srcdata files. You can later recreate the Excel book from the .srcdata file with INSFILGEN. The idea is that you would put the .srcdata files under version control rather than the Excel books, as the latter are difficult to handle, not the least with regards to merging. The .srcdata files are XML files, and should be easier to merge.

A side effect of this overhaul is that INSFILGEN is now somewhat stricter when reading the Excel book. Previously, INSFILGEN accepted that the same macro appeard twice in the Macros and Values sheets, but the result of this was undefined. INSFILGEN no longer accepts duplicates, but terminates an error. The same applies to LANGINSGEN which accepted that the same language appeared twice, again with undefined results. Here as well, duplicates now results in an error.


There was a restriction, so if you had something like:

OUTPUT deleted.katid INTO @out
FROM   katitransactions kti
WHERE  katid=@katid

Objet Checking would report the alias kti as missing, because it did not consider the OUTPUT-INTO clause. This has been fixed.


If you were running DBBUILD or update script over multiple subsystems and you were using ‑use_disk, AbaPerls did not find files for which there was a pending Add or a Rename operation in TFS. This has been fixed.


SSREPLACE can now implicitly map the current folder to version-control directory in TFS and in this case, the mapping determines the workspace in which checkouts are performed. There is also a bugfix: the default option ‑exclusive no matches the documentation. That is, ‑noexclusive is the default.

Bugfix: attempting to process a dropped table type failed with a Perl run-time error. This has been fixed.


A new feature in Preppis: delimited Macro expansion. You can now the delimit the macro name with '', "", [], {} and <> and for the first four you get the macro value enclosed in the given delimiters. The angle brackets are not retained; you use these when you want to use the macro value as the base for a name, for instance &<message_type>_contract to form the name of a Service Broker contract from a message type.


DBBUILD now includes files with a pending add operation in TFS when you use the option ‑use_disk together with ‑VC or ‑config.

Behavioural change for loading of Service Broker files: In databases labelled production, AbaPerls now considers it to be an error if there are active conversations related to any of the services in the file. In test and developement databases, AbaPerls still kills the conversations without mercy.


Update scripts generated by DBUPDGEN no longer generates an error if a file that appears in the secrion OBSOLETE-FILES includes an object name that is defined in another subsystem. This happens if the object have been moved to a different subsystem. You only get an informational message that the object was ignored.


Updated the manual page for Preppis to correct some inaccuracies with regards to macro expansion. Particularly, the topic suggested that macros would be expanded inside string literals and quoted identifiers which is not the case.


Introduced a new file type, .mty, for Service Broker message types that are used in more than one .sb file. .mty files live in the SERVICEBROKER directory and they follow the regular rule that object and file name must match. When loading a message type that already exists, AbaPerls changes CREATE to ALTER.

Bugfix: if the ‑Password option was preceded by an option without argument, for instance ‑force, the password was not masked in the output.


Improve to the version checks for production and test databases: AbaPerls now stores an MD5 hash for the files, and DBBUILD and the update scripts generated by DBUPDGEN will not perform any version checks if the stored MD5 hash matches the hash computed for the file. This should reduce the noise produced in the log files.


New tool VCDBLOAD to load information under version-control to a full-text indexed database.


Updated the instructions for VisualStudio and TextPad. Specifically, you should use $(ItemFilenName)$(ItemExt) for Visual Studio and $FileName for TextPad so that ABASQL only sees the file name and not the full path, as this works better with TFS.


Bugfix in SSGREP: If you use both ‑type and ‑lang, SSGREP would search no files. This has been fixed.


Enchanced the Preppis directive $MACRO_LONG: if the parameter NOEXPAND is given, short macros inside the long macro are not expanded until the long macro is expanded. Added a predefined macro &SQL2014.


NEWLABEL would incorrectly reporing labelling a TFS project as successful, although the operation failed. This has been fixed. However, due to limitations in the interface between Perl and the CLR, NEWLABEL is unable to report the reason for the failure.


Minor adjustment in ap_compare_tables_sp, which failed to drop a constraint, if the constraint had been loaded to abasysobjects through ap_zz_sob_load_sp.


Change in DBUPDGEN with regards how differences in TFS are determined. DBUPDGEN no longer assumes that files have changed just because the changeset ids are different, but instead DBUPDGEN compares length, encoding and the hash value stored in TFS. The check also applies to intermediate versions, to catch rollbacks. See further the TFS section in Determining Whether a File Has Changed on the DBUPDGEN page.



Bugfixes: 1) Added bypass of the DDL trigger to ap_sob_retarget_synonyms_sp and ap_spp_grant_assemperms_sp, as these procedures drops/alter objects old by AbaPerls and they are intended to be run from a query window. 2) The procedures to handle modules with special permissions could produce incorrect SQL in report mode, because AbaPerls failed to consider that output from PRINT is truncated after 8000 characters in SSMS. This has been addressed. 


Bugfix with DBBUILD ‑restruct: indexes were always rebuilt, even if they were unchanged. This has been fixed, but note that if the index defintion includes a WITH, ON or FILESTREAM_ON clause, it will always be rebuilt. A note about this has been added to the topic for DBBUILD and page about storage settings.


The DDL trigger has been eased for ALTER QUEUE, so that AbaPerls permits this command if you only use it to enable/disable the queue or activation, or set the execution principal, as this does not affect the application logic. Such an exempted command is not logged in abaddltribypasslog. See the Service Broker page for details.


The patch-script functionality in DBUPDGEN has been revamped. When you specify ‑patch, you can no longer specify ‑from, ‑VC or ‑subsystem on the command line. Instead you specify the version for the subsystem inside the patch file, and you can also specify the path in the patch file. The format for update scripts has been bumped to 3.6. See further the section Patch Scripts in the page for DBUPDGEN. Note that this section has been moved within the page.


Bugfix in DBUPGEN. Table-updates were broken: DBUPDGEN failed under most circumstances to find any primary key, why now code for handling foreign keys were added, and unless the clustered index was a non-key index, DBUPDGEN did not generate any batching.


AbaPerls now supports loading of DDL triggers on database level. (Server level triggers are not supported.) You put DDL triggers in files with the extension .ddltri. These files should reside in the MESSAGE directory. The name of the trigger must agree with the file name.

AbaPerls now installs a DDL trigger to disallow modification of objects loaded with AbaPerls from SQL Server Management Studio and similar tools. It is possible to bypass the DDL trigger to deploy critical fixes in production databases, in which case the action is logged in the table abaddltribypasslog. See the documentation for this table for further details.

The deprecated configuration options ‑[no]Adefauls, ‑[no]Anulls, ‑[no]Apadding, ‑[no]Aquoted and ‑[no]subscriber have now been dropped entirely from AbaPerls.

ABASQL, DBBUILD and update scripts generated by DBUPDGEN incorrectly recognised the options ‑onlylabel and ‑notlabel. This has been fixed.


Bugfix: when running ‑noexec ‑get inside an SQL structure, the global grant.template was not extracted to the intended place in the subsystem directory.


The ninth public release of AbaPerls.


Bugfix for SSREPLACE with TFS: The rule that we should primarily pick a workspace that matched the computer name was incorrectly implemented. This has been fixed.


AbaPerls now supports TFS 2012, both server and client.


Bugfix: when loading files, the comments before CREATE PROCEDURE or corresponding were stripped before the batch was sent to SQL Server.


In SYSTEM.DEFINITION you can now use options to define which subsystems references that are permitted and which are not. Default is that references must respect the build order, but you can override that to be more restrictive – or less. See further the section Sysdef-file Options.

Improvements and changes in Object Checking:

The option ‑sptwice for DBBUILD is now obsolete. Previously you would use ‑sptwice to ensure that you got complete dependency information. DBBUILD now employs a buffering scheme, and buffers all SPs in a subsystem. If an SP depends on a procedure to be loaded later, the SP is loaded, but requeued. In this way, a procedure is only loaded twice if there is no need to. See further the section Loading Stored Procedures on the DBBUILD page.

For a table with an IDENTITY column, DBUPDGEN now generates code to transfer the current IDENTITY value from the old table to the new table.

The manual page Known Issues has been dropped as it was not very well-maintained. Most of the restrictions are now listed on the Introduction page.


AbaPerls did not inspect grant.template for permissions on assemblies, scalar types, rules and defaults. This has been corrected.

When looking for SET ROWCOUNT, EXECUTE AS and the AS that concludes the of CREATE PROCEDURE, AbaPerls failed to consider lowercase or mixed case, and only looked at uppercase. This has been corrected.


Added support for storage properties and indexes, e.g. compression and filegroup placement that you specify with the WITH and ON clauses and in case of tables in some cases also with EXEC sp_tableoption and ALTER TABLE. You can mention these explicitly in the source file. If not, AbaPerls will preserve the database setting which may have been configured locally. See the page Storage Settings for Tables and Indexes for details. To make use of these changes, the database must have at least version L1.0.0280 of the ABAPERLS subsystem.

AbaPerls now supports columnstore indexes. AbaPerls now also understands XML and spatial indexes, but the support is very rudimentary and it is only practically useful for small development databases as XML and spatial indexes are dropped and recreated every time a .ix file is loaded. Previous, although it was not documented, AbaPerls would not start a transaction when it loaded an index file. This has been changed, so that there is a transaction for index files as well.

Previously, when you loaded an .ix file, AbaPerls would drop indexes not in the .ix file but belonging to the same subsystem. Now AbaPerls also drops indexes not in abasysobjects at all (which is what the documentation has said all the time). Indexes in other subsystems are not touched.

A few changes to update scripts generated by DBUPDGEN:

Bugfix: When a .tbl file was reloaded, it could happen that for some of the constraints the most recent row in abahistsysobjects would say that the object was deleted, and this could later cause an error message with DBBUILD ‑restruct, particular for objects in the ABAPERLS subsystem. This problem arose due to a collision on loadtime, and it has been solved by adding a small delay when required.


Bugfix for DBUPDGEN: when DBUPDGEN compared the paths for two versions of the same TFS item, it considered the path as different if there was a difference in lower/uppercase only, why DBDUPGEN compared contents instead of changeset ids. If two versions of a file was identical, DBUPDGEN could fail to include the file, even if you wanted to.


Bugfix in SSREPLACE: if you specified neither ‑lang nor ‑type, it would not search anything.


Bugfix in SSREPLACE: ‑lang and ‑type had incorrectly become mutually exclusive, so that no files would be processed. This has been fixed.


LISTERRS now applies the default for the min-severity argument for each log in the log file, so that if your log file has a mix of logs from DBBUILD and update scripts from DBUPDGEN, the default is 10 for the logs from DBBUILD and 9 for the logs from the update scripts.


Bugfix (sort of): when requesting data from TFS for the current user, AbaPerls now asks TFS what it thinks is the current user, rather than relying on Windows, as they could disagree, for instance in a workgroup. This affects several tools.


New versions of TBLFIX and PDREP to support PowerDesigner16. This also includes a new report template to use with PDREP. PDREP was previously knowns as PDREP95, but it has been renamed as now also supports PowerDesigner 16. The older PDREPDIV has been removed.


Bugfix: when print the command-line to the log file, AbaPerls could fail to include options with no arguments.

ABASQL now prints a dotted line when it has completed accessing all files, to prevent error message from drowning in that noise. This line is not printed when you use the ‑log option.


Bugfix in DBUPDGEN: If an assembly-related file such as a .dll file in SourceSafe had changed, but the .assem file was unchanged, the .assem file would always be included in all lowercase in the update script, even if the file name included uppercase. This has been fixed. This bug did not appear with files in TFS.


Improvement: DBUPDGEN now makes use of the new capabilities when loading a table and generate update scripts that first attempts to load the table with abasqlfile, and only if this fails it enters the long table-update code, which now is known as fallback code. The update scripts now includes a section INCLUDE which lists all changed include files. They are commented out, but serve as reference.

Behavioural change: AbaPerls now adds an initial ^ and a closing $ to the regular expression in grant.template, so that the regexp must match the object from start to end. Previously the pattern zz_.* matched fuzz_sp, but it no longer does. (And this is in agreement with that the examples for grant.template have said all through the years.) If you want this match, you need to the change regexp to .*zz_.*.



Bugfixes: 1) Reloading a user-defined aggregate did not work, because AbaPerls tried to use the non-existing command ALTER AGGREGATE. 2) Trigger files did not work if the name was quoted, for instance [My Table].


Changes to the AbaPerls file-loading process. Now when you load a .xmlsc, .typ or .tbltyp file and the type/schema is in use, AbaPerls will load the definition in a temp schema and compare the new definition with the definition in the database, and raise an error if they are different. The same applies to .tbl files for tables that have data, with the difference that AbaPerls will investigate whether it is possible to bring the existing definition up-to-date with ALTER TABLE, and in such case attempt such commands. See further the section Pre-SQL Analysis: Reloading a Table on the file-load page.

There are two new options to DBBUILD, ‑restruct and ‑revokeall and a change in behaviour for ‑rebuild. ‑restruct permits you to rebuild the database and change your subsystem structure. With ‑revokeall (which only can be used with ‑rebuild and ‑restruct), DBBUILD revokes all permissions to objects in abasysobjects. DBBUILD ‑rebuild now reloads all files and does not skip files for types and tables. This is possible, thanks to the changes in the previous paragraph. For more information on the new options, see the section Using the ‑rebuild and -restruct options in the topic for DBBUILD.

All these changes require that the ABAPERLS subsystem is at least of version L1.0.0270. For lower versions, the old behaviour is retained.



Bugfix: the code to move referring foreign keys failed to consider that the referring table may be in a different schema. Specifically this broke the update script which itself also has been changed to work with the side schema introduced 2012-02-20.


Bugfix: when loading an index file, AbaPerls could under some circumstances mistakenly recreate an index, even if the index definition in the file agreed in the database. This has been fixed.

More improvements to SSGREP. SSGREP can now store the output in a database with the ‑database option. When storing the output in a database, you can resume an interrupted search with the ‑resume option.


Added the option ‑input to SSGREP to permit SSGREP to read search strings from an input file.


Changes in supplemental SQL checks.

When AbaPerls adds a COLLATE clause to a temp table, AbaPerls now uses COLLATE database_default, rather than hardcoding a collation.

Bugfix in Preppis: macros with one-letter names, for instance &a were not permitted. This has been fixed.



The eighth public release of AbaPerls.



Bugfix in LISTERRS: When a procedure was missing because it had failed to load previously, the message incorrecty said that it was missing.


Completely rewritten LISTERRS, for a number of enhancements:

To support these changes, there are a few more changes in AbaPerls:

Finally, two unrelated changes:


If two developers used different paths to the same repository, this could cause the version checks for production and test databases to raise false alarams. AbaPerls addresses this by introducing repository IDs which are stored in the new table abarepositorymappings. AbaPerls accepts different repository paths, as long as the repository IDs are the same. The repository IDs are derived from within the version-control databases; both SourceSafe and TFS have a GUID that identifies the database. When the an SQL database upgraded to this version of AbaPerls (L1.0.0250), the repository ID is initially set to NULL, and it will be filled up by time as you run upgrade scripts or ABASQL on the database. If the ID missing, AbaPerls only checks the path within the repository.

As a consequence of the previous change, the tables abasysobjects, abahistsysobjects and abainstallhistory have been changed, so that the path to the repository and the path within the repository are stored in separate columns.

The format of the files SS‑FILES.LIS and SUBSYSTEMS.LIS has changed to accomodate the repository IDs. The new versions of the format is 1.1 and 1.3. They are designed so that older versions of AbaPerls are able to read this flies and act correctly. ...or at least the most recent versions of AbaPerls. For the future, AbaPerls how checks the version number of the format, and terminates with an error if the format is not supported.

AbaPerls has changed its philosophy with regards to changeset-ids in TFS. Previously, if you asked for changeset 7634 of a file, and that file was not part of that changeset, AbaPerls would report the file as missing.. Nevertheless, TFS returns the version of the file that was current when that changeset was checked in. AbaPerls now goes with the version returned by TFS, as the original rule made it impossible to use changeset numbers with ABASQL.


INSFILGEN now generates an error message when there is a duplicate entry in any of the sheets, and no file is generated.


INSFILGEN how handles the extensions .xlsx and .xml on equal footing with .xls. This also applies to the sorting in DBUPDGEN.

There was a bug in INSFILGEN, so you would get an error about missing MAXLEN for a parameter with an uppercase character in the name.


Four fixes/changes with DBUPDGEN:


DBUPDGEN now understands to strip out ASC and DESC from the definition of PRIMARY KEY and UNIQUE constraints. (DBUPDGEN already handled ASC and DESC in the definition of clustered indexes in .ix files.)


The path to the help file in the welcome message was incorrect. This has been fixed.


Added support for Service Broker to AbaPerls. You defined a collection of Server Broker objects in .sb files (new extension in AbaPerls) int the SERVICEBROKER directory in the AbaPerls SQL directory structure. See further the page Service Broker in AbaPerls. There are also two new Preppis directives, $PRELUDE and $ENDPRELUDE. While generic in nature, they are currently only permitted in Service Broker files.


If the input file is a 8-bit file, SSREPLACE now retains the encoding. If the file is a Unicode file, SSREPLACE retains the encoding only if you have Perl 5.14 or later. With Perl 5.12, SSREPLACE always write Unicode files as UTF-8, since a bug in Perl prevents writing UTF-16 files.

Bugfix in DBUPDGEN: if the path to a SourceSafe database is a UNC name, DBUPDGEN failed to observe that the leading \\ in the path must appear as \\\\ in the Perl script, because the way Perl interprets \\.

INSFILGEN produced a sporious message Missing Index for an Excel book which does not have all four possible sheets. This has been fixed, and the message no longer appears.


Bugfix: Object checking of Service Broker objects incorrectly flagged objects if there were more than one of the same kind referenced in the same file.


CREATE XML SCHEMA COLLECTION is now permitted in .sql files to permit schema collections to be used with Service Broker (which typically are defined in .sql file.)


AbaPerls now supports two version control systems: SourceSafe and Team Foundation Server (TFS). This has required a major overhaul of ABASQL, DBBUILD, DBUPDGEN, NEWSUBSYSVER, SSGREP and SSREPLACE and all code that supports these commands. You use TFS with AbaPerls very much in the same you work with SourceSafe – at least for now. Since TFS has a quite a different mindset, it is conceivable that AbaPerls will add further support for the TFS mindset later on. The support for TFS requires TFS 2010 SP1.

The page Version-control Concepts includes important information about general concepts how AbaPerls approaches version-control systems and particularly how you specify the repository for a SourceSafe database or a TFS project collection.

As a result of these changes, AbaPerls now requires Perl 5.12. It also requires the present of one more extra module, Win32::CLR. Furthermore, AbaPerls now requires the Perl installation to be on a local disk; it cannot be on a network disk. (Because of the reference to the CLR.) This applies even if you only work with SourceSafe.

There are two new commands NEWLABEL, a command that sets a label on the AbaPerls format LetterMajor.Middle.Minor and which can compute the label for you. TFSLABELFIX, which is a TFS-specific command that re-scopes TFS labels to fit with AbaPerls.

The general overhaul of the code has also lead to a number of other improvements and behavioural changes:

The following applies with regards to compatibility. Keep in mind that there are changes both to the AbaPerls client and the ABAPERLS subsystem, the database part:


LISTERRS could fail to list errors in an assembly created from a source file in VB .Net, because of the special way VB .Net displays the erroneous code.


Added support to grant permissions on types and XML schemas.


aba_tblfkey(), used in update scripts generated by DBUPDGEN, did not transfer the FK options SET NULL or SET DEFAULT. This has been fixed. (But note that if you are running with any of the ANSI options off, the issue remains.)


The seventh public release of AbaPerls,  label L1.0.0190.


AbaPerls now supports table types and XML schema collections. They can be defined in the file types .TBLTYP and .XMLSC  respectively. These files reside in the TYPE directory. In DBBUILD and DBUPDGEN, XML schema collections are loaded before regular types (.TYP files), whereas table types are loaded after. You can also define a table type or an XML schema collection in a .SP or .SQLFUN file, if the type/schema is to be used by this procedure only. In this case the name must follow certain rules. See further in the section about the SP directory on the page The AbaPerls Subsystem Structure.

AbaPerls now supports CREATE TYPE to define type. EXEC sp_addtype is still supported.

You can now create an assembly directly through a source file written in C# or Visual Basic .Net. To do this, you need to supply the $COMPILE directive in the .ASSEM file. You find more information on the CLR page. As a consequence of this change, version-checks now also include .ASSEM files.

If you run DBBUILD ‑rebuild for a single subsystem, AbaPerls now clears the settings configuration settings only for that subsystem, and leaves global settings and settings for other subsystems unchanged. Note also that the subsystem is rebuilt using the global configuration settings.

When you had expressions with .nodes(), AbaPerls could produce a internal error about too many iterations. This problem has been fixed.

I'm doing a minor overhaul of the design of the manual pages, and in a transitional period, the design between different pages will vary.


ABASQL now masks any password when printing the command-line options.


Added two new macros $DBPERM and $SERVERPERM that permits you to encapsulate permissions that can not be handled with regular ownership chaining. Examples include use of dynamic SQL and BULK INSERT. See the new topic Modules with Special Permissions for more details.

Added an argument to the $DLLINCLUDE macro where you can specify the permission set for the assembly. Using this directive, you can install unsafe assemblies on databases that are not marked as trustworthy. See the topic Privileged Assemblies on the CLR page for details.


Fixed bug in RUNSPS which caused RUNSPS to loop indefinitely if you did not supply any parameter definition at all, for instance because the procedure does not have any.


Added the option ‑tablesfirst to DBBUILD. This option specifies an alternate build order where tables and views in all subsystem are built before any functions or procedures are loaded.

Augmented the AbaPerls file-lookup order, so that AbaPerls now looks for the file in a subsystem directory before trying an AbaPerls SQL directory structure on the same level.


AbaPerls now supports use of WHERE clauses in the definition of index and statistics, so-called filtered indexes.


RUNSPS is now able to read regular Excel books, and is not constraint to CSV files. Older CSV files still work with RUNSPS, as long as Excel can read them.


DBBUILD and DOBCP now use the ‑q option with BCP to set the setting QUOTED_IDENTIFIER (which for some reason is not on by default with BCP.)


DBUPDGEN no longer complains if the ‑VSS option disagrees with the project in the file, if the only difference is that one of them has /SQL and the other not.


The sixth public release of AbaPerls, label L1.0.0091.

The tool PREPRC has been dropped.


Fixed bug in aba_check_column, so that it now correctly returns 0 when ‑noexec is in effect.


DBUPDGEN now generate update scripts that sets an error status on DOS level (i.e. %ERRORLEVEL%) if there are objects with names starting in old_ before the update starts, or when the update has completed.


The rules for ABASQL in the version-check in the AbaPerls file-loading process have been modified. Previously AbaPerls required that when a file was loaded from SourceSafe that the path was the same as when the file was most recently loaded. This has been changed so that the check is now performed against the SourceSafe path the subsystem was most recently loaded from. The check is only effective if the ABAPERLS subsystem in the database is upgraded to label L1.0.0081. For older versions of the ABAPERLS subsystem, the old version check is retained.


Important note: to get the updated version of ap_scriptname, you need to run an update script, However, this script does not run on SQL 2005 RTM and SP1. The script runs on SQL 2000 and earlier, SQL 2005 SP2 and SQL 2008. The reason is that sp_rename SQL 2005 RTM/SP1 checks for referencing stored procedures when you rename a type, and ap_scriptname is used by the procedure that loads objects into abasysobjects, resulting in a catch-22 situation.


ABASQL now requires that you specify ‑subsystem also for .TBL files. (As failing to do so when you create the table the first time, could buy problems further down the road.)


INSFILGEN used to insert an extra go after each 40th call. This has been removed. (It was a workaround for problems with the tools in SQL 6.5)


Added support for synonyms. See the page Using Synonyms for details.


Bug fix: it was not possible to connect with AbaPerls to databases with space or other special characters in the name.


Because of changes in SQL 2005 SP2, LISTERRS failed to list calls to missing stored procedure. This has been fixed. Also, AbaPerls also correctly handles the same situations with SQL 2008.


The fifth external release, L1.0.0060.

When using SourceSafe 2005, DBUPDGEN could crash while reading the object histories. This has been addressed.

AbaPerls is now able to understand Common Table Expressions (CTEs). Support for the MERGE statement in SQL 2008 added.


There was a problem with SourceSafe that made it impossible to dates with ‑label in various tools with SourceSafe 2005. AbaPerls now has a workaround for this problem.

It is now possible to use the @ character as separator for site-specific files as an alternate to % which has been outlawed by SourceSafe since 6.0d.


ABASQL now has the options ‑noexec and ‑get, and ABASQL is now able to read SourceSafe information from SS‑FILES.LIS, permitting using ABASQL to install files at customer sites to which you have no direct connection.


AbaPerls no longer performs object checking for the pattern ident1.ident2.ident3(. Previously, AbaPerls attempted to verify this as a scalar user-defined function with the database part of the name included. However, in SQL 2005, there is no syntactical difference between the call to a UDF and the invocation of a type method of an XML or CLR UDT column. AbaPerls opts to validate two-part names, but not three-part names, that look like function calls. As a consequence of this, you need to always use a table or alias prefix with your XML and CLR UDT column when you  need to invoke a method, for instance t.item.value().

A similar issue with the table-valued XML method .nodes has also been addressed. AbaPerls ignores three-part names that ends in nodes and are followed by a right parenthesis.

There was a bug with object checking, so that AbaPerls did not see a scalar function when it appear directly after a keyword. This bug has been fixed.


Thanks to Koen de Vos, the update scripts generated by DBUPDGEN will now correctly transfer ON DELETE/UPDATE CASCDE and also NOT FOR REPLICATION when moving foreign keys from one table to another.


DBBUILD and the update scripts generated by DBUPDGEN now accepts an option ‑User to permit you to specify a different SQL login than sa. AbaPerls verifies that the login you use – SQL login or Windows login – has dbo as the default schema. This applies to ABASQL as well.

DBBUILD and the update scripts generated by DBUPDGEN no longer sets the database in simple recovery, nor do they set a read-only database in read-write mode, but you need to cater for this yourself. As a consequence of this, the update scripts are no longer generated with the ‑trunctrue option.


DBBUILD now uses the option ‑h "CHECK_CONSTRAINTS" with BCP to make sure that constraints trusted. Also added the utility procedure ap_zz_enable_constraints_sp to enable all constraints in a database. Added a note the page for DOBCP about constraint checking.




The tool SPTRITEST has been removed. It was a useful tool on SQL 6.5, but less so on later versions.


Changes to DOBCP:



AbaPerls now reads the real SRCSAFE.INI for the SourceSafe database, and if there is a definition of a journal file, it is copied to the SRCSAFE.INI that AbaPerls creates so that actions from tools like SSREPLACE and NEWSUBSYSVER are journaled appropriately.


New feature in update scripts from DBUPDGEN: you can now have a final epilogue.



Bug fix: ABASQL would incorrectly report file successfully loaded, when it in fact it could not even find the file in SourceSafe.


LISTERRS now knows how to filter out messages about missing stored procedures that appear later in the script. As a consequence of this DBBUILD no longer by default loads stored procedures twice. There is a new option, ‑sptwice, to request this in case you want full dependency information. Note that this is only possible to achieve on SQL 2005, due to flaws in SQL 2000 and earlier versions.


The Preppis directives $MACRO_LONG and $ENDMACRO are now implemented.


New option for SSGREP, ‑crossref, that causes SSGREP to print matches per unique string. This is good if you are looking for references to a couple of stored procedures or similar.


The AbaPerls File-Loading Process now also replaces user-defined data types in schema declarations for OPENXML.


LISTERRS no longer prints headers for subsystems in which there are no errors.


The AbaPerls File-Loading Process now also checks for improper comparisons with NULL, e.g. WHERE x = NULL.


When generating an update script, DBUPDGEN did not add code SET IDENTITY_INSERT ON, if the IDENTITY keyword followed NOT NULL in the table definition. This has been fixed.


Several checks added/enhanced for the AbaPerls File-Loading Process:


Added ‑log option to ABASQL.


New tool PDREP95 for handling of reports generated by PowerDesigner 9.5.


The fourth public release, L1.0.0040.


See more about this on the pages for the, AbaPerls structure, the file-loading process, DBUPDGEN and ABASQL.


Slight change in the table-updates generated by DBUPDGEN: there is now a variable $batchcol which makes a little easier to change the control column for the INSERT-loop.


Two options for SSGREP and SSREPLACE: ‑type and ‑lang that you can use to constrain the tools to only work with files of certain types. For instance ‑lang SQL will constraint the search to SQL files.


The AbaPerls file-loading process could incorrectly gave a style message for a computed column.

In the update scripts generated by DBUPDGEN, the table-updates now use RAISERROR WITH NOWAIT to print their messages, so that they are flushed to the log immediately. The first message for a table-update, which displays the number of rows to copy uses severity level 8, so that you can use LISTERRS to review the copying.


LISTERRS now supports reading logs from update scripts generated by DBUPDGEN. To this end, there are some minor changes to the logs from DBBUILD and the update scripts.

INSFILGEN and LANGINSGEN now want to you declare maximum lengths for parameters with string data, to avoid truncation when you run the INSERT-files. You declare these lengths in a MAXLEN section on the Config sheet. To begin with MAXLEN is not mandatory, but the plan is that it will eventually be. See further the INSFILGEN page.


TBLFIX now formats computed columns nicely.


The third public release, L1.0.0030.


New features


Bug fixes:


When running AbaPerls with Perl 5.8.3 (or ActivePerl Build 809), you could get a run-time error in Perl just as ABASQL and similar tools were about to exit. I believe the cause is a bug in Perl, but a workaround is now in place.


Bug fix in ap_sob_update_sp. When running an update script with name longer than 35 characters, the script failed with "binary or string data would be terminated". This has been fixed, so that the name is truncated to 35 characters when saved in abasubsystems. Since the change is in the stored procedure, you need to deploy this procedure to take benefit of the fix.


Changes in DBBUILD:


Changes in DBUPDGEN and for update scripts generated by DBUPDGEN:


LANGINSGEN now supports multi-column keys.


When using a config-file, and searching for the labels of the projects in the file where there is no explicit version specification, the default behaviour of AbaPerls is now to consider only labels that match the standard AbaPerls label format LetterMajor.Middle.Minor. To permit you to override this behaviour, there are two new configuration options, ‑onlylabel and ‑notlabel.


Bug fix: When DBUPDGEN was reading a table definition to generate a table-update, it failed to recognize CREATE TABLE if these words were in lowercase.


Big news for the AbaPerls file-loading process:


Object checking now also finds objects in other databases, albeit still with some restrictions. See Known Issues for details. You need to install the user defined function list_to_tbl and stored procedure ap_check_existence_sp in the database for the improved checking to work. Else object checking will revert to the old behaviour.


INSFILGEN: Added property Postlude to the Config sheet.


New tool NEWSUBSYSVER that packages the procedure to create new version directories.


During file-load, AbaPerls now creates a temp table #current$subsystem(subsystem varchar(80) NULL) which holds the name of the current subsystem.

When DBUPDGEN generates code for a table-update, it now adds check that the number of rows in the new table is the same as in the old table. See further the section on table updates in the article on DBUPDGEN.

Fixed header generated by INSFILGEN, so that it does not include entry from check-in of INSFILGEN itself.


The second public release of AbaPerls, L1.0.0021. The changes down to 2003-11-03 are the changes since first public release. Pay particular attention to the changes 2003-01-22 and 2002-12-05, since they include significant functional changes.


The ‑crypt option did not work properly when you used the keywords AFTER or INSTEAD OF in a trigger declaration.


If a table file had been renamed, DBUPDGEN did not include that file in OBSOLETE-FILES. This had the effect that the objects in the file were not deleted from abasubsystems. Note that if a file is renamed, but the objects are not, this could lead to that the objects are dropped from the database entirely, if the file is loaded in a table-update that appears before OBSOLETE-FILES.


Documentation fix: if there is a site-specific version of a file, and the main file changes, DBUPDGEN includes all the site-specific versions in the file. This is not a new feature, but the page for DBUPDGEN failed to mention this.


Two changes for ABASQL, DBBUILD and the update scripts generated by DBUPDGEN:


The update scripts generated by DBUPDGEN now creates a temp table #update$script that you can test for in triggers, to disable parts of the triggers when running an update script. Use it like this:

   IF object_id('tempdb..#update$script') IS NULL


Database changes

There are several changes to the AbaPerls system tables. The main purpose of the changes is to permit two subsystems to have labels with the same Major, Middle and Minor, but have different letter and/or leading zeroes.

The new column abasubsystems.sortorder permits you define a sort order to that you can view abasubsystems and get the same order as in the config-file.

Other database changes are mainly of internal nature. See the database documentation for details.

To update the ABAPERLS subsystem to the new format, run the script which is in the SQL/SCRIPTS directory of the AbaPerls installation. You run this script as you run any other update script generated by DBUPDGEN.

The database update is not mandatory; that is, the tools will run against both the old format of the database (L1.0.0010) and the new format (L1.0.0020.)

Bug fixes


TBLFIX now gives UNIQUE constraints unique names.




Bug fix in INSFILGEN: when more than one single quote appeared in a value, the generated SQL would be syntactically incorrect.


Some minor changes were made to TBLFIX so that it would handle scripts from PowerDesigner 9.5 without flaws.


New or changed features

Database changes

Compatibility issues

Documentation issues

Bug fixes


DBBUILD and the update scripts generated by DBUPDGEN now write a header to the log file with information about who and when and which command-line options that were in use. (Old update scripts will not print command-line options, though. Regenerate them to get this information.)

The header is included in the output from LISTERRS


First public release of AbaPerls.