Infor LN 4GL Database Insert and Update Transaction Generator
This generator writes a Baan IV / Infor LN 3GL function that changes one record safely: it sets a retry point, selects the row for update, applies your assignments, calls db.update, db.delete or db.insert with db.retry, and commits or aborts the transaction. Fill in the table, key and fields and paste the result into a program script or library in your VRC.
Fill in
Logical table code without the leading t and company number.
Declaration
|****************************************************************************** |* Safe write to tdsls400 (operation: update) |* Compile in your own VRC with the table declared below. |****************************************************************************** declaration: table ttdsls400 | table pointer used by db.* calls extern domain tcorno i.orno | key value supplied by the caller
Update or delete an existing record
functions:
function long update.tdsls400.record()
{
long ret
db.retry.point()
select tdsls400.*
from tdsls400 for update
where tdsls400.orno = :i.orno
selectdo
| assignments are ignored for a delete
tdsls400.refa = "CHECKED"
tdsls400.refb = "BATCH01"
ret = db.update(ttdsls400, db.retry)
if ret <> 0 then
abort.transaction()
return(ret)
endif
selectempty
return(111) | 111 ENOREC: no record found
endselect
ret = commit.transaction()
return(ret)
}Insert a new record
function long insert.tdsls400.record()
{
long ret
db.retry.point()
tdsls400.orno = i.orno
tdsls400.ofbp = i.ofbp
tdsls400.sotp = i.sotp
tdsls400.odat = date.num()
ret = db.insert(ttdsls400, db.retry)
if ret <> 0 then
abort.transaction()
return(ret) | 100 EDUPL: key already exists
endif
ret = commit.transaction()
return(ret)
}Check against the Programmer's Guide for your Enterprise Server version: the db.* argument list, whether your release expects extra error-handling flags, and the domain of the key. db.update, db.insert and db.delete write directly to the table; DAL business logic of the table runs only through the DAL calls (dal.new, dal.update, dal.destroy), so use those when the table has a DAL. Fill every mandatory field before db.insert, and test in a non-production company.
Want a second pair of eyes on a database write?
Send us the function and the table and we will review locking, retry and DAL use for your LN version.
Optional. The tool and every export work without this. No spam.
How the pattern works
db.retry.point() marks where the bshell restarts the transaction when a retryable database error occurs, such as a row that was changed or locked by another user after a delayed lock. The select with for update locks the record inside the transaction. Inside selectdo you assign the new values and call db.update(t<table>, db.retry), where t<table> is the table pointer created by the table declaration. A non-zero return means the write failed, so the function calls abort.transaction() and returns the error number. If nothing matched, selectempty returns 111 (ENOREC). When all writes succeed, commit.transaction() makes them permanent.
- One retry point at the start of each transaction
- Lock with for update before you change a row
- Always end in commit.transaction() or abort.transaction()
Worked example
With the defaults, the update function locks the sales order header tdsls400 where orno equals i.orno, sets Reference A and Reference B and calls db.update(ttdsls400, db.retry). The insert function sets tdsls400.orno, the sold-to business partner, order type and order date and calls db.insert. In practice you should not insert sales orders directly: LN fills many fields and related records through the standard sessions and the DAL. Use direct inserts for your own customer tables, and use the DAL or a standard API for application tables. Rename the generated functions to match your naming convention.
Error numbers you will meet
The return values are Enterprise Server error numbers. 100 EDUPL means a duplicate key on insert. 107 ELOCKED and 113 EFLOCKED mean a record or table lock. 111 ENOREC means no record matched. 201 EROWCHANGED means the record changed after a delayed lock, which db.retry handles by going back to the retry point. 205 ENOTINRANGE means a value does not fit the field's domain. Log the number with the key so support can trace it in the bshell log. Return the number to the caller rather than showing a message inside the function, so batch jobs and sessions can each decide how to report it. The full list is in the error codes reference linked below.
DAL and upgrade notes
Direct db.* writes skip the DAL logic of the table, including checks and defaults that the standard sessions rely on. For standard LN tables with a DAL, write through the DAL functions instead, or call a standard session or API. Keep this code in your customer VRC and document it in a change header, so an upgrade does not overwrite it and reviewers can find every direct write. Before an upgrade, search your VRC for db.insert, db.update and db.delete on standard tables and check each one against the new data model, because added mandatory fields or new DAL rules can make an old direct write leave inconsistent data.
Frequently Asked Questions
What is the Baan 4GL language?
Baan 4GL is the event-driven script layer of Baan and Infor LN sessions, with sections such as before.program and field events. It sits on the Baan 3GL language, which provides variables, functions, embedded SQL (select, selectdo, endselect) and the db.* database calls used in this generator.
What does db.retry do in db.update?
Passing db.retry tells the bshell that when a retryable error occurs, it should roll back and restart from the last db.retry.point() rather than return the error. That is why the retry point must come before the select for update, so the record is read again with fresh values.
Do I need commit.transaction after db.update?
Yes. The select for update and the db.* calls run inside a transaction that is only made permanent by commit.transaction(). If any step fails, call abort.transaction() to roll back all writes made since the transaction started. Leaving a transaction open keeps locks on the rows.
Where is the Infor LN development guide for these functions?
The Infor Enterprise Server Programmer's Guide and the Enterprise Server online manual on docs.infor.com describe the 3GL language, embedded SQL and the db.* and transaction functions. Error numbers are listed in the Enterprise Server Technical Manual. Check the guide for your exact Enterprise Server version before relying on an argument list.
If you are reviewing legacy Baan or LN code for direct database writes before an upgrade, we can help your team scan and document them with a private AI assistant on your own servers.
Related Tools
Infor LN 4GL Session Script Template
Generate a clean Baan / Infor LN 4GL session script skeleton with declaration, field, choice and table I/O sections.
Infor LN & BaanInfor LN DAL Hook Review Checklist
Review checklist for LN data access layer (DAL) scripts: hook choice, validation, error handling, performance and upgrade safety.
Infor LN & BaanInfor LN Enterprise Server Error Codes and Log Files Reference
Look up bshell and database driver error numbers, what they mean, what to check first and which log file to read.
Infor LN & BaanInfor LN Sales Order Tables Reference (tdsls400, tdsls401 and related)
Searchable field-level map of the LN 10.x order-to-cash tables: quotations, contracts, sales orders, actual deliveries, history, invoices and business partner roles.
More Developer Tools tools
See all- Infor LN 4GL Embedded SQL Select Generator
- Infor LN AFS (stpapi) Session Automation Script Generator
- SAP Sales Order ABAP SELECT Generator (VBAK, VBAP, VBFA)
- SAP Sales Order Create BAPI ABAP Generator (BAPI_SALESORDER_CREATEFROMDAT2)
- SAP ABAP Open Items SELECT Generator
- SAP ACDOCA SQL Query Generator
- SAP QM Inspection Lot ABAP SELECT Generator
- SAP Quality Notification Pareto SQL Query Generator
- SAP QM Usage Decision BAPI Skeleton
Keep exploring
Free tools
- Infor LN 4GL Embedded SQL Select GeneratorFill in a table, columns and a where clause and get a Baan / Infor LN embedded SQL select loop with host variables, index ordering and selectempty and selecterror handling.
- Infor LN 4GL Session Script TemplateGenerate a clean Baan / Infor LN 4GL session script skeleton with declaration, field, choice and table I/O sections.
- Infor LN and Baan ERP Table List by PackageFilterable list of commonly used Infor LN and Baan tables by package, with the naming convention, key fields and where a Baan IV table differs from LN.
ERP fixes and how-tos
- Baan IV to Infor LN migration checklistPlan a Baan IV to Infor LN move as a re-implementation, not a patch: inventory customizations, convert data, rebuild logic, and run a real parallel test.
- Private AI Layer for Baan On-Prem: Reference ArchitectureReference architecture to add a private AI assistant to Baan on-prem: data access paths, retrieval, permissions, sizing and rollout, no cloud needed.
- Infor LN DAL Out of Sync After a Custom Field: Cause and FixInfor LN throws a DAL out of sync error after a custom field is added. Here is why table admin and DAL regeneration must run together, and the fix.
Guides
- Infor LN BShell Programming: Developer Fundamentals GuideMaster Infor LN BShell scripting with this developer guide covering 4GL syntax, database operations, session hooks, and debugging techniques for BAAN/LN ERP.
- BAAN 5 to Infor LN Complete Migration GuideMigrate from BAAN 5 to Infor LN comprehensively. 4GL analysis, data transformation, business process mapping, and organizational change management.
- Baan 4GL Modernization: Strategies for Legacy CodeBaan 4GL modernization strategies: inventory legacy sessions, retire dead code, convert customizations to LN extensions, and de-risk your Baan installed base.
Integrations
- How to add AI agents to Baan IV and Baan VHow to add AI agents to Baan IV or Baan V: tool layer over read-only database access and AFS, human approval on writes, and an on-prem model. A practical guide.
- How to use ChatGPT with Baan IV and Baan VUsing ChatGPT with Baan IV or Baan V: exports versus live access, custom GPT actions, enterprise data controls, and when a private on-prem model is the safer choice.