Skip to main content

Parameter binding

A query with :name parameters runs against different rows at each call. Three things decide what each parameter receives:

PieceWhere it is setRole
ParamsOn the query.Declares a parameter, with a label and a default value.
param_bindsOn the caller — action, lookup column, nested tab.Binds a value to a parameter: a fixed value, or another field read at call time.
Tokens {{…}}In the SQL itself.Values the server fills at execution: user, date, time.

The query owns the declaration; each caller owns its binding. The same query can be called from ten places with ten different bindings.


At a glance​

invoices_putGeneralParamsAdvancedwritableToken ▾Pool schemas ▾UPDATE invoicesSET STATUS = :STATUS, UPDATED_BY = {{LOGIN}}, UPDATED_AT = {{SYSTIMESTAMP}}WHERE INVOICE_ID = :INVOICE_ID_ORIGINAL{{LOGIN}}current user{{SYSDATE}}current date{{SYSTIMESTAMP}}date and time{{JDEDATE}}CYYDDD{{PID}}connector namePARAMSNAMELABELDEFAULTSTATUSStatusPAID:name parametersbound by the callerDeclared paramslabel and defaultToken menuvalues filled by the serverServer tokens{{LOGIN}}, {{SYSDATE}}…

Declaring a parameter​

The Params block of the query editor lists the parameters, one line each:

FieldRole
nameThe parameter as written in the SQL, without the colon.
labelThe label shown above the input when a screen or the AI assistant asks for the value. Defaults to the name.
defaultThe value bound when the caller sends none.
SELECT *
FROM invoices
WHERE invoice_date BETWEEN :FROM_DATE AND :TO_DATE
AND status = :STATUS
namelabeldefault
FROM_DATEPeriod start2026-01-01
TO_DATEPeriod end2026-12-31
STATUSStatusOPEN

Declaring is optional: a parameter that the caller does not send and that has no default is bound to NULL.


Binding a value — param_binds​

Wherever a query is called with values from the context, the caller carries a list of param_binds, one per parameter:

FieldRole
paramThe parameter of the target query. The list offers the parameters the query declares.
valueA fixed value.
sourceWhere to read the value at call time: a column of the row, a field of the form, a value returned by an earlier step of an action (step1.first_row.CUSTOMER_ID), or a built-in.
defaultBound when source gives nothing. A fixed value, a built-in or a step path.

When both value and source are set, value is used.

param_binds = [
{ param = "STATUS", value = "PAID" },
{ param = "INVOICE_ID", source = "INVOICE_ID" },
{ param = "UPMJ", source = "UPMJ", default = "#SYSDATE#" },
]

source holds the name of a column or a field, not its value. The usual case: an action on a row passes the row's key to the query — { param = "INVOICE_ID", source = "INVOICE_ID" }.

Built-in sources​

These sources are read in the browser at the time of the call:

SourceValue
#LOGIN_USER# (or #LOGIN#, #USER#)The signed-in user's name.
#LOGIN_EMAIL# (or #EMAIL#)The user's e-mail address.
#LANGUAGE# (or #LANG#)The interface language.
#POOL# (or #ENVIRONMENT#)The Pool picked in the sidebar. In a confirm / notify message: the environment the screen runs on — that pick when the screen's connector has it, else the connector's own pool.
#SYSDATE# (or #CURRENT_DATE#, #TODAY#)Today's date, YYYY-MM-DD.
#NOW# (or #CURRENT_TIMESTAMP#)The current date and time.
#CURRENT_TIME#The current time, HH:MM:SS.

An unknown built-in binds nothing. Use them in source or default: in value, the text #LOGIN_USER# is bound as it is.


Tokens resolved by the server​

A writable query can write a value the server fills when it executes the statement — the browser cannot change it. The Token menu of the SQL editor inserts them:

TokenValue
{{LOGIN}} (or {{USER}})The signed-in user's name, in upper case.
{{SYSDATE}}The current date.
{{SYSTIME}}The current time.
{{SYSTIMESTAMP}} (or {{NOW}})The current date and time.
{{JDEDATE}}Today as a JD Edwards date (CYYDDD).
{{JDETIME}}The current time as a JD Edwards time (HHMMSS).
{{PID}}The connector name, in upper case.
{{JOBN}}LIBERTY.
UPDATE invoices
SET status = 'PAID',
updated_by = {{LOGIN}},
updated_at = {{SYSTIMESTAMP}}
WHERE invoice_id = :INVOICE_ID

Dates and times use the server's local time, one instant per statement. In COLUMN = {{TOKEN}}, the value takes the column's format from the dictionary (a jdedate column receives CYYDDD). An unknown token makes the statement fail, so a typo does not go unnoticed.


Where bindings are set​

CallerSetting
Dialog save (insert, update, delete)Nothing to declare: each column is bound to the parameter of the same name, and the update's WHERE uses :<KEY>_ORIGINAL, the key's value when the dialog opened.
Action (run a query, call an API or a plugin, open a screen…)The action's param_binds.
Lookup columnThe column's lookup_param_binds (Rules tab), or the dictionary entry's Lookup params for fixed values.
Nested tabThe tab's param_binds — typically the parent row's key.
Menu itemParams (Advanced tab): fixed values passed to the target when it opens.
DashboardThe period and the filters bind :PERIOD_FROM, :PERIOD_TO and the filter columns — see Dashboards.

Resolution order​

For each parameter of the statement:

  1. the value sent by the caller — a param_binds entry, the dialog's field, a menu parameter;
  2. otherwise the default declared on the query;
  3. otherwise NULL.

On a write, the dictionary rules then apply to the bound columns: LOGIN always replaces the value, SYSDATE and DEFAULT fill an empty value, SEQUENCE numbers an insert — see Dictionary → Rules.


Naming conventions​

ConventionWhy
Upper-case parametersBinds are written in upper case on save (param, source), and the CRUD wizard generates upper-case names. Keeping the SQL in upper case avoids any mismatch.
Same name as the columnA parameter named after its column reads naturally and binds itself on a dialog save.
:<KEY>_ORIGINAL in an update's WHEREThe dialog save convention; the CRUD wizard writes it, and a hand-written _put must do the same.

Common pitfalls​

MistakeSymptomFix
value = "#LOGIN_USER#".The text #LOGIN_USER# is written.Use source.
Both value and source set.source is ignored.Keep one.
#SYSDATE# bound to a read filter.The user cannot pick another date.Leave the parameter free, with a default on the query.
A bind for a parameter the query does not have.Nothing happens.Pick the parameter from the list, which follows the query.
A hand-written _put without _ORIGINAL.Changing the key in the dialog updates no row.WHERE key = :KEY_ORIGINAL.

What's next​