<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://brwiki2.brulescorp.com/brwiki2/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=GomezL</id>
	<title>BR Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://brwiki2.brulescorp.com/brwiki2/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=GomezL"/>
	<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Special:Contributions/GomezL"/>
	<updated>2026-07-16T09:28:48Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=DATABASE&amp;diff=11517</id>
		<title>DATABASE</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=DATABASE&amp;diff=11517"/>
		<updated>2026-07-09T13:47:35Z</updated>

		<summary type="html">&lt;p&gt;GomezL: /* Closing Named Connections */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= DATABASE =&lt;br /&gt;
&lt;br /&gt;
Starting in &#039;&#039;&#039;Business Rules! 4.3&#039;&#039;&#039;, the &amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt; directive allows a BR program to connect to external SQL databases through ODBC.&lt;br /&gt;
&lt;br /&gt;
This page covers BR acting as an &#039;&#039;&#039;ODBC SQL client&#039;&#039;&#039; — connecting outward to SQL Server, MySQL, SQLite, Microsoft Access, and other relational databases, executing SQL statements, and reading result rows.&lt;br /&gt;
&lt;br /&gt;
BR treats a live SQL statement as an ordinary I/O channel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt; names the connection.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt; binds a BR file channel to a SQL statement.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; executes the SQL statement.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt; fetches rows for a &amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;CLOSE&amp;lt;/code&amp;gt; releases the statement/result set.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; This is different from the BR ODBC driver that exposes BR data files to Excel, Access, reporting tools, or other external consumers.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Step&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Statement&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Purpose&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;1. Configure connection&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;CONFIG DATABASE &amp;amp;lt;db-ref&amp;amp;gt; ...&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Names a data source and tells BR how to connect to it.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;2. Open SQL channel&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;OPEN #h: &amp;quot;DATABASE=&amp;amp;lt;db-ref&amp;amp;gt;&amp;quot;, SQL sql$, OUTIN&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Binds a BR channel to one SQL statement over the named connection.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;3. Execute SQL&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;WRITE #h:&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Executes the bound SQL statement.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;4. Fetch rows&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;READ #h, USING ...&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Reads result rows from a &amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt;.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;5. Close channel&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;CLOSE #h:&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Releases the SQL statement/result set.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;&amp;lt;db-ref&amp;gt;&amp;lt;/code&amp;gt; is the connection name. The same name used in &amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt; is referenced later in &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;&amp;quot;DATABASE=&amp;lt;db-ref&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXECUTE &#039;CONFIG DATABASE DemoConn CONNECTSTRING=&amp;quot;DRIVER=SQL Server;SERVER=myserver;Initial Catalog=mydb;UID=myuser;PWD=mypass&amp;quot;&#039;&lt;br /&gt;
&lt;br /&gt;
LET C_SQL$ = &amp;quot;SELECT FirstName, LastName FROM dbo.Customers&amp;quot;&lt;br /&gt;
&lt;br /&gt;
OPEN #(H := 21): &amp;quot;DATABASE=DemoConn&amp;quot;, SQL C_SQL$, OUTIN&lt;br /&gt;
WRITE #H:&lt;br /&gt;
&lt;br /&gt;
RD: READ #H, USING &#039;FORM POS 1,C 50,C 50&#039;: FIRST$, LAST$ EOF DONE&lt;br /&gt;
    PRINT TRIM$(FIRST$); &amp;quot; &amp;quot;; TRIM$(LAST$)&lt;br /&gt;
    GOTO RD&lt;br /&gt;
&lt;br /&gt;
DONE: CLOSE #H:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CONFIG DATABASE ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt; defines a named ODBC connection.&lt;br /&gt;
&lt;br /&gt;
It may be placed in &amp;lt;code&amp;gt;BRConfig.sys&amp;lt;/code&amp;gt; or issued from inside a program using &amp;lt;code&amp;gt;EXECUTE&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Connection Methods ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt; supports three connection methods:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;DSN&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;CONNECTSTRING&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== General Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG DATABASE &amp;lt;db-ref&amp;gt; { DSN=&amp;lt;dsn-ref&amp;gt;&lt;br /&gt;
                         | CONNECTSTRING=&amp;quot;&amp;lt;odbc-connection-string&amp;gt;&amp;quot;&lt;br /&gt;
                         | ODBC-MANAGER }&lt;br /&gt;
                         [ , USER= { &amp;lt;department&amp;gt; | LOGIN_NAME | ? } ]&lt;br /&gt;
                         [ , { PASSWORD= { &amp;lt;dept-password&amp;gt; | BR_PASSWORD | ? }&lt;br /&gt;
                             | PASSWORDD=&amp;lt;encrypted-password&amp;gt; } ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Option&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Meaning&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;&amp;amp;lt;db-ref&amp;amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Arbitrary BR database reference name. This is the name used later in &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt;.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;DSN=&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Uses a pre-configured Windows ODBC Data Source Name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;CONNECTSTRING=&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Uses a DSN-less ODBC connection string.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Displays the Windows ODBC manager so the user can select the data source.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;USER=?&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Prompts the operator for the user name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;PASSWORD=?&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Prompts the operator for the password.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;USER=LOGIN_NAME&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Uses the current BR login / Active Directory user name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;PASSWORD=BR_PASSWORD&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Uses the current BR login / Active Directory password.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;PASSWORDD=&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Supplies an encrypted password as a hexadecimal value.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DSN ==&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;DSN&amp;lt;/code&amp;gt; when the ODBC Data Source Name has already been configured in the Windows ODBC manager.&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG DATABASE &amp;lt;db-ref&amp;gt; DSN=&amp;lt;dsn-ref&amp;gt;&lt;br /&gt;
    [, USER=&amp;lt;department&amp;gt; | LOGIN_NAME | ?]&lt;br /&gt;
    [, PASSWORD=&amp;lt;dept-password&amp;gt; | BR_PASSWORD | ? | PASSWORDD=&amp;lt;encrypted-password&amp;gt;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXECUTE &#039;CONFIG DATABASE CLS_Data DSN=&amp;quot;MyData&amp;quot;, PASSWORDD=&amp;lt;encrypted-password&amp;gt;&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Encrypted passwords are expressed as hexadecimal values. BR unhexes and decrypts the value before presenting it to the SQL driver.&lt;br /&gt;
&lt;br /&gt;
== CONNECTSTRING / DSN-less Connections ==&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;CONNECTSTRING&amp;lt;/code&amp;gt; when the full ODBC connection string should be supplied directly.&lt;br /&gt;
&lt;br /&gt;
This is usually the most portable option for deployed applications because it avoids requiring a pre-created DSN on each workstation or server.&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG DATABASE &amp;lt;db-ref&amp;gt; CONNECTSTRING=&amp;quot;&amp;lt;odbc-connection-string&amp;gt;&amp;quot;&lt;br /&gt;
    [, USER=&amp;lt;department&amp;gt; | LOGIN_NAME | ?]&lt;br /&gt;
    [, PASSWORD=&amp;lt;dept-password&amp;gt; | BR_PASSWORD | ? | PASSWORDD=&amp;lt;encrypted-password&amp;gt;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SQL Server with SQL Login ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG DATABASE db-ref CONNECTSTRING=&amp;quot;DRIVER=SQL Server;SERVER=server;Initial Catalog=database;UID=username;PWD=password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Value&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Meaning&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;db-ref&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;BR database reference name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;server&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server FQDN, host name, or IP address.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;database&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server database name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;username&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server login.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;password&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server password.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SQL Server with Windows Authentication ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG DATABASE db-ref CONNECTSTRING=&amp;quot;DRIVER=SQL Server;Initial Catalog=database;SERVER=server&amp;quot; USER=LOGIN_NAME PASSWORD=BR_PASSWORD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When &amp;lt;code&amp;gt;USER=&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;PASSWORD=&amp;lt;/code&amp;gt; are specified outside the quoted connection string, BR augments the ODBC connection string with &amp;lt;code&amp;gt;UID=&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;PWD=&amp;lt;/code&amp;gt; values.&lt;br /&gt;
&lt;br /&gt;
Do not also place &amp;lt;code&amp;gt;UID&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;PWD&amp;lt;/code&amp;gt; inside the connection string itself when using BR&#039;s &amp;lt;code&amp;gt;USER=&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;PASSWORD=&amp;lt;/code&amp;gt; parameters.&lt;br /&gt;
&lt;br /&gt;
=== Other Sample Connection Strings ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Target&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Example&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server, SQL login&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;DRIVER=SQL Server;SERVER=myserver;Initial Catalog=mydb;UID=myuser;PWD=mypass&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server, Windows authentication&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;DRIVER=SQL Server;SERVER=myserver;Initial Catalog=mydb&amp;lt;/code&amp;gt; with &amp;lt;code&amp;gt;USER=LOGIN_NAME PASSWORD=BR_PASSWORD&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;MySQL&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;DSN=BRG_DEMO;SERVER=127.0.0.1;UID=dbadmin;PWD=mypass;DATABASE=brg_demo;PORT=3306&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQLite&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;DSN=SQLite3 Datasource;Database=C:\demo\brg_demo.sqlite;SyncPragma=NORMAL;Timeout=100000&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Microsoft Access&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Driver={Microsoft Access Driver (*.mdb)};DBQ=C:\path\Contact.mdb&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ODBC-MANAGER ==&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt; to display the Windows ODBC manager and allow the user to select the data source at runtime.&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG DATABASE &amp;lt;db-ref&amp;gt; ODBC-MANAGER&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Important Client/Server Note ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt; does &#039;&#039;&#039;not&#039;&#039;&#039; work in Client/Server mode because the ODBC selection occurs on the server, not on the user&#039;s workstation.&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00010 PRINT NEWPAGE&lt;br /&gt;
00020 IF Env$(&amp;quot;br_model&amp;quot;) = &amp;quot;CLIENT_SERVER&amp;quot; THEN PRINT &amp;quot;Warning, you cannot connect to ODBC-MANAGER in Client/Server mode&amp;quot;&lt;br /&gt;
00030 EXECUTE &amp;quot;CONFIG DATABASE Test_DB ODBC-MANAGER&amp;quot; ERROR CONNECT_ERROR&lt;br /&gt;
00040 PRINT &amp;quot;Connection String is:&amp;quot; !:&lt;br /&gt;
00050 PRINT Env$(&amp;quot;STATUS.DATABASE.[TEST_DB].CONNECTSTRING&amp;quot;)&lt;br /&gt;
00060 STOP&lt;br /&gt;
00100 CONNECT_ERROR:&lt;br /&gt;
00110 PRINT &amp;quot;Error Connecting - Err:&amp;quot;; Err; &amp;quot; Line:&amp;quot;; Line; &amp;quot; Syserr:&amp;quot;; Syserr$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Viewing the Resolved Connection String ==&lt;br /&gt;
&lt;br /&gt;
After a connection is configured, BR exposes the effective connection string through &amp;lt;code&amp;gt;Env$&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRINT Env$(&amp;quot;STATUS.DATABASE.[MyConn].CONNECTSTRING&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Connection names in &amp;lt;code&amp;gt;STATUS.DATABASE&amp;lt;/code&amp;gt; paths are generally uppercased by BR. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRINT Env$(&amp;quot;STATUS.DATABASE.[DEMOCONN].CONNECTSTRING&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== OPENing a SQL Statement ==&lt;br /&gt;
&lt;br /&gt;
After the database connection is configured, use &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt; to bind a BR channel to a SQL statement.&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
OPEN #&amp;lt;channel&amp;gt;: &amp;quot;DATABASE=&amp;lt;db-ref&amp;gt;&amp;quot;, SQL &amp;lt;string-expression&amp;gt;, OUTIN&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Clause&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Meaning&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;#&amp;amp;lt;channel&amp;amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;BR file channel number.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;&amp;quot;DATABASE=&amp;amp;lt;db-ref&amp;amp;gt;&amp;quot;&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Refers to the connection previously configured with &amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt;.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;SQL &amp;amp;lt;string-expression&amp;amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL text to bind to the channel.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;OUTIN&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Opens the channel for output and input. Used for both executing and reading.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DIM C_SQL$*4096&lt;br /&gt;
&lt;br /&gt;
LET C_SQL$ = &amp;quot;SELECT FirstName, LastName, Email FROM dbo.Customers ORDER BY LastName&amp;quot;&lt;br /&gt;
&lt;br /&gt;
OPEN #(DB_HANDLE := 21): &amp;quot;DATABASE=DemoConn&amp;quot;, SQL C_SQL$, OUTIN&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The SQL statement is bound at &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt; time. To run a different SQL statement, build a new SQL string and open a new channel.&lt;br /&gt;
&lt;br /&gt;
== Opening SQL from an External File ==&lt;br /&gt;
&lt;br /&gt;
A channel may also use SQL text stored in an external file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
OPEN #H: &amp;quot;DATABASE=MyConn,NAME=Setup_Tables.sql/MyFolder&amp;quot;, SQL, OUTIN&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Executing SQL with WRITE ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; with no data list executes the SQL statement bound during &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
WRITE #DB_HANDLE:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For a &amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; executes the query and prepares the result set. It must be called before the first &amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For &amp;lt;code&amp;gt;INSERT&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;UPDATE&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;DELETE&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; performs the change. No &amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt; follows unless the SQL statement returns rows.&lt;br /&gt;
&lt;br /&gt;
== Parameterized Statements ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; with a data list binds values to parameter markers in the prepared SQL statement.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET C_SQL$ = &amp;quot;INSERT INTO dbo.Customers (FirstName, LastName) VALUES (?, ?)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
OPEN #(H := 21): &amp;quot;DATABASE=DemoConn&amp;quot;, SQL C_SQL$, OUTIN&lt;br /&gt;
WRITE #H: FIRST$, LAST$&lt;br /&gt;
CLOSE #H:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use parameter binding instead of concatenating operator input into SQL strings whenever possible. It avoids quoting errors and reduces SQL injection risk.&lt;br /&gt;
&lt;br /&gt;
== Reading Result Rows ==&lt;br /&gt;
&lt;br /&gt;
Each &amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt; fetches one result row.&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
READ #&amp;lt;channel&amp;gt;, USING &#039;&amp;lt;form-spec&amp;gt;&#039;: &amp;lt;var&amp;gt; [, &amp;lt;var&amp;gt;]* EOF &amp;lt;line-ref&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RD: READ #DB_HANDLE, USING &#039;FORM POS 1,C 50,C 50&#039;: C1$, C2$ EOF DONE&lt;br /&gt;
    PRINT TRIM$(C1$); &amp;quot;,&amp;quot;; TRIM$(C2$)&lt;br /&gt;
    GOTO RD&lt;br /&gt;
&lt;br /&gt;
DONE: CLOSE #DB_HANDLE:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Columns in the SQL &amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt; list map left-to-right onto the variables in the &amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The &amp;lt;code&amp;gt;FORM&amp;lt;/code&amp;gt; must match the expected data layout.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Size character fields generously, for example &amp;lt;code&amp;gt;C 50&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;C 100&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use numeric, date, packed decimal, and other BR &amp;lt;code&amp;gt;FORM&amp;lt;/code&amp;gt; types as appropriate.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;EOF&amp;lt;/code&amp;gt; fires when the result set is exhausted.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;For many columns, arrays and composite forms are usually easier than long lists of individual variables.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Closing SQL Channels ==&lt;br /&gt;
&lt;br /&gt;
Always close SQL channels when done.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CLOSE #DB_HANDLE:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This releases the channel and the associated SQL statement/result set.&lt;br /&gt;
&lt;br /&gt;
This is especially important in loops that repeatedly open SQL statements.&lt;br /&gt;
&lt;br /&gt;
== Clearing Configured Connections ==&lt;br /&gt;
&lt;br /&gt;
To clear one named connection:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXECUTE &amp;quot;CONFIG DATABASE CLEAR MyConn&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To clear all configured database connections:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXECUTE &amp;quot;CONFIG DATABASE CLEAR ALL&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Complete SELECT Example ==&lt;br /&gt;
&lt;br /&gt;
The following example connects to SQL Server, executes a &amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt;, reads the rows, and prints the result.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00010 ! ============================================================&lt;br /&gt;
00020 ! Sample: Connect to SQL Server, SELECT rows, print results&lt;br /&gt;
00030 ! ============================================================&lt;br /&gt;
00040 PRINT NEWPAGE&lt;br /&gt;
00050 DIM C_SQL$*4096&lt;br /&gt;
00060 DIM FIRST$*50, LAST$*50, EMAIL$*100&lt;br /&gt;
00070 DIM DB_HANDLE&lt;br /&gt;
00080 !&lt;br /&gt;
00090 ! --- Step 1: Create the connection ---&lt;br /&gt;
00100 EXECUTE &#039;CONFIG DATABASE DemoConn CONNECTSTRING=&amp;quot;DRIVER=SQL Server;SERVER=myserver;Initial Catalog=mydb;UID=myuser;PWD=mypass&amp;quot;&#039; ERROR CONNECT_ERR&lt;br /&gt;
00110 !&lt;br /&gt;
00120 ! --- Step 2: Define the SQL statement and open a channel ---&lt;br /&gt;
00130 LET C_SQL$ = &amp;quot;SELECT FirstName, LastName, Email FROM dbo.Customers ORDER BY LastName&amp;quot;&lt;br /&gt;
00140 OPEN #(DB_HANDLE := 21): &amp;quot;DATABASE=DemoConn&amp;quot;, SQL C_SQL$, OUTIN ERROR OPEN_ERR&lt;br /&gt;
00150 !&lt;br /&gt;
00160 ! --- Step 3: Execute the query ---&lt;br /&gt;
00170 WRITE #DB_HANDLE: ERROR EXEC_ERR&lt;br /&gt;
00180 !&lt;br /&gt;
00190 ! --- Step 4: Loop through result rows ---&lt;br /&gt;
00200 RD: READ #DB_HANDLE, USING &#039;FORM POS 1,C 50,C 50,C 100&#039;: FIRST$, LAST$, EMAIL$ EOF DONE&lt;br /&gt;
00210     PRINT TRIM$(LAST$); &amp;quot;, &amp;quot;; TRIM$(FIRST$); &amp;quot;  &amp;lt;&amp;quot;; TRIM$(EMAIL$); &amp;quot;&amp;gt;&amp;quot;&lt;br /&gt;
00220     GOTO RD&lt;br /&gt;
00230 !&lt;br /&gt;
00240 DONE:&lt;br /&gt;
00250 CLOSE #DB_HANDLE:&lt;br /&gt;
00260 PRINT &amp;quot;Finished.&amp;quot;&lt;br /&gt;
00270 STOP&lt;br /&gt;
00280 !&lt;br /&gt;
00290 CONNECT_ERR:&lt;br /&gt;
00300 OPEN_ERR:&lt;br /&gt;
00310 EXEC_ERR:&lt;br /&gt;
00320     PRINT &amp;quot;Error:&amp;quot;; ERR; &amp;quot; Line:&amp;quot;; LINE; &amp;quot; Syserr:&amp;quot;; SYSERR$&lt;br /&gt;
00330     STOP&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Windows Authentication Example ==&lt;br /&gt;
&lt;br /&gt;
For SQL Server integrated security, omit credentials from the quoted connection string and allow BR to supply them.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXECUTE &#039;CONFIG DATABASE DemoConn CONNECTSTRING=&amp;quot;DRIVER=SQL Server;Initial Catalog=mydb;SERVER=myserver&amp;quot; USER=LOGIN_NAME PASSWORD=BR_PASSWORD&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INSERT Example ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET C_SQL$ = &amp;quot;INSERT INTO dbo.Customers (FirstName, LastName) VALUES (&#039;Jane&#039;, &#039;Doe&#039;)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
OPEN #(DB_HANDLE := 21): &amp;quot;DATABASE=DemoConn&amp;quot;, SQL C_SQL$, OUTIN&lt;br /&gt;
WRITE #DB_HANDLE:&lt;br /&gt;
CLOSE #DB_HANDLE:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside a BR string, two double-quotes represent one literal double-quote.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET C_SQL$ = &amp;quot;INSERT INTO dbo.Customers (FirstName, LastName) VALUES (&amp;quot;&amp;quot;Jane&amp;quot;&amp;quot;, &amp;quot;&amp;quot;Doe&amp;quot;&amp;quot;)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Error Handling ==&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt; clauses or &amp;lt;code&amp;gt;ON ERROR&amp;lt;/code&amp;gt; to trap connection, execution, and fetch failures.&lt;br /&gt;
&lt;br /&gt;
Report:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;ERR&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;LINE&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;SYSERR$&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
OPEN #(H := 21): &amp;quot;DATABASE=DemoConn&amp;quot;, SQL C_SQL$, OUTIN ERROR SQL_ERR&lt;br /&gt;
WRITE #H: ERROR SQL_ERR&lt;br /&gt;
&lt;br /&gt;
RD: READ #H, USING &#039;FORM POS 1,C 50&#039;: C1$ EOF DONE ERROR SQL_ERR&lt;br /&gt;
    PRINT C1$&lt;br /&gt;
    GOTO RD&lt;br /&gt;
&lt;br /&gt;
DONE:&lt;br /&gt;
    CLOSE #H:&lt;br /&gt;
    STOP&lt;br /&gt;
&lt;br /&gt;
SQL_ERR:&lt;br /&gt;
    PRINT &amp;quot;Error:&amp;quot;; ERR; &amp;quot; Line:&amp;quot;; LINE; &amp;quot; Syserr:&amp;quot;; SYSERR$&lt;br /&gt;
    STOP&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common SQL / ODBC Error Codes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Code&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Meaning&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;3006 / 4006&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL execute-direct failed.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;3007 / 4007&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; used with the incorrect number of data elements. Usually a parameter mismatch.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;3010 / 4010&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL fetch-row failed.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;3011 / 4011&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL bind-parameter failure.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;4015&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;The specified database has not been opened.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;4270&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;EOF on &amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt;. This is normal end-of-result-set behavior when an &amp;lt;code&amp;gt;EOF&amp;lt;/code&amp;gt; clause is not used.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First checks when a connection or query fails:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the ODBC driver name.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the server name or IP address.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the database name.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm credentials.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm network/firewall access.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the ODBC driver is installed on the machine running BR.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If using &amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt;, confirm BR is not running in Client/Server mode.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== STATUS.DATABASE Introspection ==&lt;br /&gt;
&lt;br /&gt;
After opening a channel against a connection, BR exposes metadata through &amp;lt;code&amp;gt;STATUS.DATABASE&amp;lt;/code&amp;gt; environment variables.&lt;br /&gt;
&lt;br /&gt;
=== Resolved Connection String ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRINT Env$(&amp;quot;STATUS.DATABASE.[DEMOCONN].CONNECTSTRING&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== List Tables ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET Env$(&amp;quot;STATUS.DATABASE.[DEMOCONN].TABLES.LIST&amp;quot;, MAT TABLES$)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== List Columns ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET Env$(&amp;quot;STATUS.DATABASE.[DEMOCONN].TABLES.[CUSTOMERS].COLUMNS.LIST&amp;quot;, MAT COLS$)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Column Metadata ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRINT Env$(&amp;quot;STATUS.DATABASE.[DEMOCONN].TABLES.[CUSTOMERS].COLUMNS.[EMAIL].TYPE&amp;quot;)&lt;br /&gt;
PRINT Env$(&amp;quot;STATUS.DATABASE.[DEMOCONN].TABLES.[CUSTOMERS].COLUMNS.[EMAIL].LENGTH&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Connection names in &amp;lt;code&amp;gt;STATUS.DATABASE&amp;lt;/code&amp;gt; paths are uppercased by BR.&lt;br /&gt;
&lt;br /&gt;
== Production-Style Usage Pattern ==&lt;br /&gt;
&lt;br /&gt;
The same ODBC pattern can be used in larger production routines that synchronize BR data files with SQL Server tables.&lt;br /&gt;
&lt;br /&gt;
A production routine commonly performs these tasks:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Configure named SQL connections.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Discover SQL table structure.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Read SQL rows through BR channels.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Compare SQL rows against BR file records.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Perform inserts, updates, and deletes.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Page through large SQL tables.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Reuse and clear named connections.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example Setup Pattern ==&lt;br /&gt;
&lt;br /&gt;
A program may load supporting routines and configure a default SQL connection from environment variables.  These examples and environment are not part of the Business Rules language, rather suggestoins that may be usefull.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY &amp;quot;SQL/Library&amp;quot;: Fnopen_Sql_File&lt;br /&gt;
LIBRARY &amp;quot;Util/Library&amp;quot;: Fngethandle, Fnget_Form&lt;br /&gt;
&lt;br /&gt;
LET Fn_Config_Sql(&amp;quot;SetUpConn&amp;quot;, Env$(&amp;quot;SQL-SYNC-SERVER&amp;quot;), Env$(&amp;quot;SQL-SYNC-DATABASE&amp;quot;))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Common environment variables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Variable&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Purpose&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;SQL-SYNC-SERVER&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server host name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;SQL-SYNC-DATABASE&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Target SQL Server database.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;SQL-SYNC-CONNECTION&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Optional override connection string. May support a &amp;lt;code&amp;gt;[LOGIN_NAME]&amp;lt;/code&amp;gt; placeholder.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;SQL-SYNC-DRIVER&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Optional ODBC driver name. Defaults to &amp;lt;code&amp;gt;SQL Server&amp;lt;/code&amp;gt;.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Connection Helper Pattern ==&lt;br /&gt;
&lt;br /&gt;
A helper routine can wrap &amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt; and cache connections so each named reference is configured only once per session.&lt;br /&gt;
&lt;br /&gt;
Typical parameters:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Parameter&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Purpose&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Cs_Connection$&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Arbitrary database reference name, such as &amp;lt;code&amp;gt;C_SelectCon&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;C_InsertCon&amp;lt;/code&amp;gt;.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Cs_Server$&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server host name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Cs_Database$&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server database name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Cs_User$&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL login. Often defaults to &amp;lt;code&amp;gt;LOGIN_NAME$&amp;lt;/code&amp;gt;.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Password$&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL password. Often defaults to &amp;lt;code&amp;gt;BR_PASSWORD&amp;lt;/code&amp;gt; for Windows authentication.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Cs_Sql_Authentication&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Indicates SQL authentication mode.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Cs_Driver$&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;ODBC driver name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example pattern:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DEF Fn_Config_Sql(Cs_Connection$*256, Cs_Server$*256, Cs_Database$*256;&lt;br /&gt;
                  Cs_User$*256, Password$*256, Cs_Sql_Authentication, Cs_Driver$*256)&lt;br /&gt;
&lt;br /&gt;
    EXECUTE &#039;CONFIG DATABASE &#039; &amp;amp; Cs_Connection$ &amp;amp;&lt;br /&gt;
            &#039; CONNECTSTRING=&amp;quot;&#039; &amp;amp; Connectionstring$ &amp;amp; &#039;&amp;quot;&#039; ERROR CONNECT_ERROR&lt;br /&gt;
&lt;br /&gt;
FNEND&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Separate Connections for Separate Workloads ==&lt;br /&gt;
&lt;br /&gt;
Larger routines commonly use separate named connections so concurrent SQL channels do not collide.  Technically you can perform everything through a single connection. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Connection Name&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Typical Use&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;C_SelectCon&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SELECT queries and schema discovery.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;C_InsertCon&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;INSERT operations.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;C_UpdateCon&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;UPDATE operations.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;C_DeleteCon&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;DELETE operations.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;C_RetryCon&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Retry path after transient SQL errors.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;SetUpConn&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Folder/setup stored procedures.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET Sconn$ = &amp;quot;C_SelectCon&amp;quot;&lt;br /&gt;
LET Insconn$ = &amp;quot;C_InsertCon&amp;quot;&lt;br /&gt;
LET Delconn$ = &amp;quot;C_DeleteCon&amp;quot;&lt;br /&gt;
&lt;br /&gt;
LET Fn_Config_Sql(Sconn$, Bc_Server$, Bc_Database$, Bc_User$, Bc_Password$)&lt;br /&gt;
LET Fn_Config_Sql(Insconn$, Bc_Server$, Bc_Database$, Bc_User$, Bc_Password$)&lt;br /&gt;
LET Fn_Config_Sql(Delconn$, Bc_Server$, Bc_Database$, Bc_User$, Bc_Password$)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discovering SQL Table Structure ==&lt;br /&gt;
&lt;br /&gt;
A program can discover SQL columns by opening a &amp;lt;code&amp;gt;SELECT TOP 1 *&amp;lt;/code&amp;gt; channel and reading metadata from &amp;lt;code&amp;gt;STATUS.DATABASE&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET Qry_Ispent_Design$ = &amp;quot;SELECT TOP 1 * FROM &amp;quot; &amp;amp; Gsf_Object$&lt;br /&gt;
&lt;br /&gt;
OPEN #(Db_Handle_Design := Fngethandle): &amp;quot;DATABASE=&amp;quot; &amp;amp; Gsf_Connection$, SQL Qry_Ispent_Design$, OUTIN&lt;br /&gt;
&lt;br /&gt;
LET Env$(&amp;quot;STATUS.DATABASE.[&amp;quot; &amp;amp; Trim$(Uprc$(Gsf_Connection$)) &amp;amp;&lt;br /&gt;
       &amp;quot;].TABLES.[&amp;quot; &amp;amp; Trim$(Uprc$(Gsf_Object$)) &amp;amp; &amp;quot;].COLUMNS&amp;quot;, MAT Columns$)&lt;br /&gt;
&lt;br /&gt;
CLOSE #Db_Handle_Design:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The resulting metadata can be used to classify columns as character, date, or numeric and to build the appropriate BR &amp;lt;code&amp;gt;FORM&amp;lt;/code&amp;gt; definitions.&lt;br /&gt;
&lt;br /&gt;
== Incremental Processing Pattern ==&lt;br /&gt;
&lt;br /&gt;
Large SQL tables should usually be processed in batches rather than loaded all at once.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
! Build the SELECT&lt;br /&gt;
LET Qry_Select$ = &amp;quot;SELECT TOP 100000 col1, col2 FROM [dbo].[MYTABLE] WITH (NOLOCK)&amp;quot; &amp;amp;&lt;br /&gt;
                  &amp;quot; WHERE Folder_Number = &amp;quot; &amp;amp; Folder_Number$ &amp;amp;&lt;br /&gt;
                  &amp;quot; ORDER BY Record_Number ASC&amp;quot;&lt;br /&gt;
&lt;br /&gt;
! Save SQL for debugging&lt;br /&gt;
LET Setenv(&amp;quot;ER_Last_SQL&amp;quot;, Qry_Select$)&lt;br /&gt;
&lt;br /&gt;
! Open and execute&lt;br /&gt;
OPEN #(Selhandle := 20): &amp;quot;DATABASE=C_SelectCon&amp;quot;, SQL Qry_Select$, OUTIN&lt;br /&gt;
WRITE #Selhandle:&lt;br /&gt;
&lt;br /&gt;
! Read rows&lt;br /&gt;
READ #Selhandle: MAT Sql_Object_Data$, MAT Sql_Object_Data_Dates$, MAT Sql_Object_Data EOF SQL_EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the batch is exhausted, close the channel, build a new &amp;lt;code&amp;gt;SELECT TOP ... WHERE Record_Number &amp;gt; &amp;lt;last&amp;gt;&amp;lt;/code&amp;gt; query, and open a fresh channel.&lt;br /&gt;
&lt;br /&gt;
== DML Pattern: INSERT / UPDATE / DELETE ==&lt;br /&gt;
&lt;br /&gt;
Data-changing SQL follows the same &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;CLOSE&amp;lt;/code&amp;gt; pattern.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET Setenv(&amp;quot;ER_Last_SQL&amp;quot;, Insert_Sql$)&lt;br /&gt;
&lt;br /&gt;
OPEN #(Inshandle := Fngethandle): &amp;quot;DATABASE=C_InsertCon&amp;quot;, SQL Insert_Sql$, OUTIN&lt;br /&gt;
WRITE #Inshandle: ERROR SQL_ERROR&lt;br /&gt;
CLOSE #Inshandle:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Closing Named Connections ==&lt;br /&gt;
&lt;br /&gt;
At the end of a SQL operation, close or clear configured connections.  For simplicity, you can define a function to close the connection.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET Fn_Close_Db_Connections(Sconn$)&lt;br /&gt;
LET Fn_Close_Db_Connections(Insconn$)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or clear all configured database connections:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXECUTE &amp;quot;CONFIG DATABASE CLEAR ALL&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example Helper Entry Points ==&lt;br /&gt;
&lt;br /&gt;
A larger BR SQL integration may include helper routines similar to the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Function&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Purpose&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Config_Sql&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Establishes a named ODBC connection.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Get_Sql_Fields&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Discovers SQL table or view column layout.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fnshow_Database&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Prints connection, table, and column metadata.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Bulk_Insert&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Copies BR records to SQL in a full load.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Incremental_Sync&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Compares and reconciles BR rows against SQL rows.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Create_Table&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Creates SQL tables.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Alter_Table&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Alters SQL table structure.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Truncate_Table&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Clears a SQL table.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Close_Db_Connections&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Releases configured SQL connections.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example Usage from a Program ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY &amp;quot;SQL/Library&amp;quot;: Fnopen_Sql_File&lt;br /&gt;
LIBRARY &amp;quot;util/Library&amp;quot;: Fngethandle, Fnget_Form&lt;br /&gt;
&lt;br /&gt;
LET Fn_Config_Sql(&amp;quot;MyConn&amp;quot;, &amp;quot;VT-SQL01&amp;quot;, &amp;quot;MyDatabase&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
LET Fn_Get_Sql_Fields(&amp;quot;MyConn&amp;quot;, &amp;quot;CUSTOMERS&amp;quot;, MAT Data$, MAT Dates$, MAT Data)&lt;br /&gt;
&lt;br /&gt;
! Program logic here&lt;br /&gt;
&lt;br /&gt;
LET Fn_Close_Db_Connections(&amp;quot;MyConn&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Security Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Protect source files and saved connection strings. Literal credentials inside connection strings are visible to anyone who can read the program or configuration.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Prefer &amp;lt;code&amp;gt;PASSWORDD=&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;BR_PASSWORD&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;LOGIN_NAME&amp;lt;/code&amp;gt;, or runtime prompts over literal passwords.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Prefer parameterized statements using &amp;lt;code&amp;gt;WRITE #h: value1, value2&amp;lt;/code&amp;gt; over string concatenation of user input.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Avoid placing both &amp;lt;code&amp;gt;UID/PWD&amp;lt;/code&amp;gt; inside the connection string and &amp;lt;code&amp;gt;USER/PASSWORD&amp;lt;/code&amp;gt; outside the connection string.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Do not use &amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt; in Client/Server mode.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;When practical, log the last SQL statement to an environment variable such as &amp;lt;code&amp;gt;ER_Last_SQL&amp;lt;/code&amp;gt; for troubleshooting.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Always close SQL channels after use.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting Checklist ==&lt;br /&gt;
&lt;br /&gt;
When a database connection fails:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the ODBC driver is installed on the machine running BR.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the driver name matches the connection string.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the SQL Server, MySQL, SQLite, or Access target is reachable.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm credentials.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the database name.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm firewall and network access.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the connection works in the Windows ODBC manager.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If using Windows authentication, confirm the BR process is running under the expected user context.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If using Client/Server mode, avoid &amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Print &amp;lt;code&amp;gt;SYSERR$&amp;lt;/code&amp;gt; for the driver-specific error message.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When a query fails:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Print or log the SQL statement.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm table and column names.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm quoting of strings and dates.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the number of parameter markers matches the number of values supplied to &amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the &amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt; form matches the selected columns.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm character fields are wide enough.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use &amp;lt;code&amp;gt;STATUS.DATABASE&amp;lt;/code&amp;gt; metadata to inspect table and column definitions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[CONFIG]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[EXECUTE]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[OPEN]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[WRITE]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[READ]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[CLOSE]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Encrypted passwords]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Unhex]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Decrypt]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:All Parameters]]&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=DATABASE&amp;diff=11516</id>
		<title>DATABASE</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=DATABASE&amp;diff=11516"/>
		<updated>2026-07-09T13:45:28Z</updated>

		<summary type="html">&lt;p&gt;GomezL: /* Separate Connections for Separate Workloads */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= DATABASE =&lt;br /&gt;
&lt;br /&gt;
Starting in &#039;&#039;&#039;Business Rules! 4.3&#039;&#039;&#039;, the &amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt; directive allows a BR program to connect to external SQL databases through ODBC.&lt;br /&gt;
&lt;br /&gt;
This page covers BR acting as an &#039;&#039;&#039;ODBC SQL client&#039;&#039;&#039; — connecting outward to SQL Server, MySQL, SQLite, Microsoft Access, and other relational databases, executing SQL statements, and reading result rows.&lt;br /&gt;
&lt;br /&gt;
BR treats a live SQL statement as an ordinary I/O channel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt; names the connection.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt; binds a BR file channel to a SQL statement.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; executes the SQL statement.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt; fetches rows for a &amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;CLOSE&amp;lt;/code&amp;gt; releases the statement/result set.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; This is different from the BR ODBC driver that exposes BR data files to Excel, Access, reporting tools, or other external consumers.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Step&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Statement&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Purpose&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;1. Configure connection&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;CONFIG DATABASE &amp;amp;lt;db-ref&amp;amp;gt; ...&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Names a data source and tells BR how to connect to it.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;2. Open SQL channel&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;OPEN #h: &amp;quot;DATABASE=&amp;amp;lt;db-ref&amp;amp;gt;&amp;quot;, SQL sql$, OUTIN&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Binds a BR channel to one SQL statement over the named connection.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;3. Execute SQL&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;WRITE #h:&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Executes the bound SQL statement.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;4. Fetch rows&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;READ #h, USING ...&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Reads result rows from a &amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt;.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;5. Close channel&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;CLOSE #h:&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Releases the SQL statement/result set.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;&amp;lt;db-ref&amp;gt;&amp;lt;/code&amp;gt; is the connection name. The same name used in &amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt; is referenced later in &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;&amp;quot;DATABASE=&amp;lt;db-ref&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXECUTE &#039;CONFIG DATABASE DemoConn CONNECTSTRING=&amp;quot;DRIVER=SQL Server;SERVER=myserver;Initial Catalog=mydb;UID=myuser;PWD=mypass&amp;quot;&#039;&lt;br /&gt;
&lt;br /&gt;
LET C_SQL$ = &amp;quot;SELECT FirstName, LastName FROM dbo.Customers&amp;quot;&lt;br /&gt;
&lt;br /&gt;
OPEN #(H := 21): &amp;quot;DATABASE=DemoConn&amp;quot;, SQL C_SQL$, OUTIN&lt;br /&gt;
WRITE #H:&lt;br /&gt;
&lt;br /&gt;
RD: READ #H, USING &#039;FORM POS 1,C 50,C 50&#039;: FIRST$, LAST$ EOF DONE&lt;br /&gt;
    PRINT TRIM$(FIRST$); &amp;quot; &amp;quot;; TRIM$(LAST$)&lt;br /&gt;
    GOTO RD&lt;br /&gt;
&lt;br /&gt;
DONE: CLOSE #H:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CONFIG DATABASE ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt; defines a named ODBC connection.&lt;br /&gt;
&lt;br /&gt;
It may be placed in &amp;lt;code&amp;gt;BRConfig.sys&amp;lt;/code&amp;gt; or issued from inside a program using &amp;lt;code&amp;gt;EXECUTE&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Connection Methods ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt; supports three connection methods:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;DSN&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;CONNECTSTRING&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== General Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG DATABASE &amp;lt;db-ref&amp;gt; { DSN=&amp;lt;dsn-ref&amp;gt;&lt;br /&gt;
                         | CONNECTSTRING=&amp;quot;&amp;lt;odbc-connection-string&amp;gt;&amp;quot;&lt;br /&gt;
                         | ODBC-MANAGER }&lt;br /&gt;
                         [ , USER= { &amp;lt;department&amp;gt; | LOGIN_NAME | ? } ]&lt;br /&gt;
                         [ , { PASSWORD= { &amp;lt;dept-password&amp;gt; | BR_PASSWORD | ? }&lt;br /&gt;
                             | PASSWORDD=&amp;lt;encrypted-password&amp;gt; } ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Option&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Meaning&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;&amp;amp;lt;db-ref&amp;amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Arbitrary BR database reference name. This is the name used later in &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt;.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;DSN=&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Uses a pre-configured Windows ODBC Data Source Name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;CONNECTSTRING=&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Uses a DSN-less ODBC connection string.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Displays the Windows ODBC manager so the user can select the data source.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;USER=?&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Prompts the operator for the user name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;PASSWORD=?&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Prompts the operator for the password.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;USER=LOGIN_NAME&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Uses the current BR login / Active Directory user name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;PASSWORD=BR_PASSWORD&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Uses the current BR login / Active Directory password.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;PASSWORDD=&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Supplies an encrypted password as a hexadecimal value.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DSN ==&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;DSN&amp;lt;/code&amp;gt; when the ODBC Data Source Name has already been configured in the Windows ODBC manager.&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG DATABASE &amp;lt;db-ref&amp;gt; DSN=&amp;lt;dsn-ref&amp;gt;&lt;br /&gt;
    [, USER=&amp;lt;department&amp;gt; | LOGIN_NAME | ?]&lt;br /&gt;
    [, PASSWORD=&amp;lt;dept-password&amp;gt; | BR_PASSWORD | ? | PASSWORDD=&amp;lt;encrypted-password&amp;gt;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXECUTE &#039;CONFIG DATABASE CLS_Data DSN=&amp;quot;MyData&amp;quot;, PASSWORDD=&amp;lt;encrypted-password&amp;gt;&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Encrypted passwords are expressed as hexadecimal values. BR unhexes and decrypts the value before presenting it to the SQL driver.&lt;br /&gt;
&lt;br /&gt;
== CONNECTSTRING / DSN-less Connections ==&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;CONNECTSTRING&amp;lt;/code&amp;gt; when the full ODBC connection string should be supplied directly.&lt;br /&gt;
&lt;br /&gt;
This is usually the most portable option for deployed applications because it avoids requiring a pre-created DSN on each workstation or server.&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG DATABASE &amp;lt;db-ref&amp;gt; CONNECTSTRING=&amp;quot;&amp;lt;odbc-connection-string&amp;gt;&amp;quot;&lt;br /&gt;
    [, USER=&amp;lt;department&amp;gt; | LOGIN_NAME | ?]&lt;br /&gt;
    [, PASSWORD=&amp;lt;dept-password&amp;gt; | BR_PASSWORD | ? | PASSWORDD=&amp;lt;encrypted-password&amp;gt;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SQL Server with SQL Login ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG DATABASE db-ref CONNECTSTRING=&amp;quot;DRIVER=SQL Server;SERVER=server;Initial Catalog=database;UID=username;PWD=password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Value&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Meaning&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;db-ref&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;BR database reference name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;server&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server FQDN, host name, or IP address.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;database&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server database name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;username&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server login.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;password&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server password.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SQL Server with Windows Authentication ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG DATABASE db-ref CONNECTSTRING=&amp;quot;DRIVER=SQL Server;Initial Catalog=database;SERVER=server&amp;quot; USER=LOGIN_NAME PASSWORD=BR_PASSWORD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When &amp;lt;code&amp;gt;USER=&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;PASSWORD=&amp;lt;/code&amp;gt; are specified outside the quoted connection string, BR augments the ODBC connection string with &amp;lt;code&amp;gt;UID=&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;PWD=&amp;lt;/code&amp;gt; values.&lt;br /&gt;
&lt;br /&gt;
Do not also place &amp;lt;code&amp;gt;UID&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;PWD&amp;lt;/code&amp;gt; inside the connection string itself when using BR&#039;s &amp;lt;code&amp;gt;USER=&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;PASSWORD=&amp;lt;/code&amp;gt; parameters.&lt;br /&gt;
&lt;br /&gt;
=== Other Sample Connection Strings ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Target&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Example&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server, SQL login&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;DRIVER=SQL Server;SERVER=myserver;Initial Catalog=mydb;UID=myuser;PWD=mypass&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server, Windows authentication&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;DRIVER=SQL Server;SERVER=myserver;Initial Catalog=mydb&amp;lt;/code&amp;gt; with &amp;lt;code&amp;gt;USER=LOGIN_NAME PASSWORD=BR_PASSWORD&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;MySQL&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;DSN=BRG_DEMO;SERVER=127.0.0.1;UID=dbadmin;PWD=mypass;DATABASE=brg_demo;PORT=3306&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQLite&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;DSN=SQLite3 Datasource;Database=C:\demo\brg_demo.sqlite;SyncPragma=NORMAL;Timeout=100000&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Microsoft Access&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Driver={Microsoft Access Driver (*.mdb)};DBQ=C:\path\Contact.mdb&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ODBC-MANAGER ==&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt; to display the Windows ODBC manager and allow the user to select the data source at runtime.&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG DATABASE &amp;lt;db-ref&amp;gt; ODBC-MANAGER&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Important Client/Server Note ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt; does &#039;&#039;&#039;not&#039;&#039;&#039; work in Client/Server mode because the ODBC selection occurs on the server, not on the user&#039;s workstation.&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00010 PRINT NEWPAGE&lt;br /&gt;
00020 IF Env$(&amp;quot;br_model&amp;quot;) = &amp;quot;CLIENT_SERVER&amp;quot; THEN PRINT &amp;quot;Warning, you cannot connect to ODBC-MANAGER in Client/Server mode&amp;quot;&lt;br /&gt;
00030 EXECUTE &amp;quot;CONFIG DATABASE Test_DB ODBC-MANAGER&amp;quot; ERROR CONNECT_ERROR&lt;br /&gt;
00040 PRINT &amp;quot;Connection String is:&amp;quot; !:&lt;br /&gt;
00050 PRINT Env$(&amp;quot;STATUS.DATABASE.[TEST_DB].CONNECTSTRING&amp;quot;)&lt;br /&gt;
00060 STOP&lt;br /&gt;
00100 CONNECT_ERROR:&lt;br /&gt;
00110 PRINT &amp;quot;Error Connecting - Err:&amp;quot;; Err; &amp;quot; Line:&amp;quot;; Line; &amp;quot; Syserr:&amp;quot;; Syserr$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Viewing the Resolved Connection String ==&lt;br /&gt;
&lt;br /&gt;
After a connection is configured, BR exposes the effective connection string through &amp;lt;code&amp;gt;Env$&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRINT Env$(&amp;quot;STATUS.DATABASE.[MyConn].CONNECTSTRING&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Connection names in &amp;lt;code&amp;gt;STATUS.DATABASE&amp;lt;/code&amp;gt; paths are generally uppercased by BR. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRINT Env$(&amp;quot;STATUS.DATABASE.[DEMOCONN].CONNECTSTRING&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== OPENing a SQL Statement ==&lt;br /&gt;
&lt;br /&gt;
After the database connection is configured, use &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt; to bind a BR channel to a SQL statement.&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
OPEN #&amp;lt;channel&amp;gt;: &amp;quot;DATABASE=&amp;lt;db-ref&amp;gt;&amp;quot;, SQL &amp;lt;string-expression&amp;gt;, OUTIN&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Clause&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Meaning&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;#&amp;amp;lt;channel&amp;amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;BR file channel number.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;&amp;quot;DATABASE=&amp;amp;lt;db-ref&amp;amp;gt;&amp;quot;&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Refers to the connection previously configured with &amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt;.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;SQL &amp;amp;lt;string-expression&amp;amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL text to bind to the channel.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;OUTIN&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Opens the channel for output and input. Used for both executing and reading.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DIM C_SQL$*4096&lt;br /&gt;
&lt;br /&gt;
LET C_SQL$ = &amp;quot;SELECT FirstName, LastName, Email FROM dbo.Customers ORDER BY LastName&amp;quot;&lt;br /&gt;
&lt;br /&gt;
OPEN #(DB_HANDLE := 21): &amp;quot;DATABASE=DemoConn&amp;quot;, SQL C_SQL$, OUTIN&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The SQL statement is bound at &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt; time. To run a different SQL statement, build a new SQL string and open a new channel.&lt;br /&gt;
&lt;br /&gt;
== Opening SQL from an External File ==&lt;br /&gt;
&lt;br /&gt;
A channel may also use SQL text stored in an external file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
OPEN #H: &amp;quot;DATABASE=MyConn,NAME=Setup_Tables.sql/MyFolder&amp;quot;, SQL, OUTIN&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Executing SQL with WRITE ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; with no data list executes the SQL statement bound during &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
WRITE #DB_HANDLE:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For a &amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; executes the query and prepares the result set. It must be called before the first &amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For &amp;lt;code&amp;gt;INSERT&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;UPDATE&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;DELETE&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; performs the change. No &amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt; follows unless the SQL statement returns rows.&lt;br /&gt;
&lt;br /&gt;
== Parameterized Statements ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; with a data list binds values to parameter markers in the prepared SQL statement.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET C_SQL$ = &amp;quot;INSERT INTO dbo.Customers (FirstName, LastName) VALUES (?, ?)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
OPEN #(H := 21): &amp;quot;DATABASE=DemoConn&amp;quot;, SQL C_SQL$, OUTIN&lt;br /&gt;
WRITE #H: FIRST$, LAST$&lt;br /&gt;
CLOSE #H:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use parameter binding instead of concatenating operator input into SQL strings whenever possible. It avoids quoting errors and reduces SQL injection risk.&lt;br /&gt;
&lt;br /&gt;
== Reading Result Rows ==&lt;br /&gt;
&lt;br /&gt;
Each &amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt; fetches one result row.&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
READ #&amp;lt;channel&amp;gt;, USING &#039;&amp;lt;form-spec&amp;gt;&#039;: &amp;lt;var&amp;gt; [, &amp;lt;var&amp;gt;]* EOF &amp;lt;line-ref&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RD: READ #DB_HANDLE, USING &#039;FORM POS 1,C 50,C 50&#039;: C1$, C2$ EOF DONE&lt;br /&gt;
    PRINT TRIM$(C1$); &amp;quot;,&amp;quot;; TRIM$(C2$)&lt;br /&gt;
    GOTO RD&lt;br /&gt;
&lt;br /&gt;
DONE: CLOSE #DB_HANDLE:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Columns in the SQL &amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt; list map left-to-right onto the variables in the &amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The &amp;lt;code&amp;gt;FORM&amp;lt;/code&amp;gt; must match the expected data layout.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Size character fields generously, for example &amp;lt;code&amp;gt;C 50&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;C 100&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use numeric, date, packed decimal, and other BR &amp;lt;code&amp;gt;FORM&amp;lt;/code&amp;gt; types as appropriate.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;EOF&amp;lt;/code&amp;gt; fires when the result set is exhausted.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;For many columns, arrays and composite forms are usually easier than long lists of individual variables.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Closing SQL Channels ==&lt;br /&gt;
&lt;br /&gt;
Always close SQL channels when done.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CLOSE #DB_HANDLE:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This releases the channel and the associated SQL statement/result set.&lt;br /&gt;
&lt;br /&gt;
This is especially important in loops that repeatedly open SQL statements.&lt;br /&gt;
&lt;br /&gt;
== Clearing Configured Connections ==&lt;br /&gt;
&lt;br /&gt;
To clear one named connection:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXECUTE &amp;quot;CONFIG DATABASE CLEAR MyConn&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To clear all configured database connections:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXECUTE &amp;quot;CONFIG DATABASE CLEAR ALL&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Complete SELECT Example ==&lt;br /&gt;
&lt;br /&gt;
The following example connects to SQL Server, executes a &amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt;, reads the rows, and prints the result.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00010 ! ============================================================&lt;br /&gt;
00020 ! Sample: Connect to SQL Server, SELECT rows, print results&lt;br /&gt;
00030 ! ============================================================&lt;br /&gt;
00040 PRINT NEWPAGE&lt;br /&gt;
00050 DIM C_SQL$*4096&lt;br /&gt;
00060 DIM FIRST$*50, LAST$*50, EMAIL$*100&lt;br /&gt;
00070 DIM DB_HANDLE&lt;br /&gt;
00080 !&lt;br /&gt;
00090 ! --- Step 1: Create the connection ---&lt;br /&gt;
00100 EXECUTE &#039;CONFIG DATABASE DemoConn CONNECTSTRING=&amp;quot;DRIVER=SQL Server;SERVER=myserver;Initial Catalog=mydb;UID=myuser;PWD=mypass&amp;quot;&#039; ERROR CONNECT_ERR&lt;br /&gt;
00110 !&lt;br /&gt;
00120 ! --- Step 2: Define the SQL statement and open a channel ---&lt;br /&gt;
00130 LET C_SQL$ = &amp;quot;SELECT FirstName, LastName, Email FROM dbo.Customers ORDER BY LastName&amp;quot;&lt;br /&gt;
00140 OPEN #(DB_HANDLE := 21): &amp;quot;DATABASE=DemoConn&amp;quot;, SQL C_SQL$, OUTIN ERROR OPEN_ERR&lt;br /&gt;
00150 !&lt;br /&gt;
00160 ! --- Step 3: Execute the query ---&lt;br /&gt;
00170 WRITE #DB_HANDLE: ERROR EXEC_ERR&lt;br /&gt;
00180 !&lt;br /&gt;
00190 ! --- Step 4: Loop through result rows ---&lt;br /&gt;
00200 RD: READ #DB_HANDLE, USING &#039;FORM POS 1,C 50,C 50,C 100&#039;: FIRST$, LAST$, EMAIL$ EOF DONE&lt;br /&gt;
00210     PRINT TRIM$(LAST$); &amp;quot;, &amp;quot;; TRIM$(FIRST$); &amp;quot;  &amp;lt;&amp;quot;; TRIM$(EMAIL$); &amp;quot;&amp;gt;&amp;quot;&lt;br /&gt;
00220     GOTO RD&lt;br /&gt;
00230 !&lt;br /&gt;
00240 DONE:&lt;br /&gt;
00250 CLOSE #DB_HANDLE:&lt;br /&gt;
00260 PRINT &amp;quot;Finished.&amp;quot;&lt;br /&gt;
00270 STOP&lt;br /&gt;
00280 !&lt;br /&gt;
00290 CONNECT_ERR:&lt;br /&gt;
00300 OPEN_ERR:&lt;br /&gt;
00310 EXEC_ERR:&lt;br /&gt;
00320     PRINT &amp;quot;Error:&amp;quot;; ERR; &amp;quot; Line:&amp;quot;; LINE; &amp;quot; Syserr:&amp;quot;; SYSERR$&lt;br /&gt;
00330     STOP&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Windows Authentication Example ==&lt;br /&gt;
&lt;br /&gt;
For SQL Server integrated security, omit credentials from the quoted connection string and allow BR to supply them.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXECUTE &#039;CONFIG DATABASE DemoConn CONNECTSTRING=&amp;quot;DRIVER=SQL Server;Initial Catalog=mydb;SERVER=myserver&amp;quot; USER=LOGIN_NAME PASSWORD=BR_PASSWORD&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INSERT Example ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET C_SQL$ = &amp;quot;INSERT INTO dbo.Customers (FirstName, LastName) VALUES (&#039;Jane&#039;, &#039;Doe&#039;)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
OPEN #(DB_HANDLE := 21): &amp;quot;DATABASE=DemoConn&amp;quot;, SQL C_SQL$, OUTIN&lt;br /&gt;
WRITE #DB_HANDLE:&lt;br /&gt;
CLOSE #DB_HANDLE:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside a BR string, two double-quotes represent one literal double-quote.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET C_SQL$ = &amp;quot;INSERT INTO dbo.Customers (FirstName, LastName) VALUES (&amp;quot;&amp;quot;Jane&amp;quot;&amp;quot;, &amp;quot;&amp;quot;Doe&amp;quot;&amp;quot;)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Error Handling ==&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt; clauses or &amp;lt;code&amp;gt;ON ERROR&amp;lt;/code&amp;gt; to trap connection, execution, and fetch failures.&lt;br /&gt;
&lt;br /&gt;
Report:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;ERR&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;LINE&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;SYSERR$&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
OPEN #(H := 21): &amp;quot;DATABASE=DemoConn&amp;quot;, SQL C_SQL$, OUTIN ERROR SQL_ERR&lt;br /&gt;
WRITE #H: ERROR SQL_ERR&lt;br /&gt;
&lt;br /&gt;
RD: READ #H, USING &#039;FORM POS 1,C 50&#039;: C1$ EOF DONE ERROR SQL_ERR&lt;br /&gt;
    PRINT C1$&lt;br /&gt;
    GOTO RD&lt;br /&gt;
&lt;br /&gt;
DONE:&lt;br /&gt;
    CLOSE #H:&lt;br /&gt;
    STOP&lt;br /&gt;
&lt;br /&gt;
SQL_ERR:&lt;br /&gt;
    PRINT &amp;quot;Error:&amp;quot;; ERR; &amp;quot; Line:&amp;quot;; LINE; &amp;quot; Syserr:&amp;quot;; SYSERR$&lt;br /&gt;
    STOP&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common SQL / ODBC Error Codes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Code&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Meaning&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;3006 / 4006&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL execute-direct failed.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;3007 / 4007&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; used with the incorrect number of data elements. Usually a parameter mismatch.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;3010 / 4010&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL fetch-row failed.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;3011 / 4011&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL bind-parameter failure.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;4015&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;The specified database has not been opened.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;4270&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;EOF on &amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt;. This is normal end-of-result-set behavior when an &amp;lt;code&amp;gt;EOF&amp;lt;/code&amp;gt; clause is not used.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First checks when a connection or query fails:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the ODBC driver name.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the server name or IP address.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the database name.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm credentials.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm network/firewall access.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the ODBC driver is installed on the machine running BR.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If using &amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt;, confirm BR is not running in Client/Server mode.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== STATUS.DATABASE Introspection ==&lt;br /&gt;
&lt;br /&gt;
After opening a channel against a connection, BR exposes metadata through &amp;lt;code&amp;gt;STATUS.DATABASE&amp;lt;/code&amp;gt; environment variables.&lt;br /&gt;
&lt;br /&gt;
=== Resolved Connection String ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRINT Env$(&amp;quot;STATUS.DATABASE.[DEMOCONN].CONNECTSTRING&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== List Tables ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET Env$(&amp;quot;STATUS.DATABASE.[DEMOCONN].TABLES.LIST&amp;quot;, MAT TABLES$)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== List Columns ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET Env$(&amp;quot;STATUS.DATABASE.[DEMOCONN].TABLES.[CUSTOMERS].COLUMNS.LIST&amp;quot;, MAT COLS$)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Column Metadata ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRINT Env$(&amp;quot;STATUS.DATABASE.[DEMOCONN].TABLES.[CUSTOMERS].COLUMNS.[EMAIL].TYPE&amp;quot;)&lt;br /&gt;
PRINT Env$(&amp;quot;STATUS.DATABASE.[DEMOCONN].TABLES.[CUSTOMERS].COLUMNS.[EMAIL].LENGTH&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Connection names in &amp;lt;code&amp;gt;STATUS.DATABASE&amp;lt;/code&amp;gt; paths are uppercased by BR.&lt;br /&gt;
&lt;br /&gt;
== Production-Style Usage Pattern ==&lt;br /&gt;
&lt;br /&gt;
The same ODBC pattern can be used in larger production routines that synchronize BR data files with SQL Server tables.&lt;br /&gt;
&lt;br /&gt;
A production routine commonly performs these tasks:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Configure named SQL connections.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Discover SQL table structure.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Read SQL rows through BR channels.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Compare SQL rows against BR file records.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Perform inserts, updates, and deletes.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Page through large SQL tables.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Reuse and clear named connections.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example Setup Pattern ==&lt;br /&gt;
&lt;br /&gt;
A program may load supporting routines and configure a default SQL connection from environment variables.  These examples and environment are not part of the Business Rules language, rather suggestoins that may be usefull.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY &amp;quot;SQL/Library&amp;quot;: Fnopen_Sql_File&lt;br /&gt;
LIBRARY &amp;quot;Util/Library&amp;quot;: Fngethandle, Fnget_Form&lt;br /&gt;
&lt;br /&gt;
LET Fn_Config_Sql(&amp;quot;SetUpConn&amp;quot;, Env$(&amp;quot;SQL-SYNC-SERVER&amp;quot;), Env$(&amp;quot;SQL-SYNC-DATABASE&amp;quot;))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Common environment variables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Variable&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Purpose&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;SQL-SYNC-SERVER&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server host name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;SQL-SYNC-DATABASE&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Target SQL Server database.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;SQL-SYNC-CONNECTION&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Optional override connection string. May support a &amp;lt;code&amp;gt;[LOGIN_NAME]&amp;lt;/code&amp;gt; placeholder.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;SQL-SYNC-DRIVER&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Optional ODBC driver name. Defaults to &amp;lt;code&amp;gt;SQL Server&amp;lt;/code&amp;gt;.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Connection Helper Pattern ==&lt;br /&gt;
&lt;br /&gt;
A helper routine can wrap &amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt; and cache connections so each named reference is configured only once per session.&lt;br /&gt;
&lt;br /&gt;
Typical parameters:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Parameter&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Purpose&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Cs_Connection$&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Arbitrary database reference name, such as &amp;lt;code&amp;gt;C_SelectCon&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;C_InsertCon&amp;lt;/code&amp;gt;.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Cs_Server$&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server host name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Cs_Database$&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server database name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Cs_User$&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL login. Often defaults to &amp;lt;code&amp;gt;LOGIN_NAME$&amp;lt;/code&amp;gt;.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Password$&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL password. Often defaults to &amp;lt;code&amp;gt;BR_PASSWORD&amp;lt;/code&amp;gt; for Windows authentication.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Cs_Sql_Authentication&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Indicates SQL authentication mode.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Cs_Driver$&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;ODBC driver name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example pattern:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DEF Fn_Config_Sql(Cs_Connection$*256, Cs_Server$*256, Cs_Database$*256;&lt;br /&gt;
                  Cs_User$*256, Password$*256, Cs_Sql_Authentication, Cs_Driver$*256)&lt;br /&gt;
&lt;br /&gt;
    EXECUTE &#039;CONFIG DATABASE &#039; &amp;amp; Cs_Connection$ &amp;amp;&lt;br /&gt;
            &#039; CONNECTSTRING=&amp;quot;&#039; &amp;amp; Connectionstring$ &amp;amp; &#039;&amp;quot;&#039; ERROR CONNECT_ERROR&lt;br /&gt;
&lt;br /&gt;
FNEND&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Separate Connections for Separate Workloads ==&lt;br /&gt;
&lt;br /&gt;
Larger routines commonly use separate named connections so concurrent SQL channels do not collide.  Technically you can perform everything through a single connection. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Connection Name&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Typical Use&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;C_SelectCon&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SELECT queries and schema discovery.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;C_InsertCon&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;INSERT operations.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;C_UpdateCon&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;UPDATE operations.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;C_DeleteCon&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;DELETE operations.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;C_RetryCon&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Retry path after transient SQL errors.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;SetUpConn&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Folder/setup stored procedures.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET Sconn$ = &amp;quot;C_SelectCon&amp;quot;&lt;br /&gt;
LET Insconn$ = &amp;quot;C_InsertCon&amp;quot;&lt;br /&gt;
LET Delconn$ = &amp;quot;C_DeleteCon&amp;quot;&lt;br /&gt;
&lt;br /&gt;
LET Fn_Config_Sql(Sconn$, Bc_Server$, Bc_Database$, Bc_User$, Bc_Password$)&lt;br /&gt;
LET Fn_Config_Sql(Insconn$, Bc_Server$, Bc_Database$, Bc_User$, Bc_Password$)&lt;br /&gt;
LET Fn_Config_Sql(Delconn$, Bc_Server$, Bc_Database$, Bc_User$, Bc_Password$)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discovering SQL Table Structure ==&lt;br /&gt;
&lt;br /&gt;
A program can discover SQL columns by opening a &amp;lt;code&amp;gt;SELECT TOP 1 *&amp;lt;/code&amp;gt; channel and reading metadata from &amp;lt;code&amp;gt;STATUS.DATABASE&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET Qry_Ispent_Design$ = &amp;quot;SELECT TOP 1 * FROM &amp;quot; &amp;amp; Gsf_Object$&lt;br /&gt;
&lt;br /&gt;
OPEN #(Db_Handle_Design := Fngethandle): &amp;quot;DATABASE=&amp;quot; &amp;amp; Gsf_Connection$, SQL Qry_Ispent_Design$, OUTIN&lt;br /&gt;
&lt;br /&gt;
LET Env$(&amp;quot;STATUS.DATABASE.[&amp;quot; &amp;amp; Trim$(Uprc$(Gsf_Connection$)) &amp;amp;&lt;br /&gt;
       &amp;quot;].TABLES.[&amp;quot; &amp;amp; Trim$(Uprc$(Gsf_Object$)) &amp;amp; &amp;quot;].COLUMNS&amp;quot;, MAT Columns$)&lt;br /&gt;
&lt;br /&gt;
CLOSE #Db_Handle_Design:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The resulting metadata can be used to classify columns as character, date, or numeric and to build the appropriate BR &amp;lt;code&amp;gt;FORM&amp;lt;/code&amp;gt; definitions.&lt;br /&gt;
&lt;br /&gt;
== Incremental Processing Pattern ==&lt;br /&gt;
&lt;br /&gt;
Large SQL tables should usually be processed in batches rather than loaded all at once.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
! Build the SELECT&lt;br /&gt;
LET Qry_Select$ = &amp;quot;SELECT TOP 100000 col1, col2 FROM [dbo].[MYTABLE] WITH (NOLOCK)&amp;quot; &amp;amp;&lt;br /&gt;
                  &amp;quot; WHERE Folder_Number = &amp;quot; &amp;amp; Folder_Number$ &amp;amp;&lt;br /&gt;
                  &amp;quot; ORDER BY Record_Number ASC&amp;quot;&lt;br /&gt;
&lt;br /&gt;
! Save SQL for debugging&lt;br /&gt;
LET Setenv(&amp;quot;ER_Last_SQL&amp;quot;, Qry_Select$)&lt;br /&gt;
&lt;br /&gt;
! Open and execute&lt;br /&gt;
OPEN #(Selhandle := 20): &amp;quot;DATABASE=C_SelectCon&amp;quot;, SQL Qry_Select$, OUTIN&lt;br /&gt;
WRITE #Selhandle:&lt;br /&gt;
&lt;br /&gt;
! Read rows&lt;br /&gt;
READ #Selhandle: MAT Sql_Object_Data$, MAT Sql_Object_Data_Dates$, MAT Sql_Object_Data EOF SQL_EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the batch is exhausted, close the channel, build a new &amp;lt;code&amp;gt;SELECT TOP ... WHERE Record_Number &amp;gt; &amp;lt;last&amp;gt;&amp;lt;/code&amp;gt; query, and open a fresh channel.&lt;br /&gt;
&lt;br /&gt;
== DML Pattern: INSERT / UPDATE / DELETE ==&lt;br /&gt;
&lt;br /&gt;
Data-changing SQL follows the same &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;CLOSE&amp;lt;/code&amp;gt; pattern.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET Setenv(&amp;quot;ER_Last_SQL&amp;quot;, Insert_Sql$)&lt;br /&gt;
&lt;br /&gt;
OPEN #(Inshandle := Fngethandle): &amp;quot;DATABASE=C_InsertCon&amp;quot;, SQL Insert_Sql$, OUTIN&lt;br /&gt;
WRITE #Inshandle: ERROR SQL_ERROR&lt;br /&gt;
CLOSE #Inshandle:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Closing Named Connections ==&lt;br /&gt;
&lt;br /&gt;
At the end of a SQL operation, close or clear configured connections.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET Fn_Close_Db_Connections(Sconn$)&lt;br /&gt;
LET Fn_Close_Db_Connections(Insconn$)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or clear all configured database connections:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXECUTE &amp;quot;CONFIG DATABASE CLEAR ALL&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example Helper Entry Points ==&lt;br /&gt;
&lt;br /&gt;
A larger BR SQL integration may include helper routines similar to the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Function&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Purpose&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Config_Sql&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Establishes a named ODBC connection.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Get_Sql_Fields&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Discovers SQL table or view column layout.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fnshow_Database&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Prints connection, table, and column metadata.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Bulk_Insert&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Copies BR records to SQL in a full load.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Incremental_Sync&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Compares and reconciles BR rows against SQL rows.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Create_Table&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Creates SQL tables.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Alter_Table&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Alters SQL table structure.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Truncate_Table&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Clears a SQL table.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Close_Db_Connections&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Releases configured SQL connections.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example Usage from a Program ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY &amp;quot;SQL/Library&amp;quot;: Fnopen_Sql_File&lt;br /&gt;
LIBRARY &amp;quot;util/Library&amp;quot;: Fngethandle, Fnget_Form&lt;br /&gt;
&lt;br /&gt;
LET Fn_Config_Sql(&amp;quot;MyConn&amp;quot;, &amp;quot;VT-SQL01&amp;quot;, &amp;quot;MyDatabase&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
LET Fn_Get_Sql_Fields(&amp;quot;MyConn&amp;quot;, &amp;quot;CUSTOMERS&amp;quot;, MAT Data$, MAT Dates$, MAT Data)&lt;br /&gt;
&lt;br /&gt;
! Program logic here&lt;br /&gt;
&lt;br /&gt;
LET Fn_Close_Db_Connections(&amp;quot;MyConn&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Security Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Protect source files and saved connection strings. Literal credentials inside connection strings are visible to anyone who can read the program or configuration.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Prefer &amp;lt;code&amp;gt;PASSWORDD=&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;BR_PASSWORD&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;LOGIN_NAME&amp;lt;/code&amp;gt;, or runtime prompts over literal passwords.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Prefer parameterized statements using &amp;lt;code&amp;gt;WRITE #h: value1, value2&amp;lt;/code&amp;gt; over string concatenation of user input.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Avoid placing both &amp;lt;code&amp;gt;UID/PWD&amp;lt;/code&amp;gt; inside the connection string and &amp;lt;code&amp;gt;USER/PASSWORD&amp;lt;/code&amp;gt; outside the connection string.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Do not use &amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt; in Client/Server mode.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;When practical, log the last SQL statement to an environment variable such as &amp;lt;code&amp;gt;ER_Last_SQL&amp;lt;/code&amp;gt; for troubleshooting.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Always close SQL channels after use.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting Checklist ==&lt;br /&gt;
&lt;br /&gt;
When a database connection fails:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the ODBC driver is installed on the machine running BR.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the driver name matches the connection string.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the SQL Server, MySQL, SQLite, or Access target is reachable.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm credentials.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the database name.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm firewall and network access.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the connection works in the Windows ODBC manager.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If using Windows authentication, confirm the BR process is running under the expected user context.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If using Client/Server mode, avoid &amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Print &amp;lt;code&amp;gt;SYSERR$&amp;lt;/code&amp;gt; for the driver-specific error message.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When a query fails:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Print or log the SQL statement.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm table and column names.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm quoting of strings and dates.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the number of parameter markers matches the number of values supplied to &amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the &amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt; form matches the selected columns.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm character fields are wide enough.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use &amp;lt;code&amp;gt;STATUS.DATABASE&amp;lt;/code&amp;gt; metadata to inspect table and column definitions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[CONFIG]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[EXECUTE]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[OPEN]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[WRITE]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[READ]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[CLOSE]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Encrypted passwords]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Unhex]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Decrypt]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:All Parameters]]&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=DATABASE&amp;diff=11515</id>
		<title>DATABASE</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=DATABASE&amp;diff=11515"/>
		<updated>2026-07-09T13:44:36Z</updated>

		<summary type="html">&lt;p&gt;GomezL: /* Example Setup Pattern */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= DATABASE =&lt;br /&gt;
&lt;br /&gt;
Starting in &#039;&#039;&#039;Business Rules! 4.3&#039;&#039;&#039;, the &amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt; directive allows a BR program to connect to external SQL databases through ODBC.&lt;br /&gt;
&lt;br /&gt;
This page covers BR acting as an &#039;&#039;&#039;ODBC SQL client&#039;&#039;&#039; — connecting outward to SQL Server, MySQL, SQLite, Microsoft Access, and other relational databases, executing SQL statements, and reading result rows.&lt;br /&gt;
&lt;br /&gt;
BR treats a live SQL statement as an ordinary I/O channel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt; names the connection.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt; binds a BR file channel to a SQL statement.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; executes the SQL statement.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt; fetches rows for a &amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;CLOSE&amp;lt;/code&amp;gt; releases the statement/result set.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; This is different from the BR ODBC driver that exposes BR data files to Excel, Access, reporting tools, or other external consumers.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Step&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Statement&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Purpose&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;1. Configure connection&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;CONFIG DATABASE &amp;amp;lt;db-ref&amp;amp;gt; ...&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Names a data source and tells BR how to connect to it.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;2. Open SQL channel&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;OPEN #h: &amp;quot;DATABASE=&amp;amp;lt;db-ref&amp;amp;gt;&amp;quot;, SQL sql$, OUTIN&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Binds a BR channel to one SQL statement over the named connection.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;3. Execute SQL&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;WRITE #h:&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Executes the bound SQL statement.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;4. Fetch rows&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;READ #h, USING ...&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Reads result rows from a &amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt;.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;5. Close channel&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;CLOSE #h:&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Releases the SQL statement/result set.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;&amp;lt;db-ref&amp;gt;&amp;lt;/code&amp;gt; is the connection name. The same name used in &amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt; is referenced later in &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;&amp;quot;DATABASE=&amp;lt;db-ref&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXECUTE &#039;CONFIG DATABASE DemoConn CONNECTSTRING=&amp;quot;DRIVER=SQL Server;SERVER=myserver;Initial Catalog=mydb;UID=myuser;PWD=mypass&amp;quot;&#039;&lt;br /&gt;
&lt;br /&gt;
LET C_SQL$ = &amp;quot;SELECT FirstName, LastName FROM dbo.Customers&amp;quot;&lt;br /&gt;
&lt;br /&gt;
OPEN #(H := 21): &amp;quot;DATABASE=DemoConn&amp;quot;, SQL C_SQL$, OUTIN&lt;br /&gt;
WRITE #H:&lt;br /&gt;
&lt;br /&gt;
RD: READ #H, USING &#039;FORM POS 1,C 50,C 50&#039;: FIRST$, LAST$ EOF DONE&lt;br /&gt;
    PRINT TRIM$(FIRST$); &amp;quot; &amp;quot;; TRIM$(LAST$)&lt;br /&gt;
    GOTO RD&lt;br /&gt;
&lt;br /&gt;
DONE: CLOSE #H:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CONFIG DATABASE ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt; defines a named ODBC connection.&lt;br /&gt;
&lt;br /&gt;
It may be placed in &amp;lt;code&amp;gt;BRConfig.sys&amp;lt;/code&amp;gt; or issued from inside a program using &amp;lt;code&amp;gt;EXECUTE&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Connection Methods ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt; supports three connection methods:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;DSN&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;CONNECTSTRING&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== General Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG DATABASE &amp;lt;db-ref&amp;gt; { DSN=&amp;lt;dsn-ref&amp;gt;&lt;br /&gt;
                         | CONNECTSTRING=&amp;quot;&amp;lt;odbc-connection-string&amp;gt;&amp;quot;&lt;br /&gt;
                         | ODBC-MANAGER }&lt;br /&gt;
                         [ , USER= { &amp;lt;department&amp;gt; | LOGIN_NAME | ? } ]&lt;br /&gt;
                         [ , { PASSWORD= { &amp;lt;dept-password&amp;gt; | BR_PASSWORD | ? }&lt;br /&gt;
                             | PASSWORDD=&amp;lt;encrypted-password&amp;gt; } ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Option&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Meaning&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;&amp;amp;lt;db-ref&amp;amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Arbitrary BR database reference name. This is the name used later in &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt;.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;DSN=&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Uses a pre-configured Windows ODBC Data Source Name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;CONNECTSTRING=&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Uses a DSN-less ODBC connection string.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Displays the Windows ODBC manager so the user can select the data source.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;USER=?&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Prompts the operator for the user name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;PASSWORD=?&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Prompts the operator for the password.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;USER=LOGIN_NAME&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Uses the current BR login / Active Directory user name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;PASSWORD=BR_PASSWORD&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Uses the current BR login / Active Directory password.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;PASSWORDD=&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Supplies an encrypted password as a hexadecimal value.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DSN ==&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;DSN&amp;lt;/code&amp;gt; when the ODBC Data Source Name has already been configured in the Windows ODBC manager.&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG DATABASE &amp;lt;db-ref&amp;gt; DSN=&amp;lt;dsn-ref&amp;gt;&lt;br /&gt;
    [, USER=&amp;lt;department&amp;gt; | LOGIN_NAME | ?]&lt;br /&gt;
    [, PASSWORD=&amp;lt;dept-password&amp;gt; | BR_PASSWORD | ? | PASSWORDD=&amp;lt;encrypted-password&amp;gt;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXECUTE &#039;CONFIG DATABASE CLS_Data DSN=&amp;quot;MyData&amp;quot;, PASSWORDD=&amp;lt;encrypted-password&amp;gt;&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Encrypted passwords are expressed as hexadecimal values. BR unhexes and decrypts the value before presenting it to the SQL driver.&lt;br /&gt;
&lt;br /&gt;
== CONNECTSTRING / DSN-less Connections ==&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;CONNECTSTRING&amp;lt;/code&amp;gt; when the full ODBC connection string should be supplied directly.&lt;br /&gt;
&lt;br /&gt;
This is usually the most portable option for deployed applications because it avoids requiring a pre-created DSN on each workstation or server.&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG DATABASE &amp;lt;db-ref&amp;gt; CONNECTSTRING=&amp;quot;&amp;lt;odbc-connection-string&amp;gt;&amp;quot;&lt;br /&gt;
    [, USER=&amp;lt;department&amp;gt; | LOGIN_NAME | ?]&lt;br /&gt;
    [, PASSWORD=&amp;lt;dept-password&amp;gt; | BR_PASSWORD | ? | PASSWORDD=&amp;lt;encrypted-password&amp;gt;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SQL Server with SQL Login ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG DATABASE db-ref CONNECTSTRING=&amp;quot;DRIVER=SQL Server;SERVER=server;Initial Catalog=database;UID=username;PWD=password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Value&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Meaning&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;db-ref&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;BR database reference name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;server&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server FQDN, host name, or IP address.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;database&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server database name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;username&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server login.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;password&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server password.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SQL Server with Windows Authentication ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG DATABASE db-ref CONNECTSTRING=&amp;quot;DRIVER=SQL Server;Initial Catalog=database;SERVER=server&amp;quot; USER=LOGIN_NAME PASSWORD=BR_PASSWORD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When &amp;lt;code&amp;gt;USER=&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;PASSWORD=&amp;lt;/code&amp;gt; are specified outside the quoted connection string, BR augments the ODBC connection string with &amp;lt;code&amp;gt;UID=&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;PWD=&amp;lt;/code&amp;gt; values.&lt;br /&gt;
&lt;br /&gt;
Do not also place &amp;lt;code&amp;gt;UID&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;PWD&amp;lt;/code&amp;gt; inside the connection string itself when using BR&#039;s &amp;lt;code&amp;gt;USER=&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;PASSWORD=&amp;lt;/code&amp;gt; parameters.&lt;br /&gt;
&lt;br /&gt;
=== Other Sample Connection Strings ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Target&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Example&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server, SQL login&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;DRIVER=SQL Server;SERVER=myserver;Initial Catalog=mydb;UID=myuser;PWD=mypass&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server, Windows authentication&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;DRIVER=SQL Server;SERVER=myserver;Initial Catalog=mydb&amp;lt;/code&amp;gt; with &amp;lt;code&amp;gt;USER=LOGIN_NAME PASSWORD=BR_PASSWORD&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;MySQL&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;DSN=BRG_DEMO;SERVER=127.0.0.1;UID=dbadmin;PWD=mypass;DATABASE=brg_demo;PORT=3306&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQLite&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;DSN=SQLite3 Datasource;Database=C:\demo\brg_demo.sqlite;SyncPragma=NORMAL;Timeout=100000&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Microsoft Access&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Driver={Microsoft Access Driver (*.mdb)};DBQ=C:\path\Contact.mdb&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ODBC-MANAGER ==&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt; to display the Windows ODBC manager and allow the user to select the data source at runtime.&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG DATABASE &amp;lt;db-ref&amp;gt; ODBC-MANAGER&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Important Client/Server Note ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt; does &#039;&#039;&#039;not&#039;&#039;&#039; work in Client/Server mode because the ODBC selection occurs on the server, not on the user&#039;s workstation.&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00010 PRINT NEWPAGE&lt;br /&gt;
00020 IF Env$(&amp;quot;br_model&amp;quot;) = &amp;quot;CLIENT_SERVER&amp;quot; THEN PRINT &amp;quot;Warning, you cannot connect to ODBC-MANAGER in Client/Server mode&amp;quot;&lt;br /&gt;
00030 EXECUTE &amp;quot;CONFIG DATABASE Test_DB ODBC-MANAGER&amp;quot; ERROR CONNECT_ERROR&lt;br /&gt;
00040 PRINT &amp;quot;Connection String is:&amp;quot; !:&lt;br /&gt;
00050 PRINT Env$(&amp;quot;STATUS.DATABASE.[TEST_DB].CONNECTSTRING&amp;quot;)&lt;br /&gt;
00060 STOP&lt;br /&gt;
00100 CONNECT_ERROR:&lt;br /&gt;
00110 PRINT &amp;quot;Error Connecting - Err:&amp;quot;; Err; &amp;quot; Line:&amp;quot;; Line; &amp;quot; Syserr:&amp;quot;; Syserr$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Viewing the Resolved Connection String ==&lt;br /&gt;
&lt;br /&gt;
After a connection is configured, BR exposes the effective connection string through &amp;lt;code&amp;gt;Env$&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRINT Env$(&amp;quot;STATUS.DATABASE.[MyConn].CONNECTSTRING&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Connection names in &amp;lt;code&amp;gt;STATUS.DATABASE&amp;lt;/code&amp;gt; paths are generally uppercased by BR. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRINT Env$(&amp;quot;STATUS.DATABASE.[DEMOCONN].CONNECTSTRING&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== OPENing a SQL Statement ==&lt;br /&gt;
&lt;br /&gt;
After the database connection is configured, use &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt; to bind a BR channel to a SQL statement.&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
OPEN #&amp;lt;channel&amp;gt;: &amp;quot;DATABASE=&amp;lt;db-ref&amp;gt;&amp;quot;, SQL &amp;lt;string-expression&amp;gt;, OUTIN&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Clause&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Meaning&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;#&amp;amp;lt;channel&amp;amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;BR file channel number.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;&amp;quot;DATABASE=&amp;amp;lt;db-ref&amp;amp;gt;&amp;quot;&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Refers to the connection previously configured with &amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt;.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;SQL &amp;amp;lt;string-expression&amp;amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL text to bind to the channel.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;OUTIN&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Opens the channel for output and input. Used for both executing and reading.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DIM C_SQL$*4096&lt;br /&gt;
&lt;br /&gt;
LET C_SQL$ = &amp;quot;SELECT FirstName, LastName, Email FROM dbo.Customers ORDER BY LastName&amp;quot;&lt;br /&gt;
&lt;br /&gt;
OPEN #(DB_HANDLE := 21): &amp;quot;DATABASE=DemoConn&amp;quot;, SQL C_SQL$, OUTIN&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The SQL statement is bound at &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt; time. To run a different SQL statement, build a new SQL string and open a new channel.&lt;br /&gt;
&lt;br /&gt;
== Opening SQL from an External File ==&lt;br /&gt;
&lt;br /&gt;
A channel may also use SQL text stored in an external file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
OPEN #H: &amp;quot;DATABASE=MyConn,NAME=Setup_Tables.sql/MyFolder&amp;quot;, SQL, OUTIN&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Executing SQL with WRITE ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; with no data list executes the SQL statement bound during &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
WRITE #DB_HANDLE:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For a &amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; executes the query and prepares the result set. It must be called before the first &amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For &amp;lt;code&amp;gt;INSERT&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;UPDATE&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;DELETE&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; performs the change. No &amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt; follows unless the SQL statement returns rows.&lt;br /&gt;
&lt;br /&gt;
== Parameterized Statements ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; with a data list binds values to parameter markers in the prepared SQL statement.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET C_SQL$ = &amp;quot;INSERT INTO dbo.Customers (FirstName, LastName) VALUES (?, ?)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
OPEN #(H := 21): &amp;quot;DATABASE=DemoConn&amp;quot;, SQL C_SQL$, OUTIN&lt;br /&gt;
WRITE #H: FIRST$, LAST$&lt;br /&gt;
CLOSE #H:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use parameter binding instead of concatenating operator input into SQL strings whenever possible. It avoids quoting errors and reduces SQL injection risk.&lt;br /&gt;
&lt;br /&gt;
== Reading Result Rows ==&lt;br /&gt;
&lt;br /&gt;
Each &amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt; fetches one result row.&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
READ #&amp;lt;channel&amp;gt;, USING &#039;&amp;lt;form-spec&amp;gt;&#039;: &amp;lt;var&amp;gt; [, &amp;lt;var&amp;gt;]* EOF &amp;lt;line-ref&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RD: READ #DB_HANDLE, USING &#039;FORM POS 1,C 50,C 50&#039;: C1$, C2$ EOF DONE&lt;br /&gt;
    PRINT TRIM$(C1$); &amp;quot;,&amp;quot;; TRIM$(C2$)&lt;br /&gt;
    GOTO RD&lt;br /&gt;
&lt;br /&gt;
DONE: CLOSE #DB_HANDLE:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Columns in the SQL &amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt; list map left-to-right onto the variables in the &amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The &amp;lt;code&amp;gt;FORM&amp;lt;/code&amp;gt; must match the expected data layout.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Size character fields generously, for example &amp;lt;code&amp;gt;C 50&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;C 100&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use numeric, date, packed decimal, and other BR &amp;lt;code&amp;gt;FORM&amp;lt;/code&amp;gt; types as appropriate.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;EOF&amp;lt;/code&amp;gt; fires when the result set is exhausted.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;For many columns, arrays and composite forms are usually easier than long lists of individual variables.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Closing SQL Channels ==&lt;br /&gt;
&lt;br /&gt;
Always close SQL channels when done.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CLOSE #DB_HANDLE:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This releases the channel and the associated SQL statement/result set.&lt;br /&gt;
&lt;br /&gt;
This is especially important in loops that repeatedly open SQL statements.&lt;br /&gt;
&lt;br /&gt;
== Clearing Configured Connections ==&lt;br /&gt;
&lt;br /&gt;
To clear one named connection:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXECUTE &amp;quot;CONFIG DATABASE CLEAR MyConn&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To clear all configured database connections:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXECUTE &amp;quot;CONFIG DATABASE CLEAR ALL&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Complete SELECT Example ==&lt;br /&gt;
&lt;br /&gt;
The following example connects to SQL Server, executes a &amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt;, reads the rows, and prints the result.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00010 ! ============================================================&lt;br /&gt;
00020 ! Sample: Connect to SQL Server, SELECT rows, print results&lt;br /&gt;
00030 ! ============================================================&lt;br /&gt;
00040 PRINT NEWPAGE&lt;br /&gt;
00050 DIM C_SQL$*4096&lt;br /&gt;
00060 DIM FIRST$*50, LAST$*50, EMAIL$*100&lt;br /&gt;
00070 DIM DB_HANDLE&lt;br /&gt;
00080 !&lt;br /&gt;
00090 ! --- Step 1: Create the connection ---&lt;br /&gt;
00100 EXECUTE &#039;CONFIG DATABASE DemoConn CONNECTSTRING=&amp;quot;DRIVER=SQL Server;SERVER=myserver;Initial Catalog=mydb;UID=myuser;PWD=mypass&amp;quot;&#039; ERROR CONNECT_ERR&lt;br /&gt;
00110 !&lt;br /&gt;
00120 ! --- Step 2: Define the SQL statement and open a channel ---&lt;br /&gt;
00130 LET C_SQL$ = &amp;quot;SELECT FirstName, LastName, Email FROM dbo.Customers ORDER BY LastName&amp;quot;&lt;br /&gt;
00140 OPEN #(DB_HANDLE := 21): &amp;quot;DATABASE=DemoConn&amp;quot;, SQL C_SQL$, OUTIN ERROR OPEN_ERR&lt;br /&gt;
00150 !&lt;br /&gt;
00160 ! --- Step 3: Execute the query ---&lt;br /&gt;
00170 WRITE #DB_HANDLE: ERROR EXEC_ERR&lt;br /&gt;
00180 !&lt;br /&gt;
00190 ! --- Step 4: Loop through result rows ---&lt;br /&gt;
00200 RD: READ #DB_HANDLE, USING &#039;FORM POS 1,C 50,C 50,C 100&#039;: FIRST$, LAST$, EMAIL$ EOF DONE&lt;br /&gt;
00210     PRINT TRIM$(LAST$); &amp;quot;, &amp;quot;; TRIM$(FIRST$); &amp;quot;  &amp;lt;&amp;quot;; TRIM$(EMAIL$); &amp;quot;&amp;gt;&amp;quot;&lt;br /&gt;
00220     GOTO RD&lt;br /&gt;
00230 !&lt;br /&gt;
00240 DONE:&lt;br /&gt;
00250 CLOSE #DB_HANDLE:&lt;br /&gt;
00260 PRINT &amp;quot;Finished.&amp;quot;&lt;br /&gt;
00270 STOP&lt;br /&gt;
00280 !&lt;br /&gt;
00290 CONNECT_ERR:&lt;br /&gt;
00300 OPEN_ERR:&lt;br /&gt;
00310 EXEC_ERR:&lt;br /&gt;
00320     PRINT &amp;quot;Error:&amp;quot;; ERR; &amp;quot; Line:&amp;quot;; LINE; &amp;quot; Syserr:&amp;quot;; SYSERR$&lt;br /&gt;
00330     STOP&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Windows Authentication Example ==&lt;br /&gt;
&lt;br /&gt;
For SQL Server integrated security, omit credentials from the quoted connection string and allow BR to supply them.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXECUTE &#039;CONFIG DATABASE DemoConn CONNECTSTRING=&amp;quot;DRIVER=SQL Server;Initial Catalog=mydb;SERVER=myserver&amp;quot; USER=LOGIN_NAME PASSWORD=BR_PASSWORD&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INSERT Example ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET C_SQL$ = &amp;quot;INSERT INTO dbo.Customers (FirstName, LastName) VALUES (&#039;Jane&#039;, &#039;Doe&#039;)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
OPEN #(DB_HANDLE := 21): &amp;quot;DATABASE=DemoConn&amp;quot;, SQL C_SQL$, OUTIN&lt;br /&gt;
WRITE #DB_HANDLE:&lt;br /&gt;
CLOSE #DB_HANDLE:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside a BR string, two double-quotes represent one literal double-quote.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET C_SQL$ = &amp;quot;INSERT INTO dbo.Customers (FirstName, LastName) VALUES (&amp;quot;&amp;quot;Jane&amp;quot;&amp;quot;, &amp;quot;&amp;quot;Doe&amp;quot;&amp;quot;)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Error Handling ==&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt; clauses or &amp;lt;code&amp;gt;ON ERROR&amp;lt;/code&amp;gt; to trap connection, execution, and fetch failures.&lt;br /&gt;
&lt;br /&gt;
Report:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;ERR&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;LINE&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;SYSERR$&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
OPEN #(H := 21): &amp;quot;DATABASE=DemoConn&amp;quot;, SQL C_SQL$, OUTIN ERROR SQL_ERR&lt;br /&gt;
WRITE #H: ERROR SQL_ERR&lt;br /&gt;
&lt;br /&gt;
RD: READ #H, USING &#039;FORM POS 1,C 50&#039;: C1$ EOF DONE ERROR SQL_ERR&lt;br /&gt;
    PRINT C1$&lt;br /&gt;
    GOTO RD&lt;br /&gt;
&lt;br /&gt;
DONE:&lt;br /&gt;
    CLOSE #H:&lt;br /&gt;
    STOP&lt;br /&gt;
&lt;br /&gt;
SQL_ERR:&lt;br /&gt;
    PRINT &amp;quot;Error:&amp;quot;; ERR; &amp;quot; Line:&amp;quot;; LINE; &amp;quot; Syserr:&amp;quot;; SYSERR$&lt;br /&gt;
    STOP&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common SQL / ODBC Error Codes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Code&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Meaning&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;3006 / 4006&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL execute-direct failed.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;3007 / 4007&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; used with the incorrect number of data elements. Usually a parameter mismatch.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;3010 / 4010&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL fetch-row failed.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;3011 / 4011&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL bind-parameter failure.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;4015&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;The specified database has not been opened.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;4270&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;EOF on &amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt;. This is normal end-of-result-set behavior when an &amp;lt;code&amp;gt;EOF&amp;lt;/code&amp;gt; clause is not used.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First checks when a connection or query fails:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the ODBC driver name.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the server name or IP address.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the database name.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm credentials.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm network/firewall access.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the ODBC driver is installed on the machine running BR.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If using &amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt;, confirm BR is not running in Client/Server mode.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== STATUS.DATABASE Introspection ==&lt;br /&gt;
&lt;br /&gt;
After opening a channel against a connection, BR exposes metadata through &amp;lt;code&amp;gt;STATUS.DATABASE&amp;lt;/code&amp;gt; environment variables.&lt;br /&gt;
&lt;br /&gt;
=== Resolved Connection String ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRINT Env$(&amp;quot;STATUS.DATABASE.[DEMOCONN].CONNECTSTRING&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== List Tables ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET Env$(&amp;quot;STATUS.DATABASE.[DEMOCONN].TABLES.LIST&amp;quot;, MAT TABLES$)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== List Columns ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET Env$(&amp;quot;STATUS.DATABASE.[DEMOCONN].TABLES.[CUSTOMERS].COLUMNS.LIST&amp;quot;, MAT COLS$)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Column Metadata ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRINT Env$(&amp;quot;STATUS.DATABASE.[DEMOCONN].TABLES.[CUSTOMERS].COLUMNS.[EMAIL].TYPE&amp;quot;)&lt;br /&gt;
PRINT Env$(&amp;quot;STATUS.DATABASE.[DEMOCONN].TABLES.[CUSTOMERS].COLUMNS.[EMAIL].LENGTH&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Connection names in &amp;lt;code&amp;gt;STATUS.DATABASE&amp;lt;/code&amp;gt; paths are uppercased by BR.&lt;br /&gt;
&lt;br /&gt;
== Production-Style Usage Pattern ==&lt;br /&gt;
&lt;br /&gt;
The same ODBC pattern can be used in larger production routines that synchronize BR data files with SQL Server tables.&lt;br /&gt;
&lt;br /&gt;
A production routine commonly performs these tasks:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Configure named SQL connections.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Discover SQL table structure.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Read SQL rows through BR channels.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Compare SQL rows against BR file records.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Perform inserts, updates, and deletes.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Page through large SQL tables.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Reuse and clear named connections.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example Setup Pattern ==&lt;br /&gt;
&lt;br /&gt;
A program may load supporting routines and configure a default SQL connection from environment variables.  These examples and environment are not part of the Business Rules language, rather suggestoins that may be usefull.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY &amp;quot;SQL/Library&amp;quot;: Fnopen_Sql_File&lt;br /&gt;
LIBRARY &amp;quot;Util/Library&amp;quot;: Fngethandle, Fnget_Form&lt;br /&gt;
&lt;br /&gt;
LET Fn_Config_Sql(&amp;quot;SetUpConn&amp;quot;, Env$(&amp;quot;SQL-SYNC-SERVER&amp;quot;), Env$(&amp;quot;SQL-SYNC-DATABASE&amp;quot;))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Common environment variables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Variable&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Purpose&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;SQL-SYNC-SERVER&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server host name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;SQL-SYNC-DATABASE&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Target SQL Server database.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;SQL-SYNC-CONNECTION&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Optional override connection string. May support a &amp;lt;code&amp;gt;[LOGIN_NAME]&amp;lt;/code&amp;gt; placeholder.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;SQL-SYNC-DRIVER&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Optional ODBC driver name. Defaults to &amp;lt;code&amp;gt;SQL Server&amp;lt;/code&amp;gt;.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Connection Helper Pattern ==&lt;br /&gt;
&lt;br /&gt;
A helper routine can wrap &amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt; and cache connections so each named reference is configured only once per session.&lt;br /&gt;
&lt;br /&gt;
Typical parameters:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Parameter&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Purpose&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Cs_Connection$&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Arbitrary database reference name, such as &amp;lt;code&amp;gt;C_SelectCon&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;C_InsertCon&amp;lt;/code&amp;gt;.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Cs_Server$&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server host name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Cs_Database$&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server database name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Cs_User$&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL login. Often defaults to &amp;lt;code&amp;gt;LOGIN_NAME$&amp;lt;/code&amp;gt;.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Password$&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL password. Often defaults to &amp;lt;code&amp;gt;BR_PASSWORD&amp;lt;/code&amp;gt; for Windows authentication.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Cs_Sql_Authentication&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Indicates SQL authentication mode.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Cs_Driver$&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;ODBC driver name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example pattern:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DEF Fn_Config_Sql(Cs_Connection$*256, Cs_Server$*256, Cs_Database$*256;&lt;br /&gt;
                  Cs_User$*256, Password$*256, Cs_Sql_Authentication, Cs_Driver$*256)&lt;br /&gt;
&lt;br /&gt;
    EXECUTE &#039;CONFIG DATABASE &#039; &amp;amp; Cs_Connection$ &amp;amp;&lt;br /&gt;
            &#039; CONNECTSTRING=&amp;quot;&#039; &amp;amp; Connectionstring$ &amp;amp; &#039;&amp;quot;&#039; ERROR CONNECT_ERROR&lt;br /&gt;
&lt;br /&gt;
FNEND&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Separate Connections for Separate Workloads ==&lt;br /&gt;
&lt;br /&gt;
Larger routines commonly use separate named connections so concurrent SQL channels do not collide.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Connection Name&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Typical Use&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;C_SelectCon&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SELECT queries and schema discovery.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;C_InsertCon&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;INSERT operations.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;C_UpdateCon&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;UPDATE operations.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;C_DeleteCon&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;DELETE operations.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;C_RetryCon&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Retry path after transient SQL errors.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;SetUpConn&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Folder/setup stored procedures.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET Sconn$ = &amp;quot;C_SelectCon&amp;quot;&lt;br /&gt;
LET Insconn$ = &amp;quot;C_InsertCon&amp;quot;&lt;br /&gt;
LET Delconn$ = &amp;quot;C_DeleteCon&amp;quot;&lt;br /&gt;
&lt;br /&gt;
LET Fn_Config_Sql(Sconn$, Bc_Server$, Bc_Database$, Bc_User$, Bc_Password$)&lt;br /&gt;
LET Fn_Config_Sql(Insconn$, Bc_Server$, Bc_Database$, Bc_User$, Bc_Password$)&lt;br /&gt;
LET Fn_Config_Sql(Delconn$, Bc_Server$, Bc_Database$, Bc_User$, Bc_Password$)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discovering SQL Table Structure ==&lt;br /&gt;
&lt;br /&gt;
A program can discover SQL columns by opening a &amp;lt;code&amp;gt;SELECT TOP 1 *&amp;lt;/code&amp;gt; channel and reading metadata from &amp;lt;code&amp;gt;STATUS.DATABASE&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET Qry_Ispent_Design$ = &amp;quot;SELECT TOP 1 * FROM &amp;quot; &amp;amp; Gsf_Object$&lt;br /&gt;
&lt;br /&gt;
OPEN #(Db_Handle_Design := Fngethandle): &amp;quot;DATABASE=&amp;quot; &amp;amp; Gsf_Connection$, SQL Qry_Ispent_Design$, OUTIN&lt;br /&gt;
&lt;br /&gt;
LET Env$(&amp;quot;STATUS.DATABASE.[&amp;quot; &amp;amp; Trim$(Uprc$(Gsf_Connection$)) &amp;amp;&lt;br /&gt;
       &amp;quot;].TABLES.[&amp;quot; &amp;amp; Trim$(Uprc$(Gsf_Object$)) &amp;amp; &amp;quot;].COLUMNS&amp;quot;, MAT Columns$)&lt;br /&gt;
&lt;br /&gt;
CLOSE #Db_Handle_Design:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The resulting metadata can be used to classify columns as character, date, or numeric and to build the appropriate BR &amp;lt;code&amp;gt;FORM&amp;lt;/code&amp;gt; definitions.&lt;br /&gt;
&lt;br /&gt;
== Incremental Processing Pattern ==&lt;br /&gt;
&lt;br /&gt;
Large SQL tables should usually be processed in batches rather than loaded all at once.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
! Build the SELECT&lt;br /&gt;
LET Qry_Select$ = &amp;quot;SELECT TOP 100000 col1, col2 FROM [dbo].[MYTABLE] WITH (NOLOCK)&amp;quot; &amp;amp;&lt;br /&gt;
                  &amp;quot; WHERE Folder_Number = &amp;quot; &amp;amp; Folder_Number$ &amp;amp;&lt;br /&gt;
                  &amp;quot; ORDER BY Record_Number ASC&amp;quot;&lt;br /&gt;
&lt;br /&gt;
! Save SQL for debugging&lt;br /&gt;
LET Setenv(&amp;quot;ER_Last_SQL&amp;quot;, Qry_Select$)&lt;br /&gt;
&lt;br /&gt;
! Open and execute&lt;br /&gt;
OPEN #(Selhandle := 20): &amp;quot;DATABASE=C_SelectCon&amp;quot;, SQL Qry_Select$, OUTIN&lt;br /&gt;
WRITE #Selhandle:&lt;br /&gt;
&lt;br /&gt;
! Read rows&lt;br /&gt;
READ #Selhandle: MAT Sql_Object_Data$, MAT Sql_Object_Data_Dates$, MAT Sql_Object_Data EOF SQL_EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the batch is exhausted, close the channel, build a new &amp;lt;code&amp;gt;SELECT TOP ... WHERE Record_Number &amp;gt; &amp;lt;last&amp;gt;&amp;lt;/code&amp;gt; query, and open a fresh channel.&lt;br /&gt;
&lt;br /&gt;
== DML Pattern: INSERT / UPDATE / DELETE ==&lt;br /&gt;
&lt;br /&gt;
Data-changing SQL follows the same &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;CLOSE&amp;lt;/code&amp;gt; pattern.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET Setenv(&amp;quot;ER_Last_SQL&amp;quot;, Insert_Sql$)&lt;br /&gt;
&lt;br /&gt;
OPEN #(Inshandle := Fngethandle): &amp;quot;DATABASE=C_InsertCon&amp;quot;, SQL Insert_Sql$, OUTIN&lt;br /&gt;
WRITE #Inshandle: ERROR SQL_ERROR&lt;br /&gt;
CLOSE #Inshandle:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Closing Named Connections ==&lt;br /&gt;
&lt;br /&gt;
At the end of a SQL operation, close or clear configured connections.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET Fn_Close_Db_Connections(Sconn$)&lt;br /&gt;
LET Fn_Close_Db_Connections(Insconn$)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or clear all configured database connections:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXECUTE &amp;quot;CONFIG DATABASE CLEAR ALL&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example Helper Entry Points ==&lt;br /&gt;
&lt;br /&gt;
A larger BR SQL integration may include helper routines similar to the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Function&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Purpose&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Config_Sql&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Establishes a named ODBC connection.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Get_Sql_Fields&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Discovers SQL table or view column layout.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fnshow_Database&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Prints connection, table, and column metadata.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Bulk_Insert&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Copies BR records to SQL in a full load.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Incremental_Sync&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Compares and reconciles BR rows against SQL rows.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Create_Table&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Creates SQL tables.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Alter_Table&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Alters SQL table structure.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Truncate_Table&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Clears a SQL table.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Close_Db_Connections&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Releases configured SQL connections.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example Usage from a Program ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY &amp;quot;SQL/Library&amp;quot;: Fnopen_Sql_File&lt;br /&gt;
LIBRARY &amp;quot;util/Library&amp;quot;: Fngethandle, Fnget_Form&lt;br /&gt;
&lt;br /&gt;
LET Fn_Config_Sql(&amp;quot;MyConn&amp;quot;, &amp;quot;VT-SQL01&amp;quot;, &amp;quot;MyDatabase&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
LET Fn_Get_Sql_Fields(&amp;quot;MyConn&amp;quot;, &amp;quot;CUSTOMERS&amp;quot;, MAT Data$, MAT Dates$, MAT Data)&lt;br /&gt;
&lt;br /&gt;
! Program logic here&lt;br /&gt;
&lt;br /&gt;
LET Fn_Close_Db_Connections(&amp;quot;MyConn&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Security Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Protect source files and saved connection strings. Literal credentials inside connection strings are visible to anyone who can read the program or configuration.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Prefer &amp;lt;code&amp;gt;PASSWORDD=&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;BR_PASSWORD&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;LOGIN_NAME&amp;lt;/code&amp;gt;, or runtime prompts over literal passwords.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Prefer parameterized statements using &amp;lt;code&amp;gt;WRITE #h: value1, value2&amp;lt;/code&amp;gt; over string concatenation of user input.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Avoid placing both &amp;lt;code&amp;gt;UID/PWD&amp;lt;/code&amp;gt; inside the connection string and &amp;lt;code&amp;gt;USER/PASSWORD&amp;lt;/code&amp;gt; outside the connection string.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Do not use &amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt; in Client/Server mode.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;When practical, log the last SQL statement to an environment variable such as &amp;lt;code&amp;gt;ER_Last_SQL&amp;lt;/code&amp;gt; for troubleshooting.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Always close SQL channels after use.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting Checklist ==&lt;br /&gt;
&lt;br /&gt;
When a database connection fails:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the ODBC driver is installed on the machine running BR.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the driver name matches the connection string.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the SQL Server, MySQL, SQLite, or Access target is reachable.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm credentials.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the database name.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm firewall and network access.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the connection works in the Windows ODBC manager.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If using Windows authentication, confirm the BR process is running under the expected user context.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If using Client/Server mode, avoid &amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Print &amp;lt;code&amp;gt;SYSERR$&amp;lt;/code&amp;gt; for the driver-specific error message.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When a query fails:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Print or log the SQL statement.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm table and column names.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm quoting of strings and dates.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the number of parameter markers matches the number of values supplied to &amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the &amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt; form matches the selected columns.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm character fields are wide enough.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use &amp;lt;code&amp;gt;STATUS.DATABASE&amp;lt;/code&amp;gt; metadata to inspect table and column definitions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[CONFIG]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[EXECUTE]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[OPEN]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[WRITE]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[READ]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[CLOSE]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Encrypted passwords]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Unhex]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Decrypt]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:All Parameters]]&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=DATABASE&amp;diff=11514</id>
		<title>DATABASE</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=DATABASE&amp;diff=11514"/>
		<updated>2026-07-06T16:53:01Z</updated>

		<summary type="html">&lt;p&gt;GomezL: Replacement Documentation for Database.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= DATABASE =&lt;br /&gt;
&lt;br /&gt;
Starting in &#039;&#039;&#039;Business Rules! 4.3&#039;&#039;&#039;, the &amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt; directive allows a BR program to connect to external SQL databases through ODBC.&lt;br /&gt;
&lt;br /&gt;
This page covers BR acting as an &#039;&#039;&#039;ODBC SQL client&#039;&#039;&#039; — connecting outward to SQL Server, MySQL, SQLite, Microsoft Access, and other relational databases, executing SQL statements, and reading result rows.&lt;br /&gt;
&lt;br /&gt;
BR treats a live SQL statement as an ordinary I/O channel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt; names the connection.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt; binds a BR file channel to a SQL statement.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; executes the SQL statement.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt; fetches rows for a &amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;CLOSE&amp;lt;/code&amp;gt; releases the statement/result set.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; This is different from the BR ODBC driver that exposes BR data files to Excel, Access, reporting tools, or other external consumers.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Step&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Statement&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Purpose&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;1. Configure connection&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;CONFIG DATABASE &amp;amp;lt;db-ref&amp;amp;gt; ...&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Names a data source and tells BR how to connect to it.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;2. Open SQL channel&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;OPEN #h: &amp;quot;DATABASE=&amp;amp;lt;db-ref&amp;amp;gt;&amp;quot;, SQL sql$, OUTIN&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Binds a BR channel to one SQL statement over the named connection.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;3. Execute SQL&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;WRITE #h:&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Executes the bound SQL statement.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;4. Fetch rows&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;READ #h, USING ...&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Reads result rows from a &amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt;.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;5. Close channel&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;CLOSE #h:&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Releases the SQL statement/result set.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;&amp;lt;db-ref&amp;gt;&amp;lt;/code&amp;gt; is the connection name. The same name used in &amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt; is referenced later in &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;&amp;quot;DATABASE=&amp;lt;db-ref&amp;gt;&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXECUTE &#039;CONFIG DATABASE DemoConn CONNECTSTRING=&amp;quot;DRIVER=SQL Server;SERVER=myserver;Initial Catalog=mydb;UID=myuser;PWD=mypass&amp;quot;&#039;&lt;br /&gt;
&lt;br /&gt;
LET C_SQL$ = &amp;quot;SELECT FirstName, LastName FROM dbo.Customers&amp;quot;&lt;br /&gt;
&lt;br /&gt;
OPEN #(H := 21): &amp;quot;DATABASE=DemoConn&amp;quot;, SQL C_SQL$, OUTIN&lt;br /&gt;
WRITE #H:&lt;br /&gt;
&lt;br /&gt;
RD: READ #H, USING &#039;FORM POS 1,C 50,C 50&#039;: FIRST$, LAST$ EOF DONE&lt;br /&gt;
    PRINT TRIM$(FIRST$); &amp;quot; &amp;quot;; TRIM$(LAST$)&lt;br /&gt;
    GOTO RD&lt;br /&gt;
&lt;br /&gt;
DONE: CLOSE #H:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CONFIG DATABASE ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt; defines a named ODBC connection.&lt;br /&gt;
&lt;br /&gt;
It may be placed in &amp;lt;code&amp;gt;BRConfig.sys&amp;lt;/code&amp;gt; or issued from inside a program using &amp;lt;code&amp;gt;EXECUTE&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Connection Methods ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt; supports three connection methods:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;DSN&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;CONNECTSTRING&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== General Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG DATABASE &amp;lt;db-ref&amp;gt; { DSN=&amp;lt;dsn-ref&amp;gt;&lt;br /&gt;
                         | CONNECTSTRING=&amp;quot;&amp;lt;odbc-connection-string&amp;gt;&amp;quot;&lt;br /&gt;
                         | ODBC-MANAGER }&lt;br /&gt;
                         [ , USER= { &amp;lt;department&amp;gt; | LOGIN_NAME | ? } ]&lt;br /&gt;
                         [ , { PASSWORD= { &amp;lt;dept-password&amp;gt; | BR_PASSWORD | ? }&lt;br /&gt;
                             | PASSWORDD=&amp;lt;encrypted-password&amp;gt; } ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Option&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Meaning&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;&amp;amp;lt;db-ref&amp;amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Arbitrary BR database reference name. This is the name used later in &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt;.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;DSN=&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Uses a pre-configured Windows ODBC Data Source Name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;CONNECTSTRING=&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Uses a DSN-less ODBC connection string.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Displays the Windows ODBC manager so the user can select the data source.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;USER=?&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Prompts the operator for the user name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;PASSWORD=?&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Prompts the operator for the password.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;USER=LOGIN_NAME&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Uses the current BR login / Active Directory user name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;PASSWORD=BR_PASSWORD&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Uses the current BR login / Active Directory password.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;PASSWORDD=&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Supplies an encrypted password as a hexadecimal value.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DSN ==&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;DSN&amp;lt;/code&amp;gt; when the ODBC Data Source Name has already been configured in the Windows ODBC manager.&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG DATABASE &amp;lt;db-ref&amp;gt; DSN=&amp;lt;dsn-ref&amp;gt;&lt;br /&gt;
    [, USER=&amp;lt;department&amp;gt; | LOGIN_NAME | ?]&lt;br /&gt;
    [, PASSWORD=&amp;lt;dept-password&amp;gt; | BR_PASSWORD | ? | PASSWORDD=&amp;lt;encrypted-password&amp;gt;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXECUTE &#039;CONFIG DATABASE CLS_Data DSN=&amp;quot;MyData&amp;quot;, PASSWORDD=&amp;lt;encrypted-password&amp;gt;&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Encrypted passwords are expressed as hexadecimal values. BR unhexes and decrypts the value before presenting it to the SQL driver.&lt;br /&gt;
&lt;br /&gt;
== CONNECTSTRING / DSN-less Connections ==&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;CONNECTSTRING&amp;lt;/code&amp;gt; when the full ODBC connection string should be supplied directly.&lt;br /&gt;
&lt;br /&gt;
This is usually the most portable option for deployed applications because it avoids requiring a pre-created DSN on each workstation or server.&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG DATABASE &amp;lt;db-ref&amp;gt; CONNECTSTRING=&amp;quot;&amp;lt;odbc-connection-string&amp;gt;&amp;quot;&lt;br /&gt;
    [, USER=&amp;lt;department&amp;gt; | LOGIN_NAME | ?]&lt;br /&gt;
    [, PASSWORD=&amp;lt;dept-password&amp;gt; | BR_PASSWORD | ? | PASSWORDD=&amp;lt;encrypted-password&amp;gt;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SQL Server with SQL Login ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG DATABASE db-ref CONNECTSTRING=&amp;quot;DRIVER=SQL Server;SERVER=server;Initial Catalog=database;UID=username;PWD=password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Value&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Meaning&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;db-ref&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;BR database reference name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;server&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server FQDN, host name, or IP address.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;database&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server database name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;username&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server login.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;password&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server password.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SQL Server with Windows Authentication ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG DATABASE db-ref CONNECTSTRING=&amp;quot;DRIVER=SQL Server;Initial Catalog=database;SERVER=server&amp;quot; USER=LOGIN_NAME PASSWORD=BR_PASSWORD&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When &amp;lt;code&amp;gt;USER=&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;PASSWORD=&amp;lt;/code&amp;gt; are specified outside the quoted connection string, BR augments the ODBC connection string with &amp;lt;code&amp;gt;UID=&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;PWD=&amp;lt;/code&amp;gt; values.&lt;br /&gt;
&lt;br /&gt;
Do not also place &amp;lt;code&amp;gt;UID&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;PWD&amp;lt;/code&amp;gt; inside the connection string itself when using BR&#039;s &amp;lt;code&amp;gt;USER=&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;PASSWORD=&amp;lt;/code&amp;gt; parameters.&lt;br /&gt;
&lt;br /&gt;
=== Other Sample Connection Strings ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Target&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Example&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server, SQL login&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;DRIVER=SQL Server;SERVER=myserver;Initial Catalog=mydb;UID=myuser;PWD=mypass&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server, Windows authentication&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;DRIVER=SQL Server;SERVER=myserver;Initial Catalog=mydb&amp;lt;/code&amp;gt; with &amp;lt;code&amp;gt;USER=LOGIN_NAME PASSWORD=BR_PASSWORD&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;MySQL&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;DSN=BRG_DEMO;SERVER=127.0.0.1;UID=dbadmin;PWD=mypass;DATABASE=brg_demo;PORT=3306&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQLite&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;DSN=SQLite3 Datasource;Database=C:\demo\brg_demo.sqlite;SyncPragma=NORMAL;Timeout=100000&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Microsoft Access&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Driver={Microsoft Access Driver (*.mdb)};DBQ=C:\path\Contact.mdb&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ODBC-MANAGER ==&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt; to display the Windows ODBC manager and allow the user to select the data source at runtime.&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG DATABASE &amp;lt;db-ref&amp;gt; ODBC-MANAGER&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Important Client/Server Note ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt; does &#039;&#039;&#039;not&#039;&#039;&#039; work in Client/Server mode because the ODBC selection occurs on the server, not on the user&#039;s workstation.&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00010 PRINT NEWPAGE&lt;br /&gt;
00020 IF Env$(&amp;quot;br_model&amp;quot;) = &amp;quot;CLIENT_SERVER&amp;quot; THEN PRINT &amp;quot;Warning, you cannot connect to ODBC-MANAGER in Client/Server mode&amp;quot;&lt;br /&gt;
00030 EXECUTE &amp;quot;CONFIG DATABASE Test_DB ODBC-MANAGER&amp;quot; ERROR CONNECT_ERROR&lt;br /&gt;
00040 PRINT &amp;quot;Connection String is:&amp;quot; !:&lt;br /&gt;
00050 PRINT Env$(&amp;quot;STATUS.DATABASE.[TEST_DB].CONNECTSTRING&amp;quot;)&lt;br /&gt;
00060 STOP&lt;br /&gt;
00100 CONNECT_ERROR:&lt;br /&gt;
00110 PRINT &amp;quot;Error Connecting - Err:&amp;quot;; Err; &amp;quot; Line:&amp;quot;; Line; &amp;quot; Syserr:&amp;quot;; Syserr$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Viewing the Resolved Connection String ==&lt;br /&gt;
&lt;br /&gt;
After a connection is configured, BR exposes the effective connection string through &amp;lt;code&amp;gt;Env$&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRINT Env$(&amp;quot;STATUS.DATABASE.[MyConn].CONNECTSTRING&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Connection names in &amp;lt;code&amp;gt;STATUS.DATABASE&amp;lt;/code&amp;gt; paths are generally uppercased by BR. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRINT Env$(&amp;quot;STATUS.DATABASE.[DEMOCONN].CONNECTSTRING&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== OPENing a SQL Statement ==&lt;br /&gt;
&lt;br /&gt;
After the database connection is configured, use &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt; to bind a BR channel to a SQL statement.&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
OPEN #&amp;lt;channel&amp;gt;: &amp;quot;DATABASE=&amp;lt;db-ref&amp;gt;&amp;quot;, SQL &amp;lt;string-expression&amp;gt;, OUTIN&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Clause&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Meaning&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;#&amp;amp;lt;channel&amp;amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;BR file channel number.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;&amp;quot;DATABASE=&amp;amp;lt;db-ref&amp;amp;gt;&amp;quot;&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Refers to the connection previously configured with &amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt;.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;SQL &amp;amp;lt;string-expression&amp;amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL text to bind to the channel.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;OUTIN&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Opens the channel for output and input. Used for both executing and reading.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DIM C_SQL$*4096&lt;br /&gt;
&lt;br /&gt;
LET C_SQL$ = &amp;quot;SELECT FirstName, LastName, Email FROM dbo.Customers ORDER BY LastName&amp;quot;&lt;br /&gt;
&lt;br /&gt;
OPEN #(DB_HANDLE := 21): &amp;quot;DATABASE=DemoConn&amp;quot;, SQL C_SQL$, OUTIN&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The SQL statement is bound at &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt; time. To run a different SQL statement, build a new SQL string and open a new channel.&lt;br /&gt;
&lt;br /&gt;
== Opening SQL from an External File ==&lt;br /&gt;
&lt;br /&gt;
A channel may also use SQL text stored in an external file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
OPEN #H: &amp;quot;DATABASE=MyConn,NAME=Setup_Tables.sql/MyFolder&amp;quot;, SQL, OUTIN&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Executing SQL with WRITE ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; with no data list executes the SQL statement bound during &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
WRITE #DB_HANDLE:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For a &amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; executes the query and prepares the result set. It must be called before the first &amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For &amp;lt;code&amp;gt;INSERT&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;UPDATE&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;DELETE&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; performs the change. No &amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt; follows unless the SQL statement returns rows.&lt;br /&gt;
&lt;br /&gt;
== Parameterized Statements ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; with a data list binds values to parameter markers in the prepared SQL statement.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET C_SQL$ = &amp;quot;INSERT INTO dbo.Customers (FirstName, LastName) VALUES (?, ?)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
OPEN #(H := 21): &amp;quot;DATABASE=DemoConn&amp;quot;, SQL C_SQL$, OUTIN&lt;br /&gt;
WRITE #H: FIRST$, LAST$&lt;br /&gt;
CLOSE #H:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use parameter binding instead of concatenating operator input into SQL strings whenever possible. It avoids quoting errors and reduces SQL injection risk.&lt;br /&gt;
&lt;br /&gt;
== Reading Result Rows ==&lt;br /&gt;
&lt;br /&gt;
Each &amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt; fetches one result row.&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
READ #&amp;lt;channel&amp;gt;, USING &#039;&amp;lt;form-spec&amp;gt;&#039;: &amp;lt;var&amp;gt; [, &amp;lt;var&amp;gt;]* EOF &amp;lt;line-ref&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RD: READ #DB_HANDLE, USING &#039;FORM POS 1,C 50,C 50&#039;: C1$, C2$ EOF DONE&lt;br /&gt;
    PRINT TRIM$(C1$); &amp;quot;,&amp;quot;; TRIM$(C2$)&lt;br /&gt;
    GOTO RD&lt;br /&gt;
&lt;br /&gt;
DONE: CLOSE #DB_HANDLE:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Columns in the SQL &amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt; list map left-to-right onto the variables in the &amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The &amp;lt;code&amp;gt;FORM&amp;lt;/code&amp;gt; must match the expected data layout.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Size character fields generously, for example &amp;lt;code&amp;gt;C 50&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;C 100&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use numeric, date, packed decimal, and other BR &amp;lt;code&amp;gt;FORM&amp;lt;/code&amp;gt; types as appropriate.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;EOF&amp;lt;/code&amp;gt; fires when the result set is exhausted.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;For many columns, arrays and composite forms are usually easier than long lists of individual variables.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Closing SQL Channels ==&lt;br /&gt;
&lt;br /&gt;
Always close SQL channels when done.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CLOSE #DB_HANDLE:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This releases the channel and the associated SQL statement/result set.&lt;br /&gt;
&lt;br /&gt;
This is especially important in loops that repeatedly open SQL statements.&lt;br /&gt;
&lt;br /&gt;
== Clearing Configured Connections ==&lt;br /&gt;
&lt;br /&gt;
To clear one named connection:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXECUTE &amp;quot;CONFIG DATABASE CLEAR MyConn&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To clear all configured database connections:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXECUTE &amp;quot;CONFIG DATABASE CLEAR ALL&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Complete SELECT Example ==&lt;br /&gt;
&lt;br /&gt;
The following example connects to SQL Server, executes a &amp;lt;code&amp;gt;SELECT&amp;lt;/code&amp;gt;, reads the rows, and prints the result.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00010 ! ============================================================&lt;br /&gt;
00020 ! Sample: Connect to SQL Server, SELECT rows, print results&lt;br /&gt;
00030 ! ============================================================&lt;br /&gt;
00040 PRINT NEWPAGE&lt;br /&gt;
00050 DIM C_SQL$*4096&lt;br /&gt;
00060 DIM FIRST$*50, LAST$*50, EMAIL$*100&lt;br /&gt;
00070 DIM DB_HANDLE&lt;br /&gt;
00080 !&lt;br /&gt;
00090 ! --- Step 1: Create the connection ---&lt;br /&gt;
00100 EXECUTE &#039;CONFIG DATABASE DemoConn CONNECTSTRING=&amp;quot;DRIVER=SQL Server;SERVER=myserver;Initial Catalog=mydb;UID=myuser;PWD=mypass&amp;quot;&#039; ERROR CONNECT_ERR&lt;br /&gt;
00110 !&lt;br /&gt;
00120 ! --- Step 2: Define the SQL statement and open a channel ---&lt;br /&gt;
00130 LET C_SQL$ = &amp;quot;SELECT FirstName, LastName, Email FROM dbo.Customers ORDER BY LastName&amp;quot;&lt;br /&gt;
00140 OPEN #(DB_HANDLE := 21): &amp;quot;DATABASE=DemoConn&amp;quot;, SQL C_SQL$, OUTIN ERROR OPEN_ERR&lt;br /&gt;
00150 !&lt;br /&gt;
00160 ! --- Step 3: Execute the query ---&lt;br /&gt;
00170 WRITE #DB_HANDLE: ERROR EXEC_ERR&lt;br /&gt;
00180 !&lt;br /&gt;
00190 ! --- Step 4: Loop through result rows ---&lt;br /&gt;
00200 RD: READ #DB_HANDLE, USING &#039;FORM POS 1,C 50,C 50,C 100&#039;: FIRST$, LAST$, EMAIL$ EOF DONE&lt;br /&gt;
00210     PRINT TRIM$(LAST$); &amp;quot;, &amp;quot;; TRIM$(FIRST$); &amp;quot;  &amp;lt;&amp;quot;; TRIM$(EMAIL$); &amp;quot;&amp;gt;&amp;quot;&lt;br /&gt;
00220     GOTO RD&lt;br /&gt;
00230 !&lt;br /&gt;
00240 DONE:&lt;br /&gt;
00250 CLOSE #DB_HANDLE:&lt;br /&gt;
00260 PRINT &amp;quot;Finished.&amp;quot;&lt;br /&gt;
00270 STOP&lt;br /&gt;
00280 !&lt;br /&gt;
00290 CONNECT_ERR:&lt;br /&gt;
00300 OPEN_ERR:&lt;br /&gt;
00310 EXEC_ERR:&lt;br /&gt;
00320     PRINT &amp;quot;Error:&amp;quot;; ERR; &amp;quot; Line:&amp;quot;; LINE; &amp;quot; Syserr:&amp;quot;; SYSERR$&lt;br /&gt;
00330     STOP&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Windows Authentication Example ==&lt;br /&gt;
&lt;br /&gt;
For SQL Server integrated security, omit credentials from the quoted connection string and allow BR to supply them.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXECUTE &#039;CONFIG DATABASE DemoConn CONNECTSTRING=&amp;quot;DRIVER=SQL Server;Initial Catalog=mydb;SERVER=myserver&amp;quot; USER=LOGIN_NAME PASSWORD=BR_PASSWORD&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== INSERT Example ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET C_SQL$ = &amp;quot;INSERT INTO dbo.Customers (FirstName, LastName) VALUES (&#039;Jane&#039;, &#039;Doe&#039;)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
OPEN #(DB_HANDLE := 21): &amp;quot;DATABASE=DemoConn&amp;quot;, SQL C_SQL$, OUTIN&lt;br /&gt;
WRITE #DB_HANDLE:&lt;br /&gt;
CLOSE #DB_HANDLE:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside a BR string, two double-quotes represent one literal double-quote.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET C_SQL$ = &amp;quot;INSERT INTO dbo.Customers (FirstName, LastName) VALUES (&amp;quot;&amp;quot;Jane&amp;quot;&amp;quot;, &amp;quot;&amp;quot;Doe&amp;quot;&amp;quot;)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Error Handling ==&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt; clauses or &amp;lt;code&amp;gt;ON ERROR&amp;lt;/code&amp;gt; to trap connection, execution, and fetch failures.&lt;br /&gt;
&lt;br /&gt;
Report:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;ERR&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;LINE&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;SYSERR$&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
OPEN #(H := 21): &amp;quot;DATABASE=DemoConn&amp;quot;, SQL C_SQL$, OUTIN ERROR SQL_ERR&lt;br /&gt;
WRITE #H: ERROR SQL_ERR&lt;br /&gt;
&lt;br /&gt;
RD: READ #H, USING &#039;FORM POS 1,C 50&#039;: C1$ EOF DONE ERROR SQL_ERR&lt;br /&gt;
    PRINT C1$&lt;br /&gt;
    GOTO RD&lt;br /&gt;
&lt;br /&gt;
DONE:&lt;br /&gt;
    CLOSE #H:&lt;br /&gt;
    STOP&lt;br /&gt;
&lt;br /&gt;
SQL_ERR:&lt;br /&gt;
    PRINT &amp;quot;Error:&amp;quot;; ERR; &amp;quot; Line:&amp;quot;; LINE; &amp;quot; Syserr:&amp;quot;; SYSERR$&lt;br /&gt;
    STOP&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common SQL / ODBC Error Codes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Code&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Meaning&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;3006 / 4006&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL execute-direct failed.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;3007 / 4007&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; used with the incorrect number of data elements. Usually a parameter mismatch.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;3010 / 4010&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL fetch-row failed.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;3011 / 4011&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL bind-parameter failure.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;4015&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;The specified database has not been opened.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;4270&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;EOF on &amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt;. This is normal end-of-result-set behavior when an &amp;lt;code&amp;gt;EOF&amp;lt;/code&amp;gt; clause is not used.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First checks when a connection or query fails:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the ODBC driver name.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the server name or IP address.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the database name.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm credentials.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm network/firewall access.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the ODBC driver is installed on the machine running BR.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If using &amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt;, confirm BR is not running in Client/Server mode.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== STATUS.DATABASE Introspection ==&lt;br /&gt;
&lt;br /&gt;
After opening a channel against a connection, BR exposes metadata through &amp;lt;code&amp;gt;STATUS.DATABASE&amp;lt;/code&amp;gt; environment variables.&lt;br /&gt;
&lt;br /&gt;
=== Resolved Connection String ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRINT Env$(&amp;quot;STATUS.DATABASE.[DEMOCONN].CONNECTSTRING&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== List Tables ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET Env$(&amp;quot;STATUS.DATABASE.[DEMOCONN].TABLES.LIST&amp;quot;, MAT TABLES$)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== List Columns ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET Env$(&amp;quot;STATUS.DATABASE.[DEMOCONN].TABLES.[CUSTOMERS].COLUMNS.LIST&amp;quot;, MAT COLS$)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Column Metadata ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PRINT Env$(&amp;quot;STATUS.DATABASE.[DEMOCONN].TABLES.[CUSTOMERS].COLUMNS.[EMAIL].TYPE&amp;quot;)&lt;br /&gt;
PRINT Env$(&amp;quot;STATUS.DATABASE.[DEMOCONN].TABLES.[CUSTOMERS].COLUMNS.[EMAIL].LENGTH&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Connection names in &amp;lt;code&amp;gt;STATUS.DATABASE&amp;lt;/code&amp;gt; paths are uppercased by BR.&lt;br /&gt;
&lt;br /&gt;
== Production-Style Usage Pattern ==&lt;br /&gt;
&lt;br /&gt;
The same ODBC pattern can be used in larger production routines that synchronize BR data files with SQL Server tables.&lt;br /&gt;
&lt;br /&gt;
A production routine commonly performs these tasks:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Configure named SQL connections.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Discover SQL table structure.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Read SQL rows through BR channels.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Compare SQL rows against BR file records.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Perform inserts, updates, and deletes.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Page through large SQL tables.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Reuse and clear named connections.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example Setup Pattern ==&lt;br /&gt;
&lt;br /&gt;
A program may load supporting routines and configure a default SQL connection from environment variables.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY &amp;quot;SQL/Library&amp;quot;: Fnopen_Sql_File&lt;br /&gt;
LIBRARY &amp;quot;Clsutil/Library&amp;quot;: Fngethandle, Fnget_Form&lt;br /&gt;
&lt;br /&gt;
LET Fn_Config_Sql(&amp;quot;SetUpConn&amp;quot;, Env$(&amp;quot;SQL-SYNC-SERVER&amp;quot;), Env$(&amp;quot;SQL-SYNC-DATABASE&amp;quot;))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Common environment variables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Variable&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Purpose&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;SQL-SYNC-SERVER&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server host name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;SQL-SYNC-DATABASE&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Target SQL Server database.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;SQL-SYNC-CONNECTION&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Optional override connection string. May support a &amp;lt;code&amp;gt;[LOGIN_NAME]&amp;lt;/code&amp;gt; placeholder.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;SQL-SYNC-DRIVER&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Optional ODBC driver name. Defaults to &amp;lt;code&amp;gt;SQL Server&amp;lt;/code&amp;gt;.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Connection Helper Pattern ==&lt;br /&gt;
&lt;br /&gt;
A helper routine can wrap &amp;lt;code&amp;gt;CONFIG DATABASE&amp;lt;/code&amp;gt; and cache connections so each named reference is configured only once per session.&lt;br /&gt;
&lt;br /&gt;
Typical parameters:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Parameter&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Purpose&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Cs_Connection$&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Arbitrary database reference name, such as &amp;lt;code&amp;gt;C_SelectCon&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;C_InsertCon&amp;lt;/code&amp;gt;.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Cs_Server$&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server host name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Cs_Database$&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL Server database name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Cs_User$&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL login. Often defaults to &amp;lt;code&amp;gt;LOGIN_NAME$&amp;lt;/code&amp;gt;.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Password$&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SQL password. Often defaults to &amp;lt;code&amp;gt;BR_PASSWORD&amp;lt;/code&amp;gt; for Windows authentication.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Cs_Sql_Authentication&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Indicates SQL authentication mode.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Cs_Driver$&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;ODBC driver name.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example pattern:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DEF Fn_Config_Sql(Cs_Connection$*256, Cs_Server$*256, Cs_Database$*256;&lt;br /&gt;
                  Cs_User$*256, Password$*256, Cs_Sql_Authentication, Cs_Driver$*256)&lt;br /&gt;
&lt;br /&gt;
    EXECUTE &#039;CONFIG DATABASE &#039; &amp;amp; Cs_Connection$ &amp;amp;&lt;br /&gt;
            &#039; CONNECTSTRING=&amp;quot;&#039; &amp;amp; Connectionstring$ &amp;amp; &#039;&amp;quot;&#039; ERROR CONNECT_ERROR&lt;br /&gt;
&lt;br /&gt;
FNEND&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Separate Connections for Separate Workloads ==&lt;br /&gt;
&lt;br /&gt;
Larger routines commonly use separate named connections so concurrent SQL channels do not collide.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Connection Name&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Typical Use&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;C_SelectCon&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;SELECT queries and schema discovery.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;C_InsertCon&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;INSERT operations.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;C_UpdateCon&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;UPDATE operations.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;C_DeleteCon&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;DELETE operations.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;C_RetryCon&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Retry path after transient SQL errors.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;SetUpConn&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Folder/setup stored procedures.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET Sconn$ = &amp;quot;C_SelectCon&amp;quot;&lt;br /&gt;
LET Insconn$ = &amp;quot;C_InsertCon&amp;quot;&lt;br /&gt;
LET Delconn$ = &amp;quot;C_DeleteCon&amp;quot;&lt;br /&gt;
&lt;br /&gt;
LET Fn_Config_Sql(Sconn$, Bc_Server$, Bc_Database$, Bc_User$, Bc_Password$)&lt;br /&gt;
LET Fn_Config_Sql(Insconn$, Bc_Server$, Bc_Database$, Bc_User$, Bc_Password$)&lt;br /&gt;
LET Fn_Config_Sql(Delconn$, Bc_Server$, Bc_Database$, Bc_User$, Bc_Password$)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Discovering SQL Table Structure ==&lt;br /&gt;
&lt;br /&gt;
A program can discover SQL columns by opening a &amp;lt;code&amp;gt;SELECT TOP 1 *&amp;lt;/code&amp;gt; channel and reading metadata from &amp;lt;code&amp;gt;STATUS.DATABASE&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET Qry_Ispent_Design$ = &amp;quot;SELECT TOP 1 * FROM &amp;quot; &amp;amp; Gsf_Object$&lt;br /&gt;
&lt;br /&gt;
OPEN #(Db_Handle_Design := Fngethandle): &amp;quot;DATABASE=&amp;quot; &amp;amp; Gsf_Connection$, SQL Qry_Ispent_Design$, OUTIN&lt;br /&gt;
&lt;br /&gt;
LET Env$(&amp;quot;STATUS.DATABASE.[&amp;quot; &amp;amp; Trim$(Uprc$(Gsf_Connection$)) &amp;amp;&lt;br /&gt;
       &amp;quot;].TABLES.[&amp;quot; &amp;amp; Trim$(Uprc$(Gsf_Object$)) &amp;amp; &amp;quot;].COLUMNS&amp;quot;, MAT Columns$)&lt;br /&gt;
&lt;br /&gt;
CLOSE #Db_Handle_Design:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The resulting metadata can be used to classify columns as character, date, or numeric and to build the appropriate BR &amp;lt;code&amp;gt;FORM&amp;lt;/code&amp;gt; definitions.&lt;br /&gt;
&lt;br /&gt;
== Incremental Processing Pattern ==&lt;br /&gt;
&lt;br /&gt;
Large SQL tables should usually be processed in batches rather than loaded all at once.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
! Build the SELECT&lt;br /&gt;
LET Qry_Select$ = &amp;quot;SELECT TOP 100000 col1, col2 FROM [dbo].[MYTABLE] WITH (NOLOCK)&amp;quot; &amp;amp;&lt;br /&gt;
                  &amp;quot; WHERE Folder_Number = &amp;quot; &amp;amp; Folder_Number$ &amp;amp;&lt;br /&gt;
                  &amp;quot; ORDER BY Record_Number ASC&amp;quot;&lt;br /&gt;
&lt;br /&gt;
! Save SQL for debugging&lt;br /&gt;
LET Setenv(&amp;quot;ER_Last_SQL&amp;quot;, Qry_Select$)&lt;br /&gt;
&lt;br /&gt;
! Open and execute&lt;br /&gt;
OPEN #(Selhandle := 20): &amp;quot;DATABASE=C_SelectCon&amp;quot;, SQL Qry_Select$, OUTIN&lt;br /&gt;
WRITE #Selhandle:&lt;br /&gt;
&lt;br /&gt;
! Read rows&lt;br /&gt;
READ #Selhandle: MAT Sql_Object_Data$, MAT Sql_Object_Data_Dates$, MAT Sql_Object_Data EOF SQL_EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the batch is exhausted, close the channel, build a new &amp;lt;code&amp;gt;SELECT TOP ... WHERE Record_Number &amp;gt; &amp;lt;last&amp;gt;&amp;lt;/code&amp;gt; query, and open a fresh channel.&lt;br /&gt;
&lt;br /&gt;
== DML Pattern: INSERT / UPDATE / DELETE ==&lt;br /&gt;
&lt;br /&gt;
Data-changing SQL follows the same &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;CLOSE&amp;lt;/code&amp;gt; pattern.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET Setenv(&amp;quot;ER_Last_SQL&amp;quot;, Insert_Sql$)&lt;br /&gt;
&lt;br /&gt;
OPEN #(Inshandle := Fngethandle): &amp;quot;DATABASE=C_InsertCon&amp;quot;, SQL Insert_Sql$, OUTIN&lt;br /&gt;
WRITE #Inshandle: ERROR SQL_ERROR&lt;br /&gt;
CLOSE #Inshandle:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Closing Named Connections ==&lt;br /&gt;
&lt;br /&gt;
At the end of a SQL operation, close or clear configured connections.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LET Fn_Close_Db_Connections(Sconn$)&lt;br /&gt;
LET Fn_Close_Db_Connections(Insconn$)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or clear all configured database connections:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXECUTE &amp;quot;CONFIG DATABASE CLEAR ALL&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example Helper Entry Points ==&lt;br /&gt;
&lt;br /&gt;
A larger BR SQL integration may include helper routines similar to the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table class=&amp;quot;wikitable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Function&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Purpose&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Config_Sql&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Establishes a named ODBC connection.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Get_Sql_Fields&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Discovers SQL table or view column layout.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fnshow_Database&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Prints connection, table, and column metadata.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Bulk_Insert&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Copies BR records to SQL in a full load.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Incremental_Sync&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Compares and reconciles BR rows against SQL rows.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Create_Table&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Creates SQL tables.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Alter_Table&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Alters SQL table structure.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Truncate_Table&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Clears a SQL table.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;Fn_Close_Db_Connections&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Releases configured SQL connections.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example Usage from a Program ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LIBRARY &amp;quot;SQL/Library&amp;quot;: Fnopen_Sql_File&lt;br /&gt;
LIBRARY &amp;quot;util/Library&amp;quot;: Fngethandle, Fnget_Form&lt;br /&gt;
&lt;br /&gt;
LET Fn_Config_Sql(&amp;quot;MyConn&amp;quot;, &amp;quot;VT-SQL01&amp;quot;, &amp;quot;MyDatabase&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
LET Fn_Get_Sql_Fields(&amp;quot;MyConn&amp;quot;, &amp;quot;CUSTOMERS&amp;quot;, MAT Data$, MAT Dates$, MAT Data)&lt;br /&gt;
&lt;br /&gt;
! Program logic here&lt;br /&gt;
&lt;br /&gt;
LET Fn_Close_Db_Connections(&amp;quot;MyConn&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Security Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Protect source files and saved connection strings. Literal credentials inside connection strings are visible to anyone who can read the program or configuration.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Prefer &amp;lt;code&amp;gt;PASSWORDD=&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;BR_PASSWORD&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;LOGIN_NAME&amp;lt;/code&amp;gt;, or runtime prompts over literal passwords.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Prefer parameterized statements using &amp;lt;code&amp;gt;WRITE #h: value1, value2&amp;lt;/code&amp;gt; over string concatenation of user input.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Avoid placing both &amp;lt;code&amp;gt;UID/PWD&amp;lt;/code&amp;gt; inside the connection string and &amp;lt;code&amp;gt;USER/PASSWORD&amp;lt;/code&amp;gt; outside the connection string.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Do not use &amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt; in Client/Server mode.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;When practical, log the last SQL statement to an environment variable such as &amp;lt;code&amp;gt;ER_Last_SQL&amp;lt;/code&amp;gt; for troubleshooting.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Always close SQL channels after use.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting Checklist ==&lt;br /&gt;
&lt;br /&gt;
When a database connection fails:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the ODBC driver is installed on the machine running BR.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the driver name matches the connection string.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the SQL Server, MySQL, SQLite, or Access target is reachable.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm credentials.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the database name.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm firewall and network access.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the connection works in the Windows ODBC manager.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If using Windows authentication, confirm the BR process is running under the expected user context.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If using Client/Server mode, avoid &amp;lt;code&amp;gt;ODBC-MANAGER&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Print &amp;lt;code&amp;gt;SYSERR$&amp;lt;/code&amp;gt; for the driver-specific error message.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When a query fails:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Print or log the SQL statement.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm table and column names.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm quoting of strings and dates.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the number of parameter markers matches the number of values supplied to &amp;lt;code&amp;gt;WRITE&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm the &amp;lt;code&amp;gt;READ&amp;lt;/code&amp;gt; form matches the selected columns.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Confirm character fields are wide enough.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Use &amp;lt;code&amp;gt;STATUS.DATABASE&amp;lt;/code&amp;gt; metadata to inspect table and column definitions.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[CONFIG]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[EXECUTE]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[OPEN]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[WRITE]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[READ]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[CLOSE]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Encrypted passwords]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Unhex]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;[[Decrypt]]&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:All Parameters]]&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Index&amp;diff=11507</id>
		<title>Index</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Index&amp;diff=11507"/>
		<updated>2026-06-13T21:46:49Z</updated>

		<summary type="html">&lt;p&gt;GomezL: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The &#039;&#039;&#039;Index&#039;&#039;&#039; [[command]] creates or recreates an index file. See the [[Index Facility]] for additional information. You may also find it useful to familiarize yourself with the concept of a [https://en.wikipedia.org/wiki/Index_(database) Database Index]&lt;br /&gt;
&lt;br /&gt;
For a simple tutorial, see [[Index_and_Sort_facilities_Tutorial|Index Tutorial]].&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
 INDEX &amp;lt;data file&amp;gt; &amp;lt;[[index file]]&amp;gt; &amp;lt;key start position&amp;gt;[/...] &amp;lt;key length&amp;gt;[/...] [-&amp;lt;work path&amp;gt;] [{[[DUPKEYS]]|NATIVE|[[REORG]]|REPLACE|[[LISTDUPKEYS]][&amp;gt;[&amp;gt;]&amp;lt;output file&amp;gt;]}][...] [-N] &lt;br /&gt;
&lt;br /&gt;
[[Image:Index.png|1000px]]&lt;br /&gt;
&lt;br /&gt;
== Errors &amp;amp; Limits ==&lt;br /&gt;
&lt;br /&gt;
=== Error 4123: Corrupted B-tree Index ===&lt;br /&gt;
&lt;br /&gt;
This error may occur when a very large table, typically 500,000 records or more, is combined with a long or complex index.&lt;br /&gt;
&lt;br /&gt;
In this situation, the index can become too large or too complex for the system to process reliably, resulting in:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Error 4123 corrupted Btree Index&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Common cause:&#039;&#039;&#039;&lt;br /&gt;
* A large number of records&lt;br /&gt;
* A long index key&lt;br /&gt;
* A complex index expression&lt;br /&gt;
* A combination of the above&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Typical threshold:&#039;&#039;&#039;&lt;br /&gt;
* Approximately 500,000 records or more, depending on the index design&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Recommendation:&#039;&#039;&#039;&lt;br /&gt;
Review the index definition and simplify it where possible. Consider reducing the number of fields in the index, shortening indexed values, or using a less complex index expression.&lt;br /&gt;
&lt;br /&gt;
==Comments and Examples==&lt;br /&gt;
Index works both in [[procedure files]] and as a separate [[:Category:Commands|command]]. It performs a [[CLEAR]] operation, except when a program is active, and creates or recreates the index file as specified.&lt;br /&gt;
&lt;br /&gt;
The following command replaces INDEX.FIL, if it already exists, with a new index file for the master file MASTER.FIL. The key is a field that starts at position 10 and consists of 5 characters:&lt;br /&gt;
&lt;br /&gt;
 INDEX MASTER.FIL INDEX.FIL 10 5 REPLACE&lt;br /&gt;
&lt;br /&gt;
The next command creates a new index file HIST.KEY for the master file HISTORY. The first key is a field that starts at position 1 and consists of 4 characters. The second key starts at position 10 and has 2 characters, and the third field starts at position 20 and has 2 characters:&lt;br /&gt;
&lt;br /&gt;
 INDEX HISTORY HIST.KEY 1/10/20 4/2/2&lt;br /&gt;
&lt;br /&gt;
In the following example, INDEX reorganizes the existing CUST.KEY index file. However, if CUST.KEY does not exist, a new index file by the same name is built. The REORG parameter greatly speeds up the INDEX command because it takes advantage of the part of the key file that is already in sorted order. The first key field starts at position 1 and consists of 6 characters. The second key field starts at position 4 and consists of 3 characters. &#039;&#039;&#039;Note&#039;&#039;&#039; that the key fields overlap.&lt;br /&gt;
&lt;br /&gt;
 	INDEX CUSTOMER CUST.KEY 1/4 6/3 REORG&lt;br /&gt;
&lt;br /&gt;
The next example builds a new index file called PAY.KEY for the PAYROLL master file. The key field starts at position 1 and consists of 6 characters. This command allows duplicate keys, and it sends a listing of duplicate keys to the file DUP. No warning error will occur if duplicate keys are encountered. &#039;&#039;&#039;Note&#039;&#039;&#039; that the parameters in this Index command are separated by commas rather than by spaces:&lt;br /&gt;
&lt;br /&gt;
 INDEX PAYROLL,PAY.KEY,1,6,DUPKEYS,LISTDUPKEYS &amp;gt;DUP&lt;br /&gt;
&lt;br /&gt;
Also note that the creation of indexes can be interrupted with Ctrl-A, and can then be resumed with GO.&lt;br /&gt;
&lt;br /&gt;
==Defaults==&lt;br /&gt;
# Use space on the current default drive and directory as temporary work space.&lt;br /&gt;
# Display a record of duplicate keys on the screen.&lt;br /&gt;
# Send an error if duplicate keys are found; use the collating sequence specified in the BRConfig.sys file (or by the most recent CONFIG command); completely build (or rebuild) the specified index; send an error message and abort the index procedure if the specified index file already exists.&lt;br /&gt;
&lt;br /&gt;
==Parameters==&lt;br /&gt;
The &#039;&#039;&#039;data file name&#039;&#039;&#039; parameter specifies the name of the data file for the index you wish to create.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Index file name&#039;&#039;&#039; specifies the name of the index file for the desired index.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1st key start position&#039;&#039;&#039; and &#039;&#039;&#039;next key start position&#039;&#039;&#039; specify the starting record positions of each key field. Up to &#039;&#039;&#039;six&#039;&#039;&#039; starting positions may be specified.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1st key length&#039;&#039;&#039; and &#039;&#039;&#039;next key length&#039;&#039;&#039; parameters indicate the number of characters contained in each key field. Each &#039;&#039;&#039;key length&#039;&#039;&#039; specification must correlate to a &#039;&#039;&#039;key starting position&#039;&#039;&#039; specification. The specifications match up according to ordinal position. The first key starting pos correlates to the first key length specification.&lt;br /&gt;
&lt;br /&gt;
The indexing process requires availability of a temporary work space. The optional &#039;&#039;&#039;work path&#039;&#039;&#039; parameter specifies a location somewhere other than the default drive and directory for this work space.&lt;br /&gt;
&lt;br /&gt;
If you decide to allow duplicate keys in the index, you can use &#039;&#039;&#039;DUPKEYS&#039;&#039;&#039; to prevent the corresponding error message 7603 from appearing on the screen.&lt;br /&gt;
&lt;br /&gt;
As the index is being created, &#039;&#039;&#039;LISTDUPKEYS&#039;&#039;&#039; lists all duplicate keys on the screen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;gt;Redirected output File&#039;&#039;&#039; saves LISTDUPKEYS information that would normally be displayed on the screen to a text file.&lt;br /&gt;
&#039;&#039;&#039;&amp;gt;&amp;gt;Redirected output File&#039;&#039;&#039; appends LISTDUPKEYS information to an existing text file.&lt;br /&gt;
Programs can use input from this file to report on or delete the duplicate keys.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NATIVE&#039;&#039;&#039; causes the Index command to use native collating sequence. This parameter should be used when the following two conditions are true: an index is being performed on a packed decimal field, and COLLATE ALTERNATE has been specified for the rest of the program.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;REORG&#039;&#039;&#039; can be used to reorganize index files directly, without reading the master file. This can greatly speed up the re-indexing process, especially on network systems, because the already sorted portion of the index file will not be sorted again. If the index file has already been fully sorted, BR will read only the header record and then quit the re-indexing process immediately.&lt;br /&gt;
&lt;br /&gt;
It is important to note that the REORG parameter will generally not cause new records to be added to the index file. It is the responsibility of the programmer to be sure that index file&#039;s overflow area is updated with added records before REORG performs its operation. This can be done by always opening the index file when writing to the master file.&lt;br /&gt;
&lt;br /&gt;
There are three cases in which INDEX with the REORG parameter will completely build an index file:&lt;br /&gt;
# When the index file does not exist.&lt;br /&gt;
# When the specified file is not an index file.&lt;br /&gt;
# When any of the key starting pos or key length parameters stored in the header record are different from those specified in the INDEX REORG command.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;REPLACE&#039;&#039;&#039; specifies that the current index should replace an index of the same name if it exists on the disk. BR expects to create a new file when this parameter is not specified.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;-N&#039;&#039;&#039; option suppresses all information that would normally be output (except LISTDUPKEYS information).&lt;br /&gt;
&lt;br /&gt;
==BADKEYS==&lt;br /&gt;
{{:Badkeys}}&lt;br /&gt;
&lt;br /&gt;
==Special Considerations==&lt;br /&gt;
&lt;br /&gt;
The Index command may be executed in a program as part of the [[EXECUTE]] statement. If a program is active, this method of running the INDEX command does not CLEAR memory.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;When the starting key position and key length parameters are both specified as 0, INDEX will now use the key parameters as they exist in the key file.&#039;&#039; The REPLACE parameter is assumed. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The INDEX command may now include a SHR parameter. This allows another workstation to access the master file while indexing. For example:&lt;br /&gt;
&lt;br /&gt;
 INDEX master.fil index.fil 1 4 REPLACE SHR&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039; that SHR should be used only for making temporary indexes because master files normally should not be modified when rebuilding indexes. When INDEX is used with the SHR parameter, all records in the master file can be accessed by the INDEX command, even if a record is locked by another user. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For &#039;&#039;case insensitive key file access&#039;&#039; place a U after the key length or key starting position parameters. This causes the program to keep that key field as uppercase. Whenever a record is written, the key field is converted to uppercase before it is written to the key file (master record is unchanged) and whenever the file is read with KEY=, the parts of the key that need to be converted to uppercase are converted before the key look up.&lt;br /&gt;
&lt;br /&gt;
This is useful for looking up names, where the capitalization of the data on file and the key entered by the operator may be inconsistent. This also permits sequential processing of a keyed file in alpha order without regard to the case of the data. &#039;&#039;&#039;Note&#039;&#039;&#039; that even though BR stores the key as uppercase, the resulting processing occurs as if the case is ignored. In other words, &#039;A&#039; and &#039;a&#039; are considered equal.&lt;br /&gt;
&lt;br /&gt;
The following code writes data as is to the master file, but writes all uppercase characters to the key file.&lt;br /&gt;
&lt;br /&gt;
 00010 OPEN #1:&amp;quot;name=XXX,kfname=XXX.key,replace,recl=63,kps=1,kln=4u&amp;quot;,INTERNAL,OUTIN,KEYED&lt;br /&gt;
 00020 WRITE #1,USING 30: &amp;quot;aaAA&amp;quot;&lt;br /&gt;
 00030 FORM C 4&lt;br /&gt;
 00040 READ #1,USING 30,KEY=&amp;quot;AAaa&amp;quot;: X$&lt;br /&gt;
 00050 PRINT X$&lt;br /&gt;
&lt;br /&gt;
 INDEX MASTER.FIL KEY.FIL 1/3 2/2U REPLACE&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If a key field is a two digit year it should be flagged as such so BR will use [[BaseYear]] when comparing values for sorting purposes. Place the letter Y after either the field position or its length. &lt;br /&gt;
&lt;br /&gt;
 INDEX MASTER.FIL KEY.FIL 1/3 2/2Y REPLACE&lt;br /&gt;
&lt;br /&gt;
If a two digit year is stored in binary or packed decimal form, the INDEX command needs to indicate that by following the Y with either P or D as in:&lt;br /&gt;
&lt;br /&gt;
 INDEX MASTER.FIL KEY.FIL 1/3 2/2YB REPLACE&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The INDEX command defaults to B-tree indexing unless OPTION 5 is used in the BRConfig.sys file to set the universal default to ISAM or the ISAM parameter is used within the syntax of the INDEX command to override the B-tree default on an individual basis. If OPTION 5 is specified in BRConfig.sys, the INDEX command&#039;s BTREE parameter can be used to override the ISAM default on an individual basis.&lt;br /&gt;
&lt;br /&gt;
;INDEX will completely rebuild the [[B-tree]] index when any of the following three conditions is true:&lt;br /&gt;
:1) When the REPLACE parameter is specified in the INDEX command,&lt;br /&gt;
:2) When INDEX REORG is specified and the key starting positions and/or lengths in the existing index file are different than those specified on the INDEX command, or&lt;br /&gt;
:3) When INDEX REORG is specified and the key file does not exist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The syntax of the INDEX command allows the BTREE or ISAM parameters, as follows:&lt;br /&gt;
&lt;br /&gt;
 INDEX file.dat,file.idx,1,2,REPLACE,ISAM&lt;br /&gt;
 INDEX file.dat,file.idx,1,2,REPLACE,BTREE&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Commands]]&lt;br /&gt;
[[Category:Facility Commands]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Encryption&amp;diff=11505</id>
		<title>Encryption</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Encryption&amp;diff=11505"/>
		<updated>2026-04-03T03:20:11Z</updated>

		<summary type="html">&lt;p&gt;GomezL: Document Status Encrypt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;(As of 4.30)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Encryption&#039;&#039;&#039; encompasses a number of different operations.  These operations can be used independently or in combination to meet different needs.  We use industry standard encryption available through OpenSSL.  Three technologies are widely used for encrypting data. BR supports the first two listed below through its [[ENCRYPT]] and [[DECRYPT]] [[internal functions]]. &lt;br /&gt;
&lt;br /&gt;
==Overview of Two Encryption Methods==&lt;br /&gt;
&lt;br /&gt;
1. &#039;&#039;&#039;Symmetric key ciphers&#039;&#039;&#039; – where the same key is used to encrypt and decrypt data. You can specify a key to encrypt some data and later use the same key to decrypt the data.&lt;br /&gt;
&lt;br /&gt;
2. &#039;&#039;&#039;Hashing routines&#039;&#039;&#039; – one way routines that take data and convert it to a hash value.  Sometimes these are thought of as checksums such as MD5 sum.  Hash values are always the same length regardless of how big the hashed data is.  A 10 gb file will have a hash result that is the same length as a 200 byte file. Hashing routines have a number of specific uses, including:&lt;br /&gt;
*Verify that data has not changed.&lt;br /&gt;
*Verifying that two files are the same.&lt;br /&gt;
*Validating passwords – this is based on the concept that if two values have the same hash value the values are equal.  Using this technique improves security because it allows a server to store passwords in an unrecoverable format.  Even the server software is unable to regenerate the original password.  It is only capable of checking if the hash of a password matches the stored password hash.&lt;br /&gt;
&lt;br /&gt;
==Symmetric Key Ciphers==&lt;br /&gt;
There are two encryption functions in the BR language, [[ENCRYPT$]] and [[DECRYPT$]].&lt;br /&gt;
&lt;br /&gt;
 ENCRYPT$(Data$ [,Key$ [,Encryption-type$ [,Initialization-vector$]]])&lt;br /&gt;
 DECRYPT$(Data$ [,Key$ [,Encryption-type$ [,Initialization-vector$]]])&lt;br /&gt;
&lt;br /&gt;
Data$ - The data to be encrypted&lt;br /&gt;
&lt;br /&gt;
Key$ - The secret key to be used for encryption.  If not specified this value will come from an OPTION 66 statement.&lt;br /&gt;
&lt;br /&gt;
Encryption-type$ - The type of encryption to be done.  If not specified, a common high strength encryption type will be employed.  This is described in more detail below, but is generally only useful for interfacing with other typically non-BR programs.&lt;br /&gt;
&lt;br /&gt;
Initialization-vector$ - This is an arcane part of encryption standards. It exists to prevent attackers from being able to tell whether the unencrypted data has changed. This is described in more detail below, but is general only needed when interfacing with other non-BR programs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interfacing With Other Programs (encryption type and initialization vector)==&lt;br /&gt;
There are a number of different types of encryption that BR supports through OpenSSL:  AES, BLOWFISH, DES, triple DES, RC4 and RC2.  Most symmetric key ciphers are block ciphers meaning that they encrypt one block at a time. This means if you have a bit message, it is broken up into multiple blocks and each block is encrypted. The block size can be set as (128, 192, 256) bits. Some encryption types don&#039;t support all of these values so STATUS ENCRYPTION should be checked to see what encryption types are available in BR. Besides block size, there are also various schemes for blocking data. One might expect that using 256 bit blocking would simply take every 32 bytes and call it a block.  This is not done though because there is a possibility that this would cause patterns in the encrypted data. To prevent this, there are various schemes known as codebooks which change the way data is blocked. Wikipedia explains this in more detail. If the encryption type is not specified AES:256:CBC:128 will be used. To be compatible with other programs the entire encryption type must be specified (cipher: key length: codebook: initialization vector length).&lt;br /&gt;
&lt;br /&gt;
Initialization-vector – this is used to cause the same data encrypted with the same key to have a different encrypted result. This is significant because otherwise an attacker looking at data seeing the same encrypted result twice would know that the key and the unencrypted data have not changed. Regardless of whether or not you are concerned about this potential security issue, the standard encryption methods require this value so interfacing with other programs may require you to use it. It is a common practice to use a random number for this value and store the value at the beginning of (ahead of) the encrypted result. This is what BR does if this parameter is omitted.&lt;br /&gt;
&lt;br /&gt;
As an example:&lt;br /&gt;
 ENCRYPT$(“test”,“key”) &lt;br /&gt;
Produces a string containing “random number initialization vector”&amp;amp;”encrypted result”.&lt;br /&gt;
&lt;br /&gt;
If the initialization vector is explicitly specified as in:&lt;br /&gt;
ENCRYPT$(“test”,“key”,“AES:256:CBC:128”,“RANDOM”) &lt;br /&gt;
the result would be simply “encrypted result”.&lt;br /&gt;
&lt;br /&gt;
DECRYPT$ has the same arguments as ENCRYPT$ with the exception of the first parameter which is the encrypted data. DECRYPT$ expects to be used with the same key$, encryption-type$, and initialization-vector$ as was used to encrypt the data.  As with ENCRYPT$, if key$ is not specified, the value from the OPTION statement will be used. If encryption-type$ is not specified, “AES:256:CBC:128” will be used. If the initialization vector is not specified, it will be assumed that the encrypted data starts with an initialization vector.&lt;br /&gt;
&lt;br /&gt;
==Hashing Routines==&lt;br /&gt;
Three common forms of hashing are allowed in BR. They are MD5, SHA, and SHA-1. These are also provided through the ENCRYPT$ function specifying a null key$ value:&lt;br /&gt;
&lt;br /&gt;
 ENCRYPT$(data$, “”, “MD5”) ENCRYPT$(data$, “”, “SHA”) ENCRYPT$(data$, “”, “SHA-1”)&lt;br /&gt;
&lt;br /&gt;
Hashing is also referred to as Message Digests or digests. This is what the MD in MD5 means. There is no way to restore data that has been hashed. Hashing is a one way function so DECRYPT$ will yield an error.&lt;br /&gt;
&lt;br /&gt;
==Asymmetric Encryption==&lt;br /&gt;
Asymmetric key encryption is also known as public/private key encryption.&lt;br /&gt;
&lt;br /&gt;
Public/private keys are created as a pair by a key generator.  They are a pair, and it is not possible to have two public keys for the same private key or vice versa. With regard to public/private key pairs, what one key encrypts the other key can decrypt, and neither key can decrypt what it has encrypted.  When a private key is used to encrypt data, the result is called a signature because everyone who has the public key can decrypt it.&lt;br /&gt;
&lt;br /&gt;
This technique is used for:&lt;br /&gt;
&lt;br /&gt;
Signing (using certificates) – A private key can be used to sign data. The result of such signing can be tested/validated with the corresponding public key.&lt;br /&gt;
&lt;br /&gt;
Data encryption – A public key can be used to encrypt data. This data can then only be decrypted by the corresponding private key.&lt;br /&gt;
&lt;br /&gt;
Hashes and signing are different but used together.  Rather than signing a large block of data which would create a large signature, only the hash is signed to create much smaller fixed length signature data.  When verifying a large block of signed data, the data is used to create a hash value and the hash value is compared to a decrypted signature.&lt;br /&gt;
&lt;br /&gt;
Asymmetric encryption is not accessible through the BR ENCRYPT$, DECRYPT$ functions. However, it is used by our SSL client server connections and HTTPS. Certificates are most commonly used by SSL and HTTPS and are less useful for other application processes. &lt;br /&gt;
&lt;br /&gt;
In the Client Server model the client knows the server’s public key and the server uses its private key to encrypt and decrypt.  BRclient.exe connects to BRListener.exe by opening an SSL socket on the server using DHE_RSA-AES256-SHA Encryption. Handshaking is performed using a private key stored on the server within BRListener. Once authenticated, the socket is then passed to BRServer.exe for actual data processing.&lt;br /&gt;
&lt;br /&gt;
Encryption is invoked by Business Rules HTTP support as follows:&lt;br /&gt;
&lt;br /&gt;
 CONFIG HTTPS port-number   [ LOG file-pathname ] [CERT= cert-file-basename]&lt;br /&gt;
 CONFIG OPTION  66   private-key-file-encryption-password&lt;br /&gt;
 OPEN #400: “HTTP=SERVER”, DISPLAY, OUTIN&lt;br /&gt;
&lt;br /&gt;
The BRSERVER executable directory must contain two files:&lt;br /&gt;
&lt;br /&gt;
 https-private.pem&lt;br /&gt;
 https-cert.pem&lt;br /&gt;
&lt;br /&gt;
These files are made by the following commands under Linux, MAC and cygwin for Windows: openssl req -new -x509 -out httpserver.pem -days 10000&lt;br /&gt;
&lt;br /&gt;
(this will prompt for the OPTION 66 password)&lt;br /&gt;
&lt;br /&gt;
 mv privkey.pem   https-private.pem&lt;br /&gt;
 mv httpserver.pem   https-cert.pem&lt;br /&gt;
&lt;br /&gt;
This port specific service can then be accessed with browsers. When the specified port is accessed through a browser, BR establishes an HTTPS connection rather than an HTTP connection.&lt;br /&gt;
&lt;br /&gt;
==Signing and Certificate Processing Industry Standards==&lt;br /&gt;
The purpose of certificates is to verify the authenticity of unencrypted data. &lt;br /&gt;
&lt;br /&gt;
Certain companies are authorized by the government to act as a Certificate Authority (CA). These companies (e.g. Verisign) issue electronic certificates which can be used to issue second level certificates. Certificates can have expiration dates and the line of authority extends from a CA to any number of levels (but a chain is only as strong as its weakest link). Certificates contain a list of signatures (described below) that trace back to a CA as follows: &lt;br /&gt;
&lt;br /&gt;
When a company needs to obtain a certificate from a CA, it prepares its own certificate and sends it to the CA for signature. Creating a certificate requires the pre-production of a private and public key pair. The certificate text properly identifies the signing authority, the owner of the certificate, and the owner’s public key. The signing authority externally verifies the identity of the owner before signing it.  The CA provides the signature and the CA’s own public key for validating it. &lt;br /&gt;
&lt;br /&gt;
Browsers know the CA identities and their public keys. A browser can verify a CA signed cert by hashing it, decrypting the signature with the known public key and matching the decrypted signature against the hash total. &lt;br /&gt;
 &lt;br /&gt;
Any company that is issued a (self-prepared authority signed) certificate by a CA can sign second level certificates issued to third parties. A second level cert contains the parent (CA issued) certificate, and includes the public keys of the issuer and the recipient. The signature is essentially the encrypted hash total of ‘itself plus all of its ancestors’. Additional levels each contain the chain of certificates leading from a CA issued cert to itself. By including public keys along with the identities of the owners, certificates become tools for validating the signatures of their owners. When signed data (with an encrypted hash total) is sent to clients the signatures insure that the data has not been altered along the way. &lt;br /&gt;
&lt;br /&gt;
Ostensibly, a certificate cannot be counterfeited because it requires the signature of its parent which can only be produced with its parent’s private key.  By providing both public keys ( signer and recipient ) in all certs along with signatures, a non-forgeable or alterable chain is established. &lt;br /&gt;
&lt;br /&gt;
====Example:====&lt;br /&gt;
CA public key – known to browser&lt;br /&gt;
certificate 1 (signed by CA – contains owner’s public key)&lt;br /&gt;
certificate 2 (signed by second level - includes certificate 1 - contains owner’s public key)&lt;br /&gt;
final certificate (signed by third level - includes certificate 2 - contains owner’s public key)&lt;br /&gt;
 &lt;br /&gt;
A browser would find the CA information in the certificate and check to see if it is in the browser’s internal list. If not, it fails. Then it verifies that certificate 1 (which ends up being part of the final certificate) has been signed by the CA. After that it checks certificate 2 and verifies that it has been signed by the owner of certificate 1. Finally it checks the final certificate and verifies that it has been signed by the owner of certificate 2.&lt;br /&gt;
&lt;br /&gt;
To assure the line authority of any certificate, the public keys are associated with signers, not with documents. &lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;Encryption Support by Version&#039;&#039;&#039;==&lt;br /&gt;
&lt;br /&gt;
BR encryption support has evolved over time. The sections below distinguish between currently supported legacy algorithms, deprecated (removed) algorithms, and newer additions.&lt;br /&gt;
&lt;br /&gt;
==Old List (Still Supported)==&lt;br /&gt;
&lt;br /&gt;
The following algorithms are supported for backward compatibility and remain available in current versions:&lt;br /&gt;
&lt;br /&gt;
===Symmetric Key Ciphers===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DES (all modes)&lt;br /&gt;
DES-EDE / DES-EDE3 (Triple DES)&lt;br /&gt;
RC4 (40, 128)&lt;br /&gt;
RC2 (40, 64, 128)&lt;br /&gt;
BF (Blowfish)&lt;br /&gt;
CAST5&lt;br /&gt;
AES:128 / 192 / 256 (ECB, CBC, CFB, OFB)&lt;br /&gt;
IDEA&lt;br /&gt;
CAMELLIA:128 / 192 / 256&lt;br /&gt;
SEED&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Message Digest Algorithms===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MD5&lt;br /&gt;
SHA-1&lt;br /&gt;
MDC-2&lt;br /&gt;
RIPEMD-160&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Deprecated (Removed / No Longer Available)==&lt;br /&gt;
&lt;br /&gt;
The following algorithms were available in earlier versions but are no longer exposed in current builds:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SHA   (original / alias)&lt;br /&gt;
DSS&lt;br /&gt;
DSS-1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These were removed due to obsolescence or lack of modern security relevance.&lt;br /&gt;
&lt;br /&gt;
==In Development (Newer Additions)==&lt;br /&gt;
&lt;br /&gt;
===Added in Version 4.31hdg===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SHA-256&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==STATUS ENCRYPTION==&lt;br /&gt;
&lt;br /&gt;
The command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
STATUS ENCRYPTION&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays the encryption and digest algorithms supported by the currently running BR executable. This is the authoritative source for determining which algorithms are available.&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&lt;br /&gt;
* Default encryption:&lt;br /&gt;
  &amp;lt;code&amp;gt;AES:256:CBC:128&amp;lt;/code&amp;gt;&lt;br /&gt;
* If no initialization vector is provided, BR prepends a random IV to the encrypted output.&lt;br /&gt;
* DECRYPT$ must use the same parameters as ENCRYPT$.&lt;br /&gt;
&lt;br /&gt;
==Wishlist: Future Encryption Types==&lt;br /&gt;
&lt;br /&gt;
The following modern algorithms are supported by OpenSSL but not currently exposed in BR:&lt;br /&gt;
&lt;br /&gt;
* AES:128:GCM:96&lt;br /&gt;
* AES:192:GCM:96&lt;br /&gt;
* AES:256:GCM:96&lt;br /&gt;
* HMAC-SHA-256&lt;br /&gt;
* HMAC-SHA-512&lt;br /&gt;
* SHA-512&lt;br /&gt;
* ChaCha20-Poly1305&lt;br /&gt;
* PBKDF2 (password hashing)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Definitions]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=MAX_SORT_MEMORY&amp;diff=11504</id>
		<title>MAX SORT MEMORY</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=MAX_SORT_MEMORY&amp;diff=11504"/>
		<updated>2026-03-22T19:28:03Z</updated>

		<summary type="html">&lt;p&gt;GomezL: /* Notes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This [[CONFIG]] option sets the maximum memory allowed for SORT and INDEX operations &#039;&#039;(in megabytes)&#039;&#039;. This is a [[BRconfig.sys]] statement.&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MAX_SORT_MEMORY &amp;lt;integer&amp;gt; MB&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:msm.png|400px]]&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
Specifies the maximum number of megabytes BR should use for sorting and indexing.&lt;br /&gt;
&lt;br /&gt;
* Default: 8 MB  &lt;br /&gt;
* Allowed range: 2–512 MB  &lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG MAX_SORT_MEMORY 512 MB&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
* The ``MB`` suffix is required after the integer value.&lt;br /&gt;
* This setting is a balance between CPU / Hard Disk Speed and available memory.&lt;br /&gt;
* Do not assume that bigger is better.   &lt;br /&gt;
* 64 MB may be the sweet spot for your system.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Config]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=MAX_SORT_MEMORY&amp;diff=11503</id>
		<title>MAX SORT MEMORY</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=MAX_SORT_MEMORY&amp;diff=11503"/>
		<updated>2026-03-22T17:10:53Z</updated>

		<summary type="html">&lt;p&gt;GomezL: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This [[CONFIG]] option sets the maximum memory allowed for SORT and INDEX operations &#039;&#039;(in megabytes)&#039;&#039;. This is a [[BRconfig.sys]] statement.&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MAX_SORT_MEMORY &amp;lt;integer&amp;gt; MB&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:msm.png|400px]]&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
Specifies the maximum number of megabytes BR should use for sorting and indexing.&lt;br /&gt;
&lt;br /&gt;
* Default: 8 MB  &lt;br /&gt;
* Allowed range: 2–512 MB  &lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG MAX_SORT_MEMORY 512 MB&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
* The ``MB`` suffix is required after the integer value.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Config]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=MAX_SORT_MEMORY&amp;diff=11502</id>
		<title>MAX SORT MEMORY</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=MAX_SORT_MEMORY&amp;diff=11502"/>
		<updated>2026-03-22T17:09:26Z</updated>

		<summary type="html">&lt;p&gt;GomezL: Document required MB and allowed values&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This [[CONFIG]] option sets the maximum memory allowed for SORT and INDEX operations &#039;&#039;(in megabytes)&#039;&#039;. This is a [[BRconfig.sys]] statement.&lt;br /&gt;
&lt;br /&gt;
== Syntax ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MAX_SORT_MEMORY &amp;lt;integer&amp;gt; MB&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:msm.png|400px]]&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
Specifies the maximum number of megabytes BR should use for sorting and indexing.&lt;br /&gt;
&lt;br /&gt;
* Default: 8 MB  &lt;br /&gt;
* Allowed range: 2–512 MB  &lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CONFIG MAX_SORT_MEMORY 512 MB&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
* The ``MB`` suffix is required after the integer value.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Config]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=%5EKeyStroke_and_%5EDataChg&amp;diff=11495</id>
		<title>^KeyStroke and ^DataChg</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=%5EKeyStroke_and_%5EDataChg&amp;diff=11495"/>
		<updated>2026-02-05T19:46:32Z</updated>

		<summary type="html">&lt;p&gt;GomezL: Show Sample for ^DataCHG&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;As of [[4.30]], two new [[INPUT FIELDS]] field attributes are now supported which provide detailed control of user input:&lt;br /&gt;
*^KEYSTROKE - return control to the program when a keystroke is entered&lt;br /&gt;
*^DATACHG - return control to the program when data is changed&lt;br /&gt;
(a subset of ^KEYSTROKE)&lt;br /&gt;
&lt;br /&gt;
When control is returned to a program as a result of these attributes, one of three new [[Fkey]] values is applied:&lt;br /&gt;
&lt;br /&gt;
*140 - a character was appended to the data&lt;br /&gt;
*141 - the data changed other than appending a character&lt;br /&gt;
*142 - ( applies only to ^KEYSTROKE ) the data is unchanged but a key was pressed or a mouse action occurred that did not trigger a field exit&lt;br /&gt;
&lt;br /&gt;
When a key is pressed with ^KEYSTROKE or ^DATACHG that sets a 140, 141 or 142 FKEY, it will also set the [[KStat$]] value.  This allows the program to see what key was pressed. This KSTAT$ value will be cleared on the next [[RINPUT Fields]] operation. &lt;br /&gt;
&lt;br /&gt;
If a navigation key operates within the field and ^KEYSTROKE is specified, it triggers fkey 142. If the navigation key causes focus to leave the field, fkeys 140-142  are not generated and KSTAT is not set. &lt;br /&gt;
&lt;br /&gt;
===Sample===&lt;br /&gt;
 00001   PRINT Newpage&lt;br /&gt;
 00010   INPUT FIELDS &amp;quot;10,10,C 10,[D]S^DataCHGC&amp;quot;&amp;amp;Str$(New_Pos),ATTR &#039;[A]&#039;: Dummy$&lt;br /&gt;
 00020   PRINT FIELDS &amp;quot;1,70,n 10&amp;quot;: Fkey&lt;br /&gt;
 00025   LET New_Field$=Kstat$&lt;br /&gt;
 00026   LET New_Pos=Curpos&lt;br /&gt;
 00030   PRINT FIELDS &amp;quot;3,70,N 10&amp;quot;: New_Pos&lt;br /&gt;
 00040   PRINT FIELDS &amp;quot;4,70,C 10&amp;quot;: Unhex$(New_Field$)&amp;amp;&amp;quot; &amp;quot;&amp;amp;New_Field$&lt;br /&gt;
 00050   PRINT FIELDS &amp;quot;5,70,C 10&amp;quot;: Dummy$&lt;br /&gt;
 00090   LET Curfld(Curfld,Fkey) !:&lt;br /&gt;
         GOTO 10&lt;br /&gt;
 &lt;br /&gt;
The program triggers ^DATACHG and displays the FKEY along with the value that was pushed to KSTAT$.   Each keystrokeis processed.   The input allows granular control. &lt;br /&gt;
&lt;br /&gt;
;Note &lt;br /&gt;
While shift, control and alt do not change either the functionality or fkey value of navigation keys, KSTAT$ produces unique values for each of these settings. This complicates things a bit but provides more options for programmed responses to custom key combinations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:All Parameters]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=DEBUG_PROFILE&amp;diff=11493</id>
		<title>DEBUG PROFILE</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=DEBUG_PROFILE&amp;diff=11493"/>
		<updated>2025-09-12T17:23:21Z</updated>

		<summary type="html">&lt;p&gt;GomezL: /* Additional resources */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= BR Profiler Main Page =&lt;br /&gt;
&lt;br /&gt;
Use &#039;&#039;&#039;PROFILER.EXE&#039;&#039;&#039; to translate the BR Profiler output file into readable text.&lt;br /&gt;
&lt;br /&gt;
== Generating profiler output ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DEBUG PROFILE SAMPLED filename&lt;br /&gt;
DEBUG PROFILE TIMED filename&lt;br /&gt;
DEBUG PROFILE STOP&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Viewing profiler output ==&lt;br /&gt;
Use &#039;&#039;&#039;profiler.exe&#039;&#039;&#039; to view the contents of a log file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
profiler.exe filename&lt;br /&gt;
profiler.exe filename raw&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Additional resources ==&lt;br /&gt;
&lt;br /&gt;
* See the FTP site: &#039;&#039;Dll_Distr/Profiler&#039;&#039; for samples and documentation.&lt;br /&gt;
* [[Profiler File Layout]] — Detailed description of the profiler log file format.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Debug]]&lt;br /&gt;
[[Category:Profiler]]&lt;br /&gt;
[[Category:Tools]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=DEBUG_PROFILE&amp;diff=11492</id>
		<title>DEBUG PROFILE</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=DEBUG_PROFILE&amp;diff=11492"/>
		<updated>2025-09-12T17:22:55Z</updated>

		<summary type="html">&lt;p&gt;GomezL: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= BR Profiler Main Page =&lt;br /&gt;
&lt;br /&gt;
Use &#039;&#039;&#039;PROFILER.EXE&#039;&#039;&#039; to translate the BR Profiler output file into readable text.&lt;br /&gt;
&lt;br /&gt;
== Generating profiler output ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DEBUG PROFILE SAMPLED filename&lt;br /&gt;
DEBUG PROFILE TIMED filename&lt;br /&gt;
DEBUG PROFILE STOP&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Viewing profiler output ==&lt;br /&gt;
Use &#039;&#039;&#039;profiler.exe&#039;&#039;&#039; to view the contents of a log file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
profiler.exe filename&lt;br /&gt;
profiler.exe filename raw&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Additional resources ==&lt;br /&gt;
&lt;br /&gt;
* See the FTP site: &#039;&#039;Dll\_Distr/Profiler&#039;&#039; for samples and documentation.&lt;br /&gt;
* [[Profiler File Layout]] — Detailed description of the profiler log file format.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Debug]]&lt;br /&gt;
[[Category:Profiler]]&lt;br /&gt;
[[Category:Tools]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Profiler_File_Layout&amp;diff=11491</id>
		<title>Profiler File Layout</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Profiler_File_Layout&amp;diff=11491"/>
		<updated>2025-09-12T17:14:40Z</updated>

		<summary type="html">&lt;p&gt;GomezL: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Profiler Output File Format =&lt;br /&gt;
&lt;br /&gt;
The profiler output file will be a sequence of variable-length records of various types. The first byte of each record provides the record type, while the length and record information are record-type specific. All numbers are in &#039;&#039;&#039;network byte order&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== CREATE MODULE MAPPING ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Byte 1:&#039;&#039;&#039; 1&lt;br /&gt;
* &#039;&#039;&#039;Byte 2–3:&#039;&#039;&#039; 16-bit module number&lt;br /&gt;
* &#039;&#039;&#039;Byte 4–5:&#039;&#039;&#039; 16-bit File Name Length&lt;br /&gt;
* &#039;&#039;&#039;Byte 6–end:&#039;&#039;&#039; File Name&lt;br /&gt;
&lt;br /&gt;
== CURRENT LINE ==&lt;br /&gt;
Current line information begins with this record and ends with an &#039;&#039;&#039;END CURRENT LINE&#039;&#039;&#039; record.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Byte 1:&#039;&#039;&#039; 3&lt;br /&gt;
* &#039;&#039;&#039;Byte 2–3:&#039;&#039;&#039; module number&lt;br /&gt;
* &#039;&#039;&#039;Byte 4–7:&#039;&#039;&#039; line number&lt;br /&gt;
* &#039;&#039;&#039;Byte 8:&#039;&#039;&#039; clause number&lt;br /&gt;
&lt;br /&gt;
== TIME SPENT IN LINE ==&lt;br /&gt;
These records exist only for timed sampling. They always occur between &#039;&#039;&#039;CURRENT LINE&#039;&#039;&#039; and &#039;&#039;&#039;END CURRENT LINE&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Byte 1:&#039;&#039;&#039; 4&lt;br /&gt;
* &#039;&#039;&#039;Byte 2–9:&#039;&#039;&#039; 8-byte time spent in line (nanoseconds)&lt;br /&gt;
&lt;br /&gt;
== BACKTRACE INFORMATION ==&lt;br /&gt;
These records may or may not exist depending on creation options. They always occur between &#039;&#039;&#039;CURRENT LINE&#039;&#039;&#039; and &#039;&#039;&#039;END CURRENT LINE&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Note: Apart from the record type identifier, these records have the same format as &#039;&#039;&#039;CURRENT LINE&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Byte 1:&#039;&#039;&#039; 5&lt;br /&gt;
* &#039;&#039;&#039;Byte 2–3:&#039;&#039;&#039; module number&lt;br /&gt;
* &#039;&#039;&#039;Byte 4–7:&#039;&#039;&#039; line number&lt;br /&gt;
* &#039;&#039;&#039;Byte 8:&#039;&#039;&#039; clause number&lt;br /&gt;
&lt;br /&gt;
== FUNCTION NAME ==&lt;br /&gt;
These records may or may not exist depending on creation options. They follow immediately after either &#039;&#039;&#039;CURRENT LINE&#039;&#039;&#039; or &#039;&#039;&#039;BACKTRACE INFORMATION&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Byte 1:&#039;&#039;&#039; 7&lt;br /&gt;
* &#039;&#039;&#039;Byte 2:&#039;&#039;&#039; 8-bit name length&lt;br /&gt;
* &#039;&#039;&#039;Byte 3–on:&#039;&#039;&#039; function name&lt;br /&gt;
&lt;br /&gt;
== GOSUB ==&lt;br /&gt;
These records may or may not exist depending on creation options. They follow immediately after either &#039;&#039;&#039;CURRENT LINE&#039;&#039;&#039; or &#039;&#039;&#039;BACKTRACE INFORMATION&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Byte 1:&#039;&#039;&#039; 8&lt;br /&gt;
&lt;br /&gt;
== MAIN ROUTINE ==&lt;br /&gt;
These records may or may not exist depending on creation options. They follow immediately after either &#039;&#039;&#039;CURRENT LINE&#039;&#039;&#039; or &#039;&#039;&#039;BACKTRACE INFORMATION&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This indicates that the given line is neither in a GOSUB nor in a function body.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Byte 1:&#039;&#039;&#039; 9&lt;br /&gt;
&lt;br /&gt;
== END CURRENT LINE ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Byte 1:&#039;&#039;&#039; 6&lt;br /&gt;
&lt;br /&gt;
= Potential Syntax =&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;DEBUG PROFILE SAMPLED filename&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DEBUG PROFILE TIMED filename&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DEBUG PROFILE STOP&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Profiler.exe ==&lt;br /&gt;
To use the profiler.exe available on the ftp site in /Dll_Distr/profiler to get a nice listing of what is in the log file use.&lt;br /&gt;
* profiler.exe filename&lt;br /&gt;
or&lt;br /&gt;
* profiler.exe filename raw&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Profiler_File_Layout&amp;diff=11490</id>
		<title>Profiler File Layout</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Profiler_File_Layout&amp;diff=11490"/>
		<updated>2025-09-12T17:10:42Z</updated>

		<summary type="html">&lt;p&gt;GomezL: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Profiler Output File Format =&lt;br /&gt;
&lt;br /&gt;
The profiler output file will be a sequence of variable-length records of various types. The first byte of each record provides the record type, while the length and record information are record-type specific. All numbers are in &#039;&#039;&#039;network byte order&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== CREATE MODULE MAPPING ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Byte 1:&#039;&#039;&#039; 1&lt;br /&gt;
* &#039;&#039;&#039;Byte 2–3:&#039;&#039;&#039; 16-bit module number&lt;br /&gt;
* &#039;&#039;&#039;Byte 4–5:&#039;&#039;&#039; 16-bit File Name Length&lt;br /&gt;
* &#039;&#039;&#039;Byte 6–end:&#039;&#039;&#039; File Name&lt;br /&gt;
&lt;br /&gt;
== CURRENT LINE ==&lt;br /&gt;
Current line information begins with this record and ends with an &#039;&#039;&#039;END CURRENT LINE&#039;&#039;&#039; record.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Byte 1:&#039;&#039;&#039; 3&lt;br /&gt;
* &#039;&#039;&#039;Byte 2–3:&#039;&#039;&#039; module number&lt;br /&gt;
* &#039;&#039;&#039;Byte 4–7:&#039;&#039;&#039; line number&lt;br /&gt;
* &#039;&#039;&#039;Byte 8:&#039;&#039;&#039; clause number&lt;br /&gt;
&lt;br /&gt;
== TIME SPENT IN LINE ==&lt;br /&gt;
These records exist only for timed sampling. They always occur between &#039;&#039;&#039;CURRENT LINE&#039;&#039;&#039; and &#039;&#039;&#039;END CURRENT LINE&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Byte 1:&#039;&#039;&#039; 4&lt;br /&gt;
* &#039;&#039;&#039;Byte 2–9:&#039;&#039;&#039; 8-byte time spent in line (nanoseconds)&lt;br /&gt;
&lt;br /&gt;
== BACKTRACE INFORMATION ==&lt;br /&gt;
These records may or may not exist depending on creation options. They always occur between &#039;&#039;&#039;CURRENT LINE&#039;&#039;&#039; and &#039;&#039;&#039;END CURRENT LINE&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Note: Apart from the record type identifier, these records have the same format as &#039;&#039;&#039;CURRENT LINE&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Byte 1:&#039;&#039;&#039; 5&lt;br /&gt;
* &#039;&#039;&#039;Byte 2–3:&#039;&#039;&#039; module number&lt;br /&gt;
* &#039;&#039;&#039;Byte 4–7:&#039;&#039;&#039; line number&lt;br /&gt;
* &#039;&#039;&#039;Byte 8:&#039;&#039;&#039; clause number&lt;br /&gt;
&lt;br /&gt;
== FUNCTION NAME ==&lt;br /&gt;
These records may or may not exist depending on creation options. They follow immediately after either &#039;&#039;&#039;CURRENT LINE&#039;&#039;&#039; or &#039;&#039;&#039;BACKTRACE INFORMATION&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Byte 1:&#039;&#039;&#039; 7&lt;br /&gt;
* &#039;&#039;&#039;Byte 2:&#039;&#039;&#039; 8-bit name length&lt;br /&gt;
* &#039;&#039;&#039;Byte 3–on:&#039;&#039;&#039; function name&lt;br /&gt;
&lt;br /&gt;
== GOSUB ==&lt;br /&gt;
These records may or may not exist depending on creation options. They follow immediately after either &#039;&#039;&#039;CURRENT LINE&#039;&#039;&#039; or &#039;&#039;&#039;BACKTRACE INFORMATION&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Byte 1:&#039;&#039;&#039; 8&lt;br /&gt;
&lt;br /&gt;
== MAIN ROUTINE ==&lt;br /&gt;
These records may or may not exist depending on creation options. They follow immediately after either &#039;&#039;&#039;CURRENT LINE&#039;&#039;&#039; or &#039;&#039;&#039;BACKTRACE INFORMATION&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This indicates that the given line is neither in a GOSUB nor in a function body.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Byte 1:&#039;&#039;&#039; 9&lt;br /&gt;
&lt;br /&gt;
== END CURRENT LINE ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Byte 1:&#039;&#039;&#039; 6&lt;br /&gt;
&lt;br /&gt;
= Potential Syntax =&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;DEBUG PROFILE SAMPLED filename&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DEBUG PROFILE TIMED filename&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DEBUG PROFILE STOP&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Profiler_File_Layout&amp;diff=11489</id>
		<title>Profiler File Layout</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Profiler_File_Layout&amp;diff=11489"/>
		<updated>2025-09-12T17:01:59Z</updated>

		<summary type="html">&lt;p&gt;GomezL: Created page with &amp;quot;The profiler output file will be a sequence of variable length records of various types.  The first byte of each record will provide the record type, the length and record information will be record type specific.  All numbers are network byte order.  CREATE MODULE MAPPING Byte 1: 1 Byte 2-3: 16 bit module number Byte 4-5: 16 bit File Name Length Byte 6-end: File Name  CURRENT LINE Current line information is started with this record and will be ended with a END CURRENT...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The profiler output file will be a sequence of variable length records of various types.  The first byte of each record will provide the record type, the length and record information will be record type specific.  All numbers are network byte order.&lt;br /&gt;
&lt;br /&gt;
CREATE MODULE MAPPING&lt;br /&gt;
Byte 1: 1&lt;br /&gt;
Byte 2-3: 16 bit module number&lt;br /&gt;
Byte 4-5: 16 bit File Name Length&lt;br /&gt;
Byte 6-end: File Name&lt;br /&gt;
&lt;br /&gt;
CURRENT LINE&lt;br /&gt;
Current line information is started with this record and will be ended with a END CURRENT LINE&lt;br /&gt;
record&lt;br /&gt;
Byte 1: 3&lt;br /&gt;
Byte 2-3: module number&lt;br /&gt;
Byte 4-7: line number&lt;br /&gt;
Byte 8: clause number&lt;br /&gt;
&lt;br /&gt;
TIME SPENT IN LINE &lt;br /&gt;
these records will only exist for timed sampling&lt;br /&gt;
they will always occur between CURRENT LINE and END CURRENT LINE&lt;br /&gt;
Byte 1: 4&lt;br /&gt;
Byte 2 – 9: 8 bit time spent in line in nano-seconds.&lt;br /&gt;
&lt;br /&gt;
BACKTRACE INFORMATION&lt;br /&gt;
these records may or may not exist depending on creation options&lt;br /&gt;
they will always occur between CURRENT LINE and END CURRENT LINE&lt;br /&gt;
Note: besides the record type identifier, these records have the same format as CURRENT LINE&lt;br /&gt;
Byte 1: 5&lt;br /&gt;
Byte 2-3: module number&lt;br /&gt;
Byte 4-7: line number&lt;br /&gt;
Byte 8: clause number&lt;br /&gt;
&lt;br /&gt;
FUNCTION NAME:&lt;br /&gt;
These records may or may not exist depending on creation options.&lt;br /&gt;
These records will follow immediately after either CURRENT LINE or BACKTRACE INFORMATION&lt;br /&gt;
Byte 1:7&lt;br /&gt;
Byte 2: 8-bit name length&lt;br /&gt;
Byte 3- on: function name&lt;br /&gt;
&lt;br /&gt;
GOSUB:&lt;br /&gt;
These records may or may not exist depending on creation options.&lt;br /&gt;
These records will follow immediately after either CURRENT LINE or BACKTRACE INFORMATION&lt;br /&gt;
Byte 1:8&lt;br /&gt;
&lt;br /&gt;
MAIN ROUTINE:&lt;br /&gt;
These records may or may not exist depending on creation options.&lt;br /&gt;
These records will follow immediately after either CURRENT LINE or BACKTRACE INFORMATION&lt;br /&gt;
This indicates that the given line is neither in a GOSUB or in a function body.&lt;br /&gt;
Byte 1:9&lt;br /&gt;
&lt;br /&gt;
END CURRENT LINE&lt;br /&gt;
Byte 1: 6&lt;br /&gt;
&lt;br /&gt;
Potential syntax&lt;br /&gt;
&lt;br /&gt;
DEBUG PROFILE SAMPLED filename&lt;br /&gt;
DEBUG PROFILE TIMED filename&lt;br /&gt;
DEBUG PROFILE STOP&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=DEBUG_PROFILE&amp;diff=11488</id>
		<title>DEBUG PROFILE</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=DEBUG_PROFILE&amp;diff=11488"/>
		<updated>2025-09-12T17:01:43Z</updated>

		<summary type="html">&lt;p&gt;GomezL: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Use PROFILER.EXE to translate the BR Profiler output file into readable text.&lt;br /&gt;
&lt;br /&gt;
To generate profiler output:&lt;br /&gt;
DEBUG PROFILE SAMPLED filename&lt;br /&gt;
or&lt;br /&gt;
DEBUG PROFILE TIMED filename&lt;br /&gt;
and&lt;br /&gt;
DEBUG PROFILE STOP to end the profile&lt;br /&gt;
&lt;br /&gt;
Also, to use the profiler.exe to get a nice listing of what is in the log file.&lt;br /&gt;
profiler.exe filename&lt;br /&gt;
or&lt;br /&gt;
profiler.exe filename raw&lt;br /&gt;
&lt;br /&gt;
See ftp site Dll_Distr/Profiler for samples and documentation.&lt;br /&gt;
&lt;br /&gt;
[[Profiler File Layout]] -- Details about the profiler log&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Debug]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=DEBUG_PROFILE&amp;diff=11487</id>
		<title>DEBUG PROFILE</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=DEBUG_PROFILE&amp;diff=11487"/>
		<updated>2025-09-12T17:00:26Z</updated>

		<summary type="html">&lt;p&gt;GomezL: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Use PROFILER.EXE to translate the BR Profiler output file into readable text.&lt;br /&gt;
&lt;br /&gt;
To generate profiler output:&lt;br /&gt;
DEBUG PROFILE SAMPLED filename&lt;br /&gt;
or&lt;br /&gt;
DEBUG PROFILE TIMED filename&lt;br /&gt;
and&lt;br /&gt;
DEBUG PROFILE STOP to end the profile&lt;br /&gt;
&lt;br /&gt;
Also, to use the profiler.exe to get a nice listing of what is in the log file.&lt;br /&gt;
profiler.exe filename&lt;br /&gt;
or&lt;br /&gt;
profiler.exe filename raw&lt;br /&gt;
&lt;br /&gt;
See ftp site Dll_Distr/Profiler for samples and documentation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Debug]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=DEBUG_PROFILE&amp;diff=11486</id>
		<title>DEBUG PROFILE</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=DEBUG_PROFILE&amp;diff=11486"/>
		<updated>2025-09-12T16:57:29Z</updated>

		<summary type="html">&lt;p&gt;GomezL: Created page with &amp;quot; Use PROFILER.EXE to translate the BR Profiler output file into readable text.  To generate profiler output: DEBUG PROFILE SAMPLED filename or DEBUG PROFILE TIMED filename and DEBUG PROFILE STOP to end the profile  Also, to use the profiler.exe to get a nice listing of what is in the log file. profiler.exe filename or profiler.exe filename raw  See ftp site Dll_Distr/Profiler for samples and documentation.&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Use PROFILER.EXE to translate the BR Profiler output file into readable text.&lt;br /&gt;
&lt;br /&gt;
To generate profiler output:&lt;br /&gt;
DEBUG PROFILE SAMPLED filename&lt;br /&gt;
or&lt;br /&gt;
DEBUG PROFILE TIMED filename&lt;br /&gt;
and&lt;br /&gt;
DEBUG PROFILE STOP to end the profile&lt;br /&gt;
&lt;br /&gt;
Also, to use the profiler.exe to get a nice listing of what is in the log file.&lt;br /&gt;
profiler.exe filename&lt;br /&gt;
or&lt;br /&gt;
profiler.exe filename raw&lt;br /&gt;
&lt;br /&gt;
See ftp site Dll_Distr/Profiler for samples and documentation.&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Debug&amp;diff=11485</id>
		<title>Debug</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Debug&amp;diff=11485"/>
		<updated>2025-09-12T16:56:13Z</updated>

		<summary type="html">&lt;p&gt;GomezL: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;see also: [[BR32.exe Debug]]&lt;br /&gt;
&lt;br /&gt;
There are many [[commands]], [[statements]], [[debuggers]], etc that will help you to &#039;&#039;&#039;debug&#039;&#039;&#039; a [[Business Rules!]] [[program]].&lt;br /&gt;
&lt;br /&gt;
Some [[editors]] such as [[MyEdit (BR Edition)]] provide an vast array of their own tools for use in debugging.&lt;br /&gt;
&lt;br /&gt;
Debug versions of BR32.exe are used almost exclusively during the [[beta]] process of upcoming versions of Business Rules!.&lt;br /&gt;
&lt;br /&gt;
Other than functions in the [[:Category:Debug|debug category]], the [[Go]] [[command]] can be very useful for debugging programs&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;DEBUG CONSOLE OFF&#039;&#039;&#039; command is supported as of BR [[4.18a]].&lt;br /&gt;
&lt;br /&gt;
[[DEBUG PROFILE]] -- Used to create Itemized Profile log file for troubleshooting performance.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Debug]]&lt;br /&gt;
[[Category:Needs Help]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=-202,020,202.02&amp;diff=11484</id>
		<title>-202,020,202.02</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=-202,020,202.02&amp;diff=11484"/>
		<updated>2025-06-05T12:57:41Z</updated>

		<summary type="html">&lt;p&gt;GomezL: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[PD]] is a Packed Decimal.&lt;br /&gt;
&lt;br /&gt;
PD 6.2 can store +/ 999,999,999.99&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;-202,020,202.02&#039;&#039;&#039; is the value read from an empty, never written, [[PD]] &#039;&#039;&#039;6.2&#039;&#039;&#039; field.&lt;br /&gt;
&lt;br /&gt;
[[Category:Number]]&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=SQL&amp;diff=11483</id>
		<title>SQL</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=SQL&amp;diff=11483"/>
		<updated>2025-05-23T15:48:50Z</updated>

		<summary type="html">&lt;p&gt;GomezL: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SQL manages data via a relational data management system. As of 4.3, BR includes several special ways of working together with SQL.&lt;br /&gt;
&lt;br /&gt;
====CONFIG DATABASE db-ref ODBC-MANAGER====&lt;br /&gt;
CONFIG [[DATABASE]] db-ref ODBC-MANAGER will invoke the ODBC Manager to define or identify a file DSN. Once this is done you can issue the command [[STATUS]] DATABASE –P to see the connect string that the ODBC Manager used to make the connection. Thereafter you can use that connection string to establish the connection to the database as follows:&lt;br /&gt;
&lt;br /&gt;
 CONFIG DATABASE db-ref  CONNECTSTRING=&amp;quot;Driver={Microsoft Access Driver (*.mdb)}DBQ=C:\inetpub\wwwroot\BegASP\Chapter.14\Contact.mdb&amp;quot;&lt;br /&gt;
            - or -&lt;br /&gt;
 CONFIG DATABASE db-ref  DSN=’dsn-ref ‘ &lt;br /&gt;
&lt;br /&gt;
;Additional Optional Parameters:&lt;br /&gt;
&lt;br /&gt;
 [, USER= department | LOGIN_NAME | ? ]&lt;br /&gt;
 [, {PASSWORD= dept-password | PASSWORDD=encrypted-passwd  | BR_PASSWORD | ? ]&lt;br /&gt;
&lt;br /&gt;
Where &#039;&#039;&#039;?&#039;&#039;&#039; indicates prompt and &#039;&#039;&#039;BR_PASSWORD&#039;&#039;&#039; indicates the password used during client login. If running the standard model (not client-server) then this is equivalent to &amp;quot;?&amp;quot;. &#039;&#039;&#039;encrypted-passwd&#039;&#039;&#039; is the DB password encrypted with the key stated in OPTION 66.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CONFIG DATABASE  MAX_COLUMN_WIDTH   nnnn&#039;&#039;&#039;&lt;br /&gt;
Some database column types are variable length. SQL requires advanced buffer allocation. This would unnecessarily tax the system if not restricted. This statement sets a maximum width for all columns. Memory is allocated to the minimum of (this amount or the column width). &amp;quot;nnnn&amp;quot; is the maximum column width. The default is 2000 characters.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;CONFIG DATABASE CLEAR   { db-ref | ALL }&#039;&#039;&#039;&lt;br /&gt;
This will close the specified database or all open databases.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Sample Connection Strings:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 Using a SQL Server /w SQL Login:&lt;br /&gt;
 CONFIG database db-ref connectstring=&amp;quot;DRIVER=SQL Server;SERVER=server;Initial Catalog=database;UID=username;PWD=password&amp;quot;&lt;br /&gt;
 db-ref is the database reference.&lt;br /&gt;
 server is the SQL Server [FQDN] or IP Address&lt;br /&gt;
 database is the [SQL Server Database] &lt;br /&gt;
 username is the [SQL Server User Name]&lt;br /&gt;
 password is the [SQL Server Password]&lt;br /&gt;
&lt;br /&gt;
 Using a SQL Server /w Windows Authentication:&lt;br /&gt;
 CONFIG database db-ref connectstring=&amp;quot;DRIVER=SQL Server;Initial Catalog=database;Persist Security Info=True;MultipleBC_TableResultSets=True; Database=database;SERVER=server;Login Name=username;Password=BR_PASSWORD&amp;quot;&lt;br /&gt;
 db-ref is the database reference.&lt;br /&gt;
 server is the SQL Server [FQDN] or IP Address&lt;br /&gt;
 database is the [SQL Server Database] &lt;br /&gt;
 username is the [SQL Server User Name]&lt;br /&gt;
 Note that BR_PASSWORD will use the users Active Directory password to connect to the SQL Server.&lt;br /&gt;
 Note that &amp;quot;SQL Server&amp;quot; is one of several choices for SQL Server, another choice would be SQL Server Native Client 11.0&lt;br /&gt;
&lt;br /&gt;
====OPEN statements====&lt;br /&gt;
&lt;br /&gt;
 OPEN #20: &amp;quot;DATABASE= db-ref&amp;quot;, SQL &amp;quot;sql-statement&amp;quot;, OUTIN&lt;br /&gt;
              - or -&lt;br /&gt;
 OPEN #20: &amp;quot;DATABASE= db-ref, Name= filename&amp;quot; , SQL, OUTIN&lt;br /&gt;
Where filename refers to a DISPLAY file containing a SQL statement that gets executed when a WRITE statement is processed.&lt;br /&gt;
&lt;br /&gt;
Example: &lt;br /&gt;
 OPEN #20: &amp;quot;DATABASE=MyData&amp;quot;,SQL &amp;quot;SELECT FILENO,BALANCE from MASTER WHERE FILENO=?&amp;quot;,OUTIN&lt;br /&gt;
&lt;br /&gt;
====Sequence of Operations====&lt;br /&gt;
#Begin processing with a WRITE statement.&lt;br /&gt;
#If the WRITE contains an IO list of values then it is used to populate the SQL before it is executed. In this process IO list values replace question marks positionally from left to right. These question marks only work with SQL arguments that refer to stored data. Question marks cannot be specified where SQL keywords or table column names appear. &lt;br /&gt;
#Resulting SQL may or may not produce a result set. If it does, the result set may be processed like a BR file opened RELATIVE. Some operations that use file positioning may be slow since the whole result set may not be in memory immediately. Simple sequential access should be fairly quick.&lt;br /&gt;
#Once SQL has been populated by an IOlist, it may be reused with the same values by issuing a WRITE with no IOlist.&lt;br /&gt;
#READ IOlist variable associations are positional with each READ accessing one row of values.&lt;br /&gt;
&lt;br /&gt;
===SQL read/write example===&lt;br /&gt;
&lt;br /&gt;
 00001    execute &amp;quot;CONFIG database Inventory connectstring=&amp;quot;&amp;quot;DRIVER=SQL Server;SERVER=COMPUTER;Initial Catalog=Inventory;Integrated Security=True;Persist Security Info=False;Pooling=False;MultipleActiveResultSets=False;Encrypt=False;TrustServerCertificate=True&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 00002    let sqlconnection = 1&lt;br /&gt;
 00003 !  READ test&lt;br /&gt;
 00004    open #sqlconnection: &amp;quot;DATABASE=Inventory&amp;quot;,SQL &amp;quot;SELECT [Name],[Address],[City],[Country],[DateOfBirth],[Age] FROM [Inventory].[dbo].[Customer]&amp;quot;,OUTIN&lt;br /&gt;
 00005    write #sqlconnection:&lt;br /&gt;
 00006    do&lt;br /&gt;
 00007       read #sqlconnection, using &#039;form POS 1,C 50,C 50,C 50,C 50,C 50,N 3&#039;: Name$,Address$,City$,Country$,DateOfBirth$,Age eof ignore&lt;br /&gt;
 00008 !     if EOF was encountered, then we are finished reading the result set&lt;br /&gt;
 00009       if file(sqlconnection)&amp;lt;&amp;gt;0 then exit do&lt;br /&gt;
 00010       let dob$ = &amp;quot;&amp;quot;&lt;br /&gt;
 00011 !     only convert SQL date to BR date if it is non-empty, otherwise BR_DATE$ bombs&lt;br /&gt;
 00012       if DateOfBirth$&amp;lt;&amp;gt;&amp;quot;&amp;quot; then&lt;br /&gt;
 00013          let dob$ = BR_DATE$(DateOfBirth$)&lt;br /&gt;
 00014       end if&lt;br /&gt;
 00015 !     show user the next result row&lt;br /&gt;
 00016       print Name$,Address$,City$,Country$,dob$,Age&lt;br /&gt;
 00017    loop&lt;br /&gt;
 00018    close #sqlconnection:&lt;br /&gt;
 00019  !&lt;br /&gt;
 00020 !  WRITE test&lt;br /&gt;
 00021    open #sqlconnection: &amp;quot;DATABASE=Inventory&amp;quot;,SQL &amp;quot;insert into [Inventory].[dbo].[Customer] ([Id],[Name],[Address],[City],[Country],[DateOfBirth],[Age]) values (6,&#039;Tom, Jerryngton&#039;, &#039;123 Big Walkway&#039;, &#039;Dallas&#039;, &#039;USA&#039;, &#039;1982-01-01&#039;, 35);&amp;quot;,OUTIN&lt;br /&gt;
 00022    write #sqlconnection:&lt;br /&gt;
 00023    close #sqlconnection:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===SQL Date Format Functions===&lt;br /&gt;
&lt;br /&gt;
 A$=SQL_DATE$(BR-date-string,&amp;quot;format-mask&amp;quot;)   ! format date for storage&lt;br /&gt;
 B$=BR_DATE$(SQL-date-string,&amp;quot;format-mask&amp;quot;)   ! unpack DB date value&lt;br /&gt;
&lt;br /&gt;
* Note: SQL DATETIME fields are &amp;quot;Packed for Storage&amp;quot;, but &amp;quot;DATE&amp;quot; fields are returned as a CCYY-MM-DD string in a SQL Query.  DATE returns &amp;quot;BLANK&amp;quot; for &amp;quot;Empty or Null Date&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===SQL Table Interrogation===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ENV$(STATUS)&#039;&#039;&#039; has been extended to interrogate database connections and ODBC data sources. A program called ENVDB.BRS (listed below) has been written to demonstrate how this extension works and to show how to setup linkage to a database or ODBC data source. Run the program as is to bring up the Microsoft ODBC manager. Then select a data source and look at the output from the program. This will also show you how to get and use connect strings. In this example lines 1900 and 2000 accomplish the same open as line 1800 in my environment. &lt;br /&gt;
&lt;br /&gt;
Try it on your Windows workstation. As long as you have one or more ODBC drivers supported you can use it without having to install a database. You can even use it to interrogate Excel files because Microsoft provides an ODBC driver for that. &lt;br /&gt;
&lt;br /&gt;
A sample program to demonstrate database interrogation entry is:&lt;br /&gt;
 01000 ! Replace Envdb&lt;br /&gt;
 01100    dim DATABASES$(1)*100&lt;br /&gt;
 01200    dim DATABASE$*100&lt;br /&gt;
 01300    dim TABLES$(1)*100&lt;br /&gt;
 01400    dim TABLE$*100&lt;br /&gt;
 01500    dim COLUMNS$(1)*100&lt;br /&gt;
 01600    dim COLUMN$*100&lt;br /&gt;
 01700    dim C$*100,FLD1$*40,FLD2$*40,FLD3$*40,FLD4$*40&lt;br /&gt;
 01800    Execute &amp;quot;CONFIG database testdb odbc-manager&amp;quot;&lt;br /&gt;
 01900 !   Execute &amp;quot;CONFIG database testdb DSN=&#039;Accounts Payable&#039;&amp;quot;&lt;br /&gt;
 02000 !   Execute &amp;quot;CONFIG database testdb connectstring=&amp;quot;&amp;quot;DSN=Excel Files;DBQ=L:\orders\Beneficial PORCEL.xls;DefaultDir=L:\orders;DriverId=1046;MaxBufferSize=2048&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 02100    open #1: &amp;quot;name=envdb.txt,replace&amp;quot;,display,output &lt;br /&gt;
 02200 Dump_Table: ! ***** Dump Table Layout&lt;br /&gt;
 02300    let OUTFD = 1&lt;br /&gt;
 02400    let ENV$(&amp;quot;status.database.LIST&amp;quot;, MAT DATABASES$)  !List of db&#039;s&lt;br /&gt;
 02500    for DATABASE=1 to UDIM(DATABASES$)  !For each connected database&lt;br /&gt;
 02600       let DATABASE$=DATABASES$(DATABASE)&lt;br /&gt;
 02700       let FNSHOW_DATABASE(DATABASE$, &amp;quot;status.database.&amp;quot;&amp;amp;DATABASE$)&lt;br /&gt;
 02800    next DATABASE&lt;br /&gt;
 02900    end &lt;br /&gt;
 03000 ! &lt;br /&gt;
 03100    def FNSHOW_DATABASE(DATABASE$*100, ST_PREFIX$*100)&lt;br /&gt;
 03200       print #OUTFD: DATABASE$&lt;br /&gt;
 03300       let OUT_PREFIX$=CHR$(9)&lt;br /&gt;
 03400       print #OUTFD: OUT_PREFIX$&amp;amp;&amp;quot;DSN=&amp;quot;&amp;amp;ENV$(ST_PREFIX$&amp;amp;&amp;quot;.DSN&amp;quot;)&lt;br /&gt;
 03500       print #OUTFD: OUT_PREFIX$&amp;amp;&amp;quot;CONNECTSTRING=&amp;quot;&amp;amp;ENV$(ST_PREFIX$&amp;amp;&amp;quot;.CONNECTSTRING&amp;quot;)&lt;br /&gt;
 03600       print #OUTFD: OUT_PREFIX$&amp;amp;&amp;quot;Tables:&amp;quot;&lt;br /&gt;
 03700       let ST_PREFIX$=ST_PREFIX$&amp;amp;&amp;quot;.TABLES&amp;quot;&lt;br /&gt;
 03800       let ENV$(ST_PREFIX$&amp;amp;&amp;quot;.LIST&amp;quot;, MAT TABLES$)&lt;br /&gt;
 03900       for TABLE = 1 to UDIM(MAT TABLES$)&lt;br /&gt;
 04000          let TABLE$=TABLES$(TABLE)&lt;br /&gt;
 04100          let FNSHOW_TABLE(TABLE$,ST_PREFIX$&amp;amp;&amp;quot;.&amp;quot;&amp;amp;TABLE$,OUT_PREFIX$&amp;amp;CHR$(9))&lt;br /&gt;
 04200       next TABLE&lt;br /&gt;
 04300    fnend &lt;br /&gt;
 04400 ! &lt;br /&gt;
 04500    def FNSHOW_TABLE(TABLE$*100, ST_PREFIX$*100, OUT_PREFIX$)&lt;br /&gt;
 04600       print #OUTFD: OUT_PREFIX$&amp;amp;TABLE$&lt;br /&gt;
 04700       let OUT_PREFIX$=OUT_PREFIX$&amp;amp;CHR$(9)&lt;br /&gt;
 04800       print #OUTFD: OUT_PREFIX$&amp;amp;&amp;quot;Table remarks=&amp;quot;&amp;amp;ENV$(ST_PREFIX$&amp;amp;&amp;quot;.REMARKS&amp;quot;)&lt;br /&gt;
 04900       print #OUTFD: OUT_PREFIX$&amp;amp;&amp;quot;Table type=&amp;quot;&amp;amp;ENV$(ST_PREFIX$&amp;amp;&amp;quot;.TYPE&amp;quot;)&lt;br /&gt;
 05000       print #OUTFD: OUT_PREFIX$&amp;amp;&amp;quot;Columns:&amp;quot;&lt;br /&gt;
 05100       let ST_PREFIX$=ST_PREFIX$&amp;amp;&amp;quot;.COLUMNS&amp;quot;&lt;br /&gt;
 05200       let ENV$(ST_PREFIX$&amp;amp;&amp;quot;.LIST&amp;quot;, MAT COLUMNS$)&lt;br /&gt;
 05300       for COLUMN = 1 to UDIM(MAT COLUMNS$)&lt;br /&gt;
 05400          let COLUMN$=COLUMNS$(COLUMN)&lt;br /&gt;
 05500          let FNSHOW_COLUMN(COLUMN$, ST_PREFIX$&amp;amp;&amp;quot;.&amp;quot;&amp;amp;COLUMN$,OUT_PREFIX$&amp;amp;CHR$(9))&lt;br /&gt;
 05600       next COLUMN&lt;br /&gt;
 05700    fnend &lt;br /&gt;
 05800 ! &lt;br /&gt;
 05900    def FNSHOW_COLUMN(COLUMN$*100, ST_PREFIX$*100, OUT_PREFIX$)&lt;br /&gt;
 06000       print #OUTFD: OUT_PREFIX$&amp;amp;COLUMN$&lt;br /&gt;
 06100       let OUT_PREFIX$=OUT_PREFIX$&amp;amp;CHR$(9)&lt;br /&gt;
 06200       print #OUTFD: OUT_PREFIX$&amp;amp;&amp;quot;Column type=&amp;quot;&amp;amp;ENV$(ST_PREFIX$&amp;amp;&amp;quot;.TYPE&amp;quot;)&lt;br /&gt;
 06300       print #OUTFD: OUT_PREFIX$&amp;amp;&amp;quot;Column length=&amp;quot;&amp;amp;ENV$(ST_PREFIX$&amp;amp;&amp;quot;.LENGTH&amp;quot;)&lt;br /&gt;
 06400       print #OUTFD: OUT_PREFIX$&amp;amp;&amp;quot;Column decimals=&amp;quot;&amp;amp;ENV$(ST_PREFIX$&amp;amp;&amp;quot;.DECIMALS&amp;quot;)&lt;br /&gt;
 06500    fnend&lt;br /&gt;
&lt;br /&gt;
===Other===&lt;br /&gt;
For more information about &#039;&#039;&#039;SQL&#039;&#039;&#039; or &#039;&#039;&#039;Structured Query Language&#039;&#039;&#039; see [[Wikipedia:SQL]].&lt;br /&gt;
&lt;br /&gt;
===CLIENT_SERVER RECONNECT===&lt;br /&gt;
You can modify WBCONFIG.SYS or execute in code.&lt;br /&gt;
&lt;br /&gt;
Sample:&lt;br /&gt;
 EXECUTE &amp;quot;CONFIG CLIENT_SERVER RECONNECT_AFTER=120 RECONNECT_TIME=120&amp;quot; &lt;br /&gt;
&lt;br /&gt;
The default 120 is two minutes; set the values to 99999 to wait 27 hours (infinity).&lt;br /&gt;
&lt;br /&gt;
Please remember that the BRServer.exe components will remain &amp;quot;Active&amp;quot; in the server&#039;s task manager until the timeout period has passed.   &lt;br /&gt;
&lt;br /&gt;
When executing a SQL command, Client Server &amp;quot;appears to be hung&amp;quot; waiting for a response.   if you reach the limit (IE 120 seconds), BRClient will believe it has timed out, and &amp;quot;Crash&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===SQL LOCK_TIMEOUT===&lt;br /&gt;
In SQL, [LOCK_TIMEOUT] instructs the SQL Server session to wait a certain number of seconds before returning an error.&lt;br /&gt;
&lt;br /&gt;
* The default value is -1&lt;br /&gt;
* 120 is a reasonable value, and it works in tandem with CLIENT_SERVER RECONNECT.&lt;br /&gt;
&lt;br /&gt;
Sample Code to set the [LOCK_TIMEOUT] settings:&lt;br /&gt;
&lt;br /&gt;
Call the function providing the SQL Connection Name and the desired timeout.&lt;br /&gt;
&lt;br /&gt;
If there is a blocking transaction, that transaction will trigger an error 3006 with SQL State of &amp;quot;42000&amp;quot;   &lt;br /&gt;
&lt;br /&gt;
Sample Function:&lt;br /&gt;
 64230 DEF FNSET_LOCK_TIMEOUT(SLT_Connection$,SLT_Timeout)&lt;br /&gt;
 64232 DIM SLT_SQL$*9999&lt;br /&gt;
 64234 SLT_SQL$=&amp;quot;SET LOCK_TIMEOUT &amp;quot;&amp;amp;str$(SLT_Timeout)&lt;br /&gt;
 64236     OPEN #(Updhandle=Fngethandle): &amp;quot;DATABASE=&amp;quot;&amp;amp;SLT_Connection$,SQL SLT_SQL$,OUTIN &lt;br /&gt;
 64238     WRITE #Updhandle: &lt;br /&gt;
 64240     CLOSE #Updhandle: &lt;br /&gt;
 64242 FNEND&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Terminology]]&lt;br /&gt;
[[Category:SQL]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Editor&amp;diff=11480</id>
		<title>Editor</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Editor&amp;diff=11480"/>
		<updated>2025-04-20T15:29:22Z</updated>

		<summary type="html">&lt;p&gt;GomezL: /* Known Third Party Editors */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Many editors are supported for BR! [[Source code]]. &lt;br /&gt;
&lt;br /&gt;
The purpose of the EDITOR statement is to identify the program used by the [[EDIT]] command. &lt;br /&gt;
&lt;br /&gt;
 Editor &amp;quot;editor-program&amp;quot; [ REMOVE ] [NOWAIT]&lt;br /&gt;
&lt;br /&gt;
While the &#039;&#039;&#039;Editor&#039;&#039;&#039; specification is normally placed within a BRCONFIG.SYS file, it can also be specified with the [[config|Config]] command or within a program line using the [[Execute]] statement to issue the Config command. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Examples====&lt;br /&gt;
An Editor Statement could be typed in the command console like: &lt;br /&gt;
&lt;br /&gt;
  Config Editor &amp;quot;C:\Program Files\NotePad++\NotePad++.exe&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Or added to [[BRConfig.sys]] like: &lt;br /&gt;
&lt;br /&gt;
  Editor &amp;quot;C:\Program Files\NotePad++\NotePad++.exe&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Or perhaps added to BRConfig.sys, but only applicable to an individual user (Herbert) like: &lt;br /&gt;
&lt;br /&gt;
 @&amp;quot;Herbert&amp;quot; Editor &amp;quot;C:\Program Files\Mills Enterprise\MyEditBR\MyEditBR.exe&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
REMOVE and NOWAIT affect the way the EDIT command uses the editor program. REMOVE causes BR to remove the source file when editing is complete. &lt;br /&gt;
&lt;br /&gt;
====See also====&lt;br /&gt;
&lt;br /&gt;
*[[Edit]] &lt;br /&gt;
*[[wikipedia:comparison_of_text_editors]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
====Known Third Party Editors====&lt;br /&gt;
&lt;br /&gt;
These editors can process .wbs/.brs [[Business Rules! Editable Source]] code. &lt;br /&gt;
&lt;br /&gt;
*NotePad &lt;br /&gt;
*[[PFE32]] &lt;br /&gt;
*[http://www.textpad.com/ TextPad] &lt;br /&gt;
*[[My Edit BR]] &lt;br /&gt;
*[http://www.mills-enterprise.ca MyEditBR website]&lt;br /&gt;
*[http://www.brixoft.net/prodinfo.asp?id=1 Source Edit] &lt;br /&gt;
*[[EditPad Pro]] &lt;br /&gt;
*[[Notepad++]] (open source) &lt;br /&gt;
*[http://www.ultraedit.com/ UltraEdit] &lt;br /&gt;
*[https://sourceforge.net/projects/jedit/ JEdit] (open source) &lt;br /&gt;
*[http://www.crimsoneditor.com Crimson Editor] (open source) &lt;br /&gt;
*[http://www.lugaru.com/ Epsilon] &lt;br /&gt;
*[http://www.context.cx/ ConTEXT] &lt;br /&gt;
*[http://www.andre-simon.de/ WinHighlight] &lt;br /&gt;
*[http://editra.org/index.php Editra]&lt;br /&gt;
*[https://www.cursor.com/ Cursor]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Utilities Third Party]]&lt;br /&gt;
[[Category:Config]]&lt;br /&gt;
[[Category:Basics]]&lt;br /&gt;
[[Category:Needs Help]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=0317&amp;diff=11479</id>
		<title>0317</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=0317&amp;diff=11479"/>
		<updated>2025-03-03T15:17:22Z</updated>

		<summary type="html">&lt;p&gt;GomezL: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Error&lt;br /&gt;
|0317&lt;br /&gt;
|attempt to [[redimension]] an [[array]] that is already on the [[RPN stack]]&lt;br /&gt;
|attempt to redimension an array that is already on the RPN stack&lt;br /&gt;
This error was added in BR! version [[4.2]].&lt;br /&gt;
&lt;br /&gt;
The following program demonstrates the error.   Remember that X &amp;amp; Y are the same array in this example, and you cannot assign the results of FN_Y to the same array.   &lt;br /&gt;
&lt;br /&gt;
 00010 dim x(10)&lt;br /&gt;
 00020 let &#039;&#039;&#039;x(1)&amp;lt;nowiki&amp;gt;=&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;fn_y(mat x)&lt;br /&gt;
 00030 end &lt;br /&gt;
 00040 def fn_y(mat y)&lt;br /&gt;
 00060   mat y(1) &lt;br /&gt;
 00070   let y(1)&amp;lt;nowiki&amp;gt;=&amp;lt;/nowiki&amp;gt;123&lt;br /&gt;
 00080   let fn_y&amp;lt;nowiki&amp;gt;=&amp;lt;/nowiki&amp;gt;y(1)&lt;br /&gt;
 00090 fnend &lt;br /&gt;
&lt;br /&gt;
|Type [[GO]] and hit enter to continue.&lt;br /&gt;
&lt;br /&gt;
You can solve the above example like this becomes 1:&lt;br /&gt;
 00010 dim x(10),&lt;br /&gt;
 00020 let temp&amp;lt;nowiki&amp;gt;=&amp;lt;/nowiki&amp;gt;fn_y(mat x)&lt;br /&gt;
 00025 let x(1)&amp;lt;nowiki&amp;gt;=&amp;lt;/nowiki&amp;gt;temp&lt;br /&gt;
 00030 end &lt;br /&gt;
 00040 def fn_y(mat y)&lt;br /&gt;
 00060   mat y(1) &lt;br /&gt;
 00070   let y(1)&amp;lt;nowiki&amp;gt;=&amp;lt;/nowiki&amp;gt;123&lt;br /&gt;
 00080   let fn_y&amp;lt;nowiki&amp;gt;=&amp;lt;/nowiki&amp;gt;y(1)&lt;br /&gt;
 00090 fnend &lt;br /&gt;
&lt;br /&gt;
Another alternative Becomes 123: &lt;br /&gt;
&lt;br /&gt;
 00010 dim x(10),&lt;br /&gt;
 00020 let fn_y(mat x)&lt;br /&gt;
 00030 end &lt;br /&gt;
 00040 def fn_y(mat y)&lt;br /&gt;
 00060   mat y(1) &lt;br /&gt;
 00070   let y(1)&amp;lt;nowiki&amp;gt;=&amp;lt;/nowiki&amp;gt;123&lt;br /&gt;
 00080   let fn_y&amp;lt;nowiki&amp;gt;=&amp;lt;/nowiki&amp;gt;y(1)&lt;br /&gt;
 00090 fnend &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
[[Category:Error Codes]]&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=0317&amp;diff=11478</id>
		<title>0317</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=0317&amp;diff=11478"/>
		<updated>2025-03-03T15:14:38Z</updated>

		<summary type="html">&lt;p&gt;GomezL: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Error&lt;br /&gt;
|0317&lt;br /&gt;
|attempt to [[redimension]] an [[array]] that is already on the [[RPN stack]]&lt;br /&gt;
|attempt to redimension an array that is already on the RPN stack&lt;br /&gt;
This error was added in BR! version [[4.2]].&lt;br /&gt;
&lt;br /&gt;
The following program demonstrates the error.   Remember that X &amp;amp; Y are the same array in this example, and you cannot assign the results of FN_Y to the same array.   &lt;br /&gt;
&lt;br /&gt;
 00010 dim x(10)&lt;br /&gt;
 00020 let &#039;&#039;&#039;x(1)&amp;lt;nowiki&amp;gt;=&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;fn_y(mat x)&lt;br /&gt;
 00030 end &lt;br /&gt;
 00040 def fn_y(mat y)&lt;br /&gt;
 00060   mat y(1) &lt;br /&gt;
 00070   let y(1)&amp;lt;nowiki&amp;gt;=&amp;lt;/nowiki&amp;gt;123&lt;br /&gt;
 00080   let fn_y&amp;lt;nowiki&amp;gt;=&amp;lt;/nowiki&amp;gt;y(1)&lt;br /&gt;
 00090 fnend &lt;br /&gt;
&lt;br /&gt;
|Type [[GO]] and hit enter to continue.&lt;br /&gt;
&lt;br /&gt;
You can solve the above example like this:  (X(1)=1)&lt;br /&gt;
&lt;br /&gt;
 00010 dim x(10),&lt;br /&gt;
 00020 let temp&amp;lt;nowiki&amp;gt;=&amp;lt;/nowiki&amp;gt;fn_y(mat x)&lt;br /&gt;
 00025 let x(1)&amp;lt;nowiki&amp;gt;=&amp;lt;/nowiki&amp;gt;temp&lt;br /&gt;
 00030 end &lt;br /&gt;
 00040 def fn_y(mat y)&lt;br /&gt;
 00060   mat y(1) &lt;br /&gt;
 00070   let y(1)&amp;lt;nowiki&amp;gt;=&amp;lt;/nowiki&amp;gt;123&lt;br /&gt;
 00080   let fn_y&amp;lt;nowiki&amp;gt;=&amp;lt;/nowiki&amp;gt;y(1)&lt;br /&gt;
 00090 fnend &lt;br /&gt;
&lt;br /&gt;
Another alternative:  (X(1)=123)&lt;br /&gt;
&lt;br /&gt;
 00010 dim x(10),&lt;br /&gt;
 00020 let fn_y(mat x)&lt;br /&gt;
 00030 end &lt;br /&gt;
 00040 def fn_y(mat y)&lt;br /&gt;
 00060   mat y(1) &lt;br /&gt;
 00070   let y(1)&amp;lt;nowiki&amp;gt;=&amp;lt;/nowiki&amp;gt;123&lt;br /&gt;
 00080   let fn_y&amp;lt;nowiki&amp;gt;=&amp;lt;/nowiki&amp;gt;y(1)&lt;br /&gt;
 00090 fnend &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
[[Category:Error Codes]]&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=BRSerial.dat&amp;diff=11450</id>
		<title>BRSerial.dat</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=BRSerial.dat&amp;diff=11450"/>
		<updated>2024-03-04T15:52:46Z</updated>

		<summary type="html">&lt;p&gt;GomezL: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The &#039;&#039;&#039;BRSerial.dat&#039;&#039;&#039; file contains your [[Business Rules!]] license information.  You can easily check the license information contained in this file by using [[CheckSerial.exe]].&lt;br /&gt;
&lt;br /&gt;
You may Rename BRSerial.dat to BrSerial.[BR Version] such as BRSerial.42 or BRSerial.43.  &lt;br /&gt;
&lt;br /&gt;
[[UserID$]]&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Files]] &lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=BRSerial.dat&amp;diff=11449</id>
		<title>BRSerial.dat</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=BRSerial.dat&amp;diff=11449"/>
		<updated>2024-03-04T15:52:01Z</updated>

		<summary type="html">&lt;p&gt;GomezL: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The &#039;&#039;&#039;BRSerial.dat&#039;&#039;&#039; file contains your [[Business Rules!]] license information.  You can easily check the license information contained in this file by using [[CheckSerial.exe]].&lt;br /&gt;
&lt;br /&gt;
You may Rename BRSerial.dat to BrSerial.[BR Version] such as BRSerial.42 or BRSerial.43.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Files]] [[UserID$]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Sort_Facility&amp;diff=11426</id>
		<title>Sort Facility</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Sort_Facility&amp;diff=11426"/>
		<updated>2023-06-09T19:58:33Z</updated>

		<summary type="html">&lt;p&gt;GomezL: Sort expanding on A vs B for &amp;quot;Address Out&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Business Rules sort facility allows you to produce a sorted output file from a randomly ordered file of records, and to rearrange the records in a variety of ways.&lt;br /&gt;
&lt;br /&gt;
A simple [[Index and Sort facilities Tutorial#Basic Overview of SORT|Sort Tutorial]] is now available.&lt;br /&gt;
&lt;br /&gt;
==Sort Command==&lt;br /&gt;
The SORT command is the instruction that tells BR to begin the sorting procedure. Its only parameter is an optional control file name that contains all the specifications about how a particular file, or set of files, is to be sorted.&lt;br /&gt;
&lt;br /&gt;
BR will execute the SORT command in any of the following 3 ways:&lt;br /&gt;
&lt;br /&gt;
#From READY mode. When followed by the name of the sort control file, SORT can be executed from READY mode.&lt;br /&gt;
#From a procedure file. When followed by either a sort control file name or by the specifications that make up a single sort group, SORT can be executed from a procedure file.&lt;br /&gt;
#With the EXECUTE statement. When the name of the sort control file is included, SORT may be specified by the EXECUTE statement.&lt;br /&gt;
&lt;br /&gt;
BR SORT facility allows you to produce a sorted output file from a randomly ordered file of records, and to rearrange the records in a variety of ways.&lt;br /&gt;
&lt;br /&gt;
===Comments and Examples===&lt;br /&gt;
The following example causes the sort specifications in ALPHABET.FIL to be executed (when ALPHABET.FIL is a sort control file in the form of an internal file):&lt;br /&gt;
 SORT ALPHABET.FIL&lt;br /&gt;
&lt;br /&gt;
Alternatively, and more easily edited sort control files can be created as [[PROC]] files. For example:&lt;br /&gt;
 PROC SAMPLESORT&lt;br /&gt;
&lt;br /&gt;
This command will run the procedure file SAMPLESORT, which begins with the SORT command, and contains all the sort control information. The SAMPLESORT procedure file might look like this:&lt;br /&gt;
&lt;br /&gt;
 Sort&lt;br /&gt;
 ! Creating a sort file, don&#039;t you worry!&lt;br /&gt;
 FILE orders.int,,,samplesort2,,,,,R,,REPLACE,SHR&lt;br /&gt;
 ALTS RO 1,&amp;quot;VERYQUICKFOX&amp;quot;&lt;br /&gt;
 RECORD I,106,2,C,&amp;quot;TX&amp;quot;,&amp;quot;TX&amp;quot;,OR&lt;br /&gt;
 RECORD I,106,2,C,&amp;quot;LA&amp;quot;,&amp;quot;LA&amp;quot;,OR&lt;br /&gt;
 RECORD I,106,2,C,&amp;quot;tx&amp;quot;,&amp;quot;tx&amp;quot;,OR&lt;br /&gt;
 RECORD I,106,2,C,&amp;quot;la&amp;quot;,&amp;quot;la&amp;quot;,OR&lt;br /&gt;
 SUM &lt;br /&gt;
 MASK 31,30,C,A,1,30,C,A&lt;br /&gt;
&lt;br /&gt;
SORT tells BR to run a sort as the first step of the procedure. The comment will show up on the operator&#039;s screen. Only FILE and MASK are required. Each parameter will be described in detail below, but this particular SORT will return a file named samplesort2 of the data in the ORDERS.INT file, containing only the customer information from Texas and Louisiana arranged alphabetically according to &amp;quot;VERYQUICKFOX&amp;quot;. Commas are necessary when skipping optional parameters within each line.&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
 SORT [&amp;lt;[[Sort control file|control file]]&amp;gt;]&lt;br /&gt;
[[Image:Sort.png]]&lt;br /&gt;
&lt;br /&gt;
===Defaults===&lt;br /&gt;
1.) Look to the next lines in the procedure file for the sort specifications.&lt;br /&gt;
&lt;br /&gt;
===Parameters===&lt;br /&gt;
The &amp;quot;control file&amp;quot; parameter specifies the name (and path, if required) of the sort control file to be executed. The sort control file contains up to six different types of specifications:&lt;br /&gt;
# COMMENT (use ! as the first character of a comment)&lt;br /&gt;
# FILE&lt;br /&gt;
# ALTS&lt;br /&gt;
# RECORD&lt;br /&gt;
# SUM&lt;br /&gt;
# MASK&lt;br /&gt;
&lt;br /&gt;
FILE and MASK are required, others are optional.&lt;br /&gt;
&lt;br /&gt;
The use of SORT without a control file-ref can only be done from within a procedure. All required sort specifications must then immediately follow the SORT command. (See [[Sort Facility]] for more information).&lt;br /&gt;
&lt;br /&gt;
Sort control files can be created in a text editor as a procedure file, or as an internal file using WRITE. The simplest way is using a procedure file, since you can easily view and edit the file.&lt;br /&gt;
&lt;br /&gt;
===Technical Considerations===&lt;br /&gt;
The &#039;&#039;&#039;Sort&#039;&#039;&#039; command performs a [[Clear]] operation (unless a program is active) and begins execution of the SORT control file. The number of RECORD specifications that may be used in sort control files is 20.&lt;br /&gt;
&lt;br /&gt;
A user-defined collating sequence may be accessed through the FILE specification&#039;s collating sequence parameter. See [[COLLATE ALTERNATE]] in [[BRConfig.sys]] for more information.&lt;br /&gt;
&lt;br /&gt;
==Types of Sort Specifications==&lt;br /&gt;
&lt;br /&gt;
Six different types of sort specifications are allowed in each sort group. FILE and MASK are required. The following table summarizes some information about the sort specifications:&lt;br /&gt;
&lt;br /&gt;
[[Image:SortSpecs.png]]&lt;br /&gt;
&lt;br /&gt;
Below are six sections describing each SORT specification in detail.&lt;br /&gt;
&lt;br /&gt;
===Comment===&lt;br /&gt;
&lt;br /&gt;
The optional Comment (!) specification displays a message to the operator on the screen. Usually it&#039;s a description of the current sort. Comments appear exactly as you enter them.&lt;br /&gt;
&lt;br /&gt;
====Comments and Examples====&lt;br /&gt;
BR displays up to twenty lines worth of Comments per sort group. Comments or Comment lines exceeding this amount are ignored. If a Comment is longer than 43 characters, it will wrap to the next line on the screen. The following is an example of SORT&#039;s Comment:&lt;br /&gt;
&lt;br /&gt;
 ! Now sorting customer file&lt;br /&gt;
&lt;br /&gt;
====Syntax====&lt;br /&gt;
&lt;br /&gt;
[[Image:SortComment.png]]&lt;br /&gt;
&lt;br /&gt;
====Parameters====&lt;br /&gt;
After the required &#039;&#039;&#039;!&#039;&#039;&#039; symbol, you mat include an optional message.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Message&#039;&#039;&#039; is the information to be displayed on the screen exactly as it is entered.&lt;br /&gt;
&lt;br /&gt;
====Technical Considerations====&lt;br /&gt;
&lt;br /&gt;
1) Comment specifications may be placed anywhere before the MASK specification in the sort group.&lt;br /&gt;
&lt;br /&gt;
===SUM===&lt;br /&gt;
&lt;br /&gt;
SUM is an optional specification that causes BR to display a summary of record counts after a file has been sorted. The way the titles are displayed is currently under development.&lt;br /&gt;
&lt;br /&gt;
====Comments and Examples====&lt;br /&gt;
&lt;br /&gt;
SUM should be used only when an operator will be in attendance during the sort, as execution will not continue between sort groups until &amp;lt;ENTER&amp;gt; has been pressed.&lt;br /&gt;
&lt;br /&gt;
SUM displays three record counts:&lt;br /&gt;
# the total number of records in the input file not including deleted records.&lt;br /&gt;
# the number of records that were included in the sort.&lt;br /&gt;
# the number of records that were written to the output file.&lt;br /&gt;
&lt;br /&gt;
The following example replaces the first and last messages printed by the SUM specification. The &amp;quot;Records read&amp;quot; and &amp;quot;Records selected&amp;quot; titles are left unchanged, but the single space in the fourth position causes the title for &amp;quot;Records output&amp;quot; to be omitted.&lt;br /&gt;
&lt;br /&gt;
    SUM Sort of HIST.FIL completed,,, ,Press &amp;lt;CR&amp;gt; to continue&lt;br /&gt;
&lt;br /&gt;
====Syntax====&lt;br /&gt;
&lt;br /&gt;
[[Image:SortSum.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Defaults====&lt;br /&gt;
#Display &amp;quot;Sort successfully completed.&amp;quot;&lt;br /&gt;
#Display &amp;quot;Records read&amp;quot;&lt;br /&gt;
#Display &amp;quot;Records selected&amp;quot;&lt;br /&gt;
#Display &amp;quot;Records output&amp;quot;&lt;br /&gt;
#Display &amp;quot;Press any key to continue.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
====Parameters====&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;90&amp;quot;|&#039;&#039;&#039;Title1&#039;&#039;&#039;||is a replacement for the message &amp;quot;Sort successfully completed&amp;quot;, which will automatically be displayed unless you specify otherwise.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;90&amp;quot;|&#039;&#039;&#039;Title2&#039;&#039;&#039;||is a replacement for the title &amp;quot;Records read&amp;quot;. Unless you specify otherwise, BR displays this title next to a count of the total number of records read from the input file.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;90&amp;quot;|&#039;&#039;&#039;Title3&#039;&#039;&#039;||is a replacement for the title &amp;quot;Records selected&amp;quot;. Unless you specify otherwise, BR displays this title next to the total number of records, which were included in the sort.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;90&amp;quot;|&#039;&#039;&#039;Title4&#039;&#039;&#039;||is a replacement for the title &amp;quot;Records output&amp;quot;, which is displayed next to the total number of records that were written to the output file.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;90&amp;quot;|&#039;&#039;&#039;Title5&#039;&#039;&#039;||is a replacement for the message &amp;quot;Press Enter to continue&amp;quot;, which is automatically displayed unless you specify otherwise.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Technical Considerations====&lt;br /&gt;
&lt;br /&gt;
#To entirely suppress a message, enter a space for the title. There is no way to suppress record counts when SUM is specified.&lt;br /&gt;
#BR truncates any title parameter, which is longer than 70 characters.&lt;br /&gt;
#The number of records selected displayed on the third line and the number of records output displayed on the fourth line should always be the same.&lt;br /&gt;
&lt;br /&gt;
===FILE===&lt;br /&gt;
&lt;br /&gt;
The FILE specification is a required specification that identifies the following:&lt;br /&gt;
#Names of input and output files.&lt;br /&gt;
#Directory for workspace.&lt;br /&gt;
#Type of output file.&lt;br /&gt;
#Desired collating sequence.&lt;br /&gt;
#Optional replacement of previous output files with the same name.&lt;br /&gt;
#File sharing rules for the input file.&lt;br /&gt;
&lt;br /&gt;
====Comments and Examples====&lt;br /&gt;
The following specification indicates that MASTER is the file to be sorted. It can be found in the VOL subdirectory on drive C. SORTOUT is the name of the output file. This can also be found in the VOL subdirectory on drive C. The WORK subdirectory, on drive D, is the designated work space. An address-out sort (PD3 format) is to be performed, and the native collating sequence is to be used (unless the BRConfig.sys file or CONFIG command has specified ALTERNATE):&lt;br /&gt;
&lt;br /&gt;
 FILE MASTER,VOL,C,SORTOUT,VOL,C,WORK,D,A,N&lt;br /&gt;
&lt;br /&gt;
In the following example, SORT.IN is the file to be sorted. It is located in the current directory on the current drive. SORT[WSID].OUT is the output file. The current drive and directory will be used for the work space. In the name SORT[WSID].OUT, the [WSID] will be replaced with the current workstation ID. A record-out sort using the alternate collating sequence is called for. If SORT[WSID].OUT already exists, BR will replace it with the newly sorted file.&lt;br /&gt;
&lt;br /&gt;
 FILE SORT.IN,,,SORT[WSID].OUT,,,,,R,A,REPLACE&lt;br /&gt;
&lt;br /&gt;
====Syntax====&lt;br /&gt;
&lt;br /&gt;
[[Image:SortFile.png]]&lt;br /&gt;
&lt;br /&gt;
====Defaults====&lt;br /&gt;
#Use the current directory.&lt;br /&gt;
#Use the current drive.&lt;br /&gt;
#Record-out sort (FILE spec)&lt;br /&gt;
#Default according to the COLLATE specification in the BRConfig.sys file.&lt;br /&gt;
#Do not replace existing file by same name.&lt;br /&gt;
#Use SHRI.&lt;br /&gt;
&lt;br /&gt;
====Parameters====&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;150&amp;quot;|&#039;&#039;&#039;Input file name&#039;&#039;&#039;||is the name of the internal file containing the records to be sorted. &amp;quot;Path&amp;quot; is the sequence of directories, which leads to this file. &amp;quot;Drive&amp;quot; is the drive on which the subdirectory path and file can be found.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;150&amp;quot;|&#039;&#039;&#039;Output file name&#039;&#039;&#039;||is the name of the file that is to contain the sorted records (or just the record numbers of the records in sorted order). &amp;quot;Path&amp;quot; is the sequence of directories, which leads to this file, and &amp;quot;drive&amp;quot; is the drive on which the subdirectory path and file can be found.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;150&amp;quot;|&#039;&#039;&#039;Workpath&#039;&#039;&#039;||is a sequence of subdirectories, which leads to the disk area where BR should create a temporary Workspace. &amp;quot;Workrive&amp;quot; is the drive on which this subdirectory path can be found. There is no need to specify a name for the work file, as BR handles this internally. See the Technical Considerations section below for formulas to help you estimate work file space.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;150&amp;quot;|&#039;&#039;&#039;FILE spec&#039;&#039;&#039;||allows you to choose from three different sort storage methods. &amp;quot;A&amp;quot; calls for an address-out sort, which is to be stored in PD3 format. &amp;quot;B&amp;quot; calls for an address-out sort, which is to be stored in B4 format. (&#039;&#039;Note: Not BH4&#039;&#039;) In both cases, the &amp;quot;address&amp;quot; which is being stored is the relative record number. &amp;quot;R&amp;quot; calls for a record-out sort, which means that each entire record is written to the output file. See the Technical Considerations section below for formulas to help you estimate address-out and record-out space. Address-out sorts execute much more quickly than record-out sorts, and the B storage method is faster than the A storage method.   When using the A Method, PD 3 has a limit of 99,999, so any records &amp;gt;10,000 will have a 0 in the PD 3 value.  When possible using &amp;quot;B&amp;quot; to avoid problems with large data sets.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;150&amp;quot;|&#039;&#039;&#039;Collating sequence&#039;&#039;&#039;||allows you to specify a collating sequence for the sort. &amp;quot;A&amp;quot; calls for the alternate collating sequence to be used, and &amp;quot;N&amp;quot; calls for the native sequence to be used. In most instances, the FILE specification collating sequence will override the BRConfig.sys file&#039;s COLLATE specification (for the sort only). There is one exception, however: if the FILES specification is N, and the BRConfig.sys specification is COLLATE ALTERNATE, the alternate collating sequence will be used. The following table should help clarify when each sequence is used. NOTE that the column labeled BRConfig.sys refers to the specification currently in use, whether it was actually specified by the BRConfig.sys file or by the CONFIG command: &lt;br /&gt;
[[Image:SortFileTable.png]] &lt;br /&gt;
&#039;&#039;&#039;*Note&#039;&#039;&#039; the exception with this option&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;150&amp;quot;|&#039;&#039;&#039;REPLACE&#039;&#039;&#039;|| replaces an old sort output file (if it exists under the specified name) with the new output file. This eliminates the need to free or drop the file before sorting. REPLACE should only be used with caution, as the existence of the output file may indicate that a previous error has occurred. You may wish to restrict the use of this parameter to WSID temporary files and to address-out files.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;150&amp;quot;|&#039;&#039;&#039;share spec&#039;&#039;&#039;|| allows you to specify file sharing rules for the input file. Any one of the NOSHR, SHRI, SHR or SHRU keywords is accepted. Keep in mind that the sort output file will not be in sorted order if SHR is specified and a record&#039;s sort field is modified by another workstation during the sort. (See &amp;quot;[[share specs]]&amp;quot; for more information about share parameters)&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All commas must be included in the FILE specification, even if some parameters are omitted&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
====Technical Considerations====&lt;br /&gt;
1) To estimate the amount of space BR will need for its temporary work space, use the following formula (applies to both address-out and record-out sorts):&lt;br /&gt;
&lt;br /&gt;
:     Number of records selected x 2&lt;br /&gt;
:       x Sort key length + 4&lt;br /&gt;
:      = N [round up to a multiple of 1024]&lt;br /&gt;
&lt;br /&gt;
2) To estimate the byte size of a PD3-formatted output file for an address-out sort (specified with the &amp;quot;A&amp;quot; parameter), use the following formula:&lt;br /&gt;
&lt;br /&gt;
:     Number of records selected&lt;br /&gt;
:       x 4&lt;br /&gt;
:      + 15&lt;br /&gt;
:       = N [round up to a multiple of 512]&lt;br /&gt;
&lt;br /&gt;
3) The record limit for a PD3-formatted address-out sort (&amp;quot;A&amp;quot;), is 99,999 records.&lt;br /&gt;
&lt;br /&gt;
4) To estimate the byte size of a B4-formatted output file for an address-out sort (specified with the &amp;quot;B&amp;quot; parameter), use the following formula:&lt;br /&gt;
&lt;br /&gt;
:      Number of records selected&lt;br /&gt;
:     x 5&lt;br /&gt;
:     + 16&lt;br /&gt;
:     = N [round up to a multiple of 512]&lt;br /&gt;
&lt;br /&gt;
5) The record limit for a B4-formatted address-out sort (&amp;quot;R&amp;quot;), is 2.147 billion (2**31-1) records.&lt;br /&gt;
&lt;br /&gt;
6) To estimate the byte size of the output file for a record-out sort (specified with the &amp;quot;R&amp;quot; parameter), use the following formula:&lt;br /&gt;
&lt;br /&gt;
:      Number of records selected&lt;br /&gt;
:     x Record length + 1&lt;br /&gt;
:       = N [round up to a multiple of 512]&lt;br /&gt;
&lt;br /&gt;
7) BR automatically clears the controls (including collating sequence) set by one sort group before it begins executing the next sort group.&lt;br /&gt;
&lt;br /&gt;
===ALTS===&lt;br /&gt;
&lt;br /&gt;
The optional ALTS specification allows you to either reorder part of the collating sequence or to set certain characters equal to a new collating value.&lt;br /&gt;
&lt;br /&gt;
====Comments and Examples====&lt;br /&gt;
&lt;br /&gt;
ALTS is frequently used to set the values of uppercase letters to the same values as their lowercase counterparts.&lt;br /&gt;
&lt;br /&gt;
ALTS specifications take effect only during character comparisons when C is specified as the format type.&lt;br /&gt;
&lt;br /&gt;
The following example reorders the collating values for the uppercase letters A through Z to match the collating values for their lowercase counterparts:&lt;br /&gt;
&lt;br /&gt;
 ALTS RO,97,&amp;quot;ABCDEFGHIJKLMNOPQRSTUVWXYZ&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The following example reorders lowercase letters so that vowels are sorted before consonants:&lt;br /&gt;
&lt;br /&gt;
 ALTS RO,97,&amp;quot;aeioubcdfghjklmnpqrstvwXYZ&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The following nine specifications set the collating values for the characters 1 through 9 to a collating value of 48. These values come into effect only when the sort is performed on C field types. It does not effect the sorting of the digits 1 through 9 when they appear in N fields:&lt;br /&gt;
&lt;br /&gt;
 ALTS EQ,48,&amp;quot;123456789&amp;quot;&lt;br /&gt;
&lt;br /&gt;
====Syntax====&lt;br /&gt;
&lt;br /&gt;
[[Image:SortAlts.png]]&lt;br /&gt;
&lt;br /&gt;
====Parameters====&lt;br /&gt;
&lt;br /&gt;
In the top route of the syntax diagram, &amp;quot;RO&amp;quot; indicates that a set of characters is to be reordered.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;New starting value&amp;quot; is the first value to be assigned in the reordering process. It must be a number from 0 to 255, and it must not be allowed to increment beyond 255. Thus if you enter a value of 253, only three characters may be reordered.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Character sequence&amp;quot; is a list of up to 28 characters which are to be reordered. It must be enclosed in quotation marks. The value which is specified as the &amp;quot;new starting value&amp;quot; will be assigned to the first character specified in the &amp;quot;character sequence&amp;quot;. The next sequential value will be assigned to the second character in the &amp;quot;character sequence&amp;quot;, and so on. If you wish to reorder more than 28 characters, you must use an additional ALTS specification.&lt;br /&gt;
&lt;br /&gt;
In the lower route of the syntax diagram, &amp;quot;EQ&amp;quot; indicates that a new, single collating value is to be assigned to the specified characters (the value and the characters are set equal).&lt;br /&gt;
&lt;br /&gt;
&amp;quot;New value&amp;quot; is a value from 0 to 255 which is to be assigned to the character. &amp;quot;Character sequence&amp;quot; is the character or set of characters which is to be given a new value; it must be enclosed within quotation marks.&lt;br /&gt;
&lt;br /&gt;
====Technical Considerations====&lt;br /&gt;
&lt;br /&gt;
1) If the ALTERNATE collating sequence is used for the sort, the following implied ALTS specification is automatically registered before any other ALTS specification is executed. Subsequent and overlapping ALTS specifications will take precedence over this specification:&lt;br /&gt;
&lt;br /&gt;
      ALTS RO,176,&amp;quot;0123456789&amp;quot;&lt;br /&gt;
&lt;br /&gt;
2) There is no limit to the number of ALTS specifications in a single sort group.&lt;br /&gt;
&lt;br /&gt;
3) BR automatically clears all controls (including collating sequence and ALTS reordering) set by one sort group before it begins executing the next sort group.&lt;br /&gt;
&lt;br /&gt;
===Record===&lt;br /&gt;
&lt;br /&gt;
The optional RECORD specification allows you to specifically include or eliminate particular records from the sorting procedure.&lt;br /&gt;
&lt;br /&gt;
====Comments and Examples====&lt;br /&gt;
Each RECORD specification tells BR to examine a specific field, called the select field, and determines whether or not the record should be included in the sort. If the value of the select field falls inside the specified limits and I (include) has been specified, BR includes that record in the sort.&lt;br /&gt;
&lt;br /&gt;
If the value of the select field falls outside the specified limits and O (omit) has been specified, BR includes that record in the sort.&lt;br /&gt;
&lt;br /&gt;
When two or more RECORD specifications are connected by the keyword &amp;quot;AND&amp;quot; (also the default), a single record must meet the qualifications of both before it will be included in the sort.&lt;br /&gt;
&lt;br /&gt;
The RECORD specification in the following example tells BR to include only the records that fall inside the specified limits. The select field starts in position one of the record and is four characters in length. It is in packed decimal (PD) format. If the select field is equal to or greater than 100, and not more than 999, it will be included in the sort.&lt;br /&gt;
&lt;br /&gt;
 RECORD I,1,4,PD,&amp;quot;100&amp;quot;,&amp;quot;999&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The following six RECORD specifications demonstrate the use of AND and OR. If a record passes the test in the first specification, it is automatically included in the sort. If it does not pass this test, it is evaluated according to the next three record specifications. If it does not receive a true evaluation for each, it may still be able to pass the requirements of the last two specifications. If it does not pass any of the three tests, it is not included in the sort:&lt;br /&gt;
&lt;br /&gt;
 RECORD I,40,5,C,&amp;quot;55024&amp;quot;,&amp;quot;55036&amp;quot;,OR&lt;br /&gt;
 RECORD I,49,15,C,&amp;quot;DAKOTA&amp;quot;,&amp;quot;DAKOTA&amp;quot;,AND&lt;br /&gt;
 RECORD I,20,15,C,&amp;quot;OUST RD&amp;quot;,&amp;quot;OUST RD&amp;quot;,AND&lt;br /&gt;
 RECORD I,15,5,C,&amp;quot;47315&amp;quot;,&amp;quot;47722&amp;quot;,OR&lt;br /&gt;
 RECORD I,49,15,C,&amp;quot;DAKOTA&amp;quot;,&amp;quot;DAKOTA&amp;quot;,AND&lt;br /&gt;
 RECORD I,20,15,C,&amp;quot;RIDGE RD&amp;quot;,&amp;quot;RIDGE RD&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The following record specification uses comparison fields in each individual record as the select field&#039;s lower and upper limits. An example of how it would be used is to identify all inventory items which are either understocked or overstocked. The select field (which represents the current inventory amount), is described as the six-character field that starts at position 28. If the value of this field is less than the value of the field that starts at position 52 (the minimum inventory amount) or greater than the value of the field that starts at position 59 (the maximum inventory amount), it will be included in the sort.&lt;br /&gt;
&lt;br /&gt;
 RECORD O,28,6,N,52,59&lt;br /&gt;
&lt;br /&gt;
====Syntax====&lt;br /&gt;
&lt;br /&gt;
[[Image:SortRecord.png]]&lt;br /&gt;
&lt;br /&gt;
====Defaults====&lt;br /&gt;
&lt;br /&gt;
1) Use AND.&lt;br /&gt;
&lt;br /&gt;
====Parameters====&lt;br /&gt;
&lt;br /&gt;
RECORD&#039;s first parameter must either be &amp;quot;I&amp;quot; (include) or &amp;quot;O&amp;quot; (omit). If you choose I, BR will include all records with select fields that fall inside the values you specify. If you choose O, BR will exclude all records with select fields that fall outside the values you specify. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;Start pos&amp;quot; is the starting position of the select field, and &amp;quot;field length&amp;quot; is its character length. &amp;quot;Form spec&amp;quot; indicates the format of the field (C, N, PD, etc.; see the discussion of [[Category:File_Operations#Format_Specifications|format specifications]] in the [[File Operations]] Section for more information).&lt;br /&gt;
&lt;br /&gt;
BR compares the data in the specified field to lower and upper limits before determining whether or not its record should be included in the sort.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Lower limit start pos&amp;quot; identifies the starting position of another field in the record. BR will use the value of this comparison field as the lower limit of the select field. The format type of the comparison field must be identical to that of the select field, and the field length must be the same.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Upper limit start pos&amp;quot; identifies the starting position of the field which contains the upper limit value for the select field. The format type of this comparison field must be identical to that of the select field, and the field length must be the same.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Lower limit&amp;quot; and &amp;quot;upper limit&amp;quot; are constants enclosed within quotation marks. BR will consider these to be the low and high limit values for the select field in determining whether or not the record should be included. BR will not accept strings greater than 40 characters in length for this parameter. It is important to distinguish between uppercase and lowercase letters when using these options, as BR makes a letter-for-letter comparison on character fields.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;OR&amp;quot; and &amp;quot;AND&amp;quot; are the RECORD specifications&#039; last two parameters. If all the RECORD specifications in a sort group are joined by &amp;quot;AND&amp;quot;, a record must pass the requirements of each before it will be included in the sort. The following two specifications, for instance, require that the value of a certain four-character field in the record fall outside 2000 and 8000 and that a certain two-character field is equal to MN. If a record doesn&#039;t pass both these tests, it is not included in the sort.&lt;br /&gt;
&lt;br /&gt;
 RECORD O,3,4,C,&amp;quot;2000&amp;quot;,&amp;quot;8000&amp;quot;,AND&lt;br /&gt;
 RECORD I,28,2,&amp;quot;MN&amp;quot;,&amp;quot;MN&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OR&amp;quot; parameter gives a second try to records that don&#039;t pass the first set of requirements. When it is included at the end of a RECORD specification, &amp;quot;OR&amp;quot; tells BR that the next RECORD specification begins a new set of requirements. If the current record passes the first set of requirements, BR does not check to see if it will pass any others. If the record does not pass the first set, however, BR sequentially checks to see if it will pass any other sets. As soon as it passes the requirements for one set of RECORD specifications, BR includes it in the sort.&lt;br /&gt;
&lt;br /&gt;
When &amp;quot;passing&amp;quot;lower and higher limits in the &amp;quot;record&amp;quot; section be sure and enclose the incoming variables with the appropriate quote sequence. This is just and example:&lt;br /&gt;
&lt;br /&gt;
 LET Data_Record$=&#039;RECORD I,&#039;&amp;amp;Str$(Recpos)&amp;amp;&#039;,8,C,&amp;quot;&#039;&amp;amp;V_File$&amp;amp;&#039;&amp;quot;,&amp;quot;&#039;&amp;amp;V_File$&amp;amp;&#039;&amp;quot;&#039;&lt;br /&gt;
&lt;br /&gt;
In the above example we are passing the Record Position and the lower and upper file numbers we want included in the &amp;quot;filter&amp;quot;&lt;br /&gt;
&lt;br /&gt;
====Technical Considerations====&lt;br /&gt;
&lt;br /&gt;
1) BR allows up to 20 RECORD specifications per sort group. (On releases prior to 3.21b, the limit was ten)&lt;br /&gt;
2) When the OR parameter is used, processing will be faster if the first conditions are the ones most likely to result in a true evaluation.&lt;br /&gt;
3) The two different types of lower and upper limit parameters may be specified in the same RECORD specification.&lt;br /&gt;
4) When I is specified, the RECORD specification&#039;s parameters are inclusive. This means that a record will be included in the sort if the select field&#039;s value is equal to the upper or lower limit value or if it is between the upper and lower limit values.&lt;br /&gt;
5) When O is specified, RECORD&#039;s upper and lower limits are exclusive; the select field value may not be equal to either the upper or lower limit if it is to be included in the sort.&lt;br /&gt;
&lt;br /&gt;
===MASK===&lt;br /&gt;
&lt;br /&gt;
MASK is a required specification that identifies up to ten sort fields and the manner (ascending or descending) in which they should be sorted.&lt;br /&gt;
&lt;br /&gt;
====Comments and Examples====&lt;br /&gt;
A sort field contains the specific information to be sorted. When you wish to organize records in descending order by zip code, for example, the sort field is the zip code. The following MASK specification defines two sort fields. The first starts in position 1 and is four characters long; it is in packed decimal (PD) format, and it is to be sorted in ascending order. The second field starts in position 10 and is three characters long. It is in character (C) format, and is also to be sorted in ascending order.&lt;br /&gt;
&lt;br /&gt;
 MASK 1,4,PD,A,10,3,C,A&lt;br /&gt;
&lt;br /&gt;
====Syntax====&lt;br /&gt;
&lt;br /&gt;
[[File:SortMask.png]]&lt;br /&gt;
&lt;br /&gt;
====Parameters====&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Start position&amp;quot; is the starting record position of the field to be sorted, and &amp;quot;field length&amp;quot; is its character length. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;Form spec&amp;quot; indicates the format, or data type, of the field. The format specifications which can be used in the MASK specification include the following: B (Binary); BL (Binary low); BH (Binary high); C (Character); D (Double-precision); L (Long); N (Numeric); PD (Packed decimal); S (Single-precision) and ZD (Zoned decimal). See [[:Category:File_Operations#Format_Specifications|Format Specifications]] in the [[File Operations]] section for more information about each of these format types.&lt;br /&gt;
&lt;br /&gt;
The last parameter must either be &amp;quot;A&amp;quot; to sort the specified record in ascending order, or &amp;quot;D&amp;quot; to sort it in descending order.&lt;br /&gt;
&lt;br /&gt;
====Technical Considerations====&lt;br /&gt;
#The following field lengths are required for the D, S &amp;amp; L format specs: D is 8; S is 4; &amp;amp; L is 9.&lt;br /&gt;
#The total sort key length may not exceed 32,767 bytes.&lt;br /&gt;
#Up to ten fields may be specified with the MASK specification.&lt;br /&gt;
#MASK must always be the last specification in a sort group.&lt;br /&gt;
#The existence of MASK flags the end of the current sort group. BR will automatically treat any specifications that follow as part of the next sort group.&lt;br /&gt;
&lt;br /&gt;
==Sort Specification==&lt;br /&gt;
&lt;br /&gt;
The ! (for a comment), FILE, ALTS, RECORD, SUM and MASK specifications each control a different aspect of the sorting procedure. A set of these specifications makes up a sort group.&lt;br /&gt;
&lt;br /&gt;
===Sort Group===&lt;br /&gt;
&lt;br /&gt;
A sort group contains all the necessary specifications for controlling the sorting of a single file. If only one file is to be sorted, a single sort group may simply follow a SORT command when it is specified in a procedure file. When several files are to be sorted, the sort group for each file may be placed together in a single sort control file.&lt;br /&gt;
&lt;br /&gt;
==Sort Control File==&lt;br /&gt;
{{:Sort control file}}&lt;br /&gt;
&lt;br /&gt;
==Sort Baseyear Processing==&lt;br /&gt;
&lt;br /&gt;
If a Y is appended to the A/D (ascending/descending) indicator of sort MASK statements or the I/O (include/exclude) field of RECORD statements, the field is subject to BASEYEAR processing.&lt;br /&gt;
&lt;br /&gt;
If such a field is in display format, then the first two characters are assumed to be a BASEYEAR dependent value.  If the field is packed (BH or PD) then the storage format is assumed to be YYMMDD, YYMM or YY format depending on the length of the field, similar to INDEX (see above table).&lt;br /&gt;
&lt;br /&gt;
The Y2K sorting and indexing features interpret year zero as zero (instead of 2000) if the month and day are zero.  Leading blanks in baseyear sensitive fields are replaced with zeroes for sorting purposes, provided the remainder of the field contains only numeric data.&lt;br /&gt;
&lt;br /&gt;
Prior to release 3.83e, BR ignored the digits to the left of the rightmost six digits of a date value unless century was specified in the mask.&lt;br /&gt;
&lt;br /&gt;
;Example:&lt;br /&gt;
&lt;br /&gt;
 ... DAYS(1001021,&amp;quot;YMD&amp;quot;) produced the same result as DAYS(001021,&amp;quot;YMD&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Now if BR is unsuccessful applying the &amp;quot;YMD&amp;quot; mask it now tries &amp;quot;CYMD&amp;quot;.  This change has inconvenienced some dealers.  Therefore OPTION 18 is provided to ignore the presence of digits to the left of the rightmost six digits.&lt;br /&gt;
&lt;br /&gt;
==Improving Sort Speed==&lt;br /&gt;
&lt;br /&gt;
All of the following factors can affect the speed of a sorting operation:&lt;br /&gt;
&lt;br /&gt;
# Number of records to be sorted. The fewer the records, the faster the sort.&lt;br /&gt;
# Type of sort. Address-out sorts takes less time to run than a record-out sorts because they require fewer disk reads and writes. Also the B storage method for address-out sorts is faster than the A storage method.&lt;br /&gt;
# RECORD specification(s). When RECORD specifications cause many records to be omitted from the sort, the sort runs faster.&lt;br /&gt;
# Length of sort field. The shorter the sort field, the faster the sort.&lt;br /&gt;
# Order of records in the input file. Files with records that are already close to the desired order sort more quickly than more randomly ordered files.&lt;br /&gt;
# Record size. The smaller the input records the faster the sort.&lt;br /&gt;
# Storage size of the computer. In general, the greater the storage, the faster the sort. If the computer does not have enough storage, it must use work files: the time required to read from and write to these files adds to the amount of time the sort takes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Sorting and Indexing]]&lt;br /&gt;
[[Category:Facility Commands]]&lt;br /&gt;
[[Category:Needs Help]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Category:Format_Specifications&amp;diff=11419</id>
		<title>Category:Format Specifications</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Category:Format_Specifications&amp;diff=11419"/>
		<updated>2023-04-11T16:27:00Z</updated>

		<summary type="html">&lt;p&gt;GomezL: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See the format specifications below for more details on each.&lt;br /&gt;
&lt;br /&gt;
See also [[Format specifications]] for a chart comparing their uses.&lt;br /&gt;
&lt;br /&gt;
Format specifications tell Business Rules the form that a particular data field will be in. A format specification is required whenever data is input into or output from a program. It is also required with the full screen processing statements. Format specs are not required in the following situations: with unformatted internal files, with all display files, and when unformatted PRINT statements are used.&lt;br /&gt;
&lt;br /&gt;
Not all format specifications are alike in their uses. Some can be used with internal and external files, but not with display files. Some can be used only with full screen formatting. And some format specifications behave differently depending on whether they are used for input or output.&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;&#039;Common SQL Fields and BR Equivilants&#039;&#039;&#039; ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TABLE BORDER=&amp;quot;1&amp;quot; CELLSPACING=&amp;quot;1&amp;quot; CELLPADDING=&amp;quot;3&amp;quot; WIDTH=&amp;quot;100%&amp;quot; ALIGN=&amp;quot;Center&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TH&amp;gt;SQL Field&amp;lt;/TH&amp;gt;&lt;br /&gt;
 &amp;lt;TH&amp;gt;BR Equivilant&amp;lt;/TH&amp;gt;&lt;br /&gt;
 &amp;lt;TH&amp;gt;Example&amp;lt;/TH&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;COUNTER&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N 6&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;INTEGER&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N 6&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;LONG INTEGER&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N 12&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;SINGLE&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;S&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;S&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;DOUBLE&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;D&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;D&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;BINGINT&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N/A&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N 10&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;SMALLINT&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;BH&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;BH 2&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;FLOAT&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;L&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N 6&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;DECIMAL&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N or PD&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N 12.2 or PD 6.2&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;DATETIME&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N/A&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;Typically Stored as separate fields&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;DATE&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;C or D&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;C 8 or D&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;CHAR&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;C&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;C 30&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/TABLE&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Field Specifications]]&lt;br /&gt;
[[Category:All Parameters]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Category:Format_Specifications&amp;diff=11418</id>
		<title>Category:Format Specifications</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Category:Format_Specifications&amp;diff=11418"/>
		<updated>2023-04-11T16:26:21Z</updated>

		<summary type="html">&lt;p&gt;GomezL: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See the format specifications below for more details on each.&lt;br /&gt;
&lt;br /&gt;
See also [[Format specifications]] for a chart comparing their uses.&lt;br /&gt;
&lt;br /&gt;
Format specifications tell Business Rules the form that a particular data field will be in. A format specification is required whenever data is input into or output from a program. It is also required with the full screen processing statements. Format specs are not required in the following situations: with unformatted internal files, with all display files, and when unformatted PRINT statements are used.&lt;br /&gt;
&lt;br /&gt;
Not all format specifications are alike in their uses. Some can be used with internal and external files, but not with display files. Some can be used only with full screen formatting. And some format specifications behave differently depending on whether they are used for input or output.&lt;br /&gt;
&lt;br /&gt;
Common SQL Fields and BR Equivilants&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TABLE BORDER=&amp;quot;1&amp;quot; CELLSPACING=&amp;quot;1&amp;quot; CELLPADDING=&amp;quot;3&amp;quot; WIDTH=&amp;quot;100%&amp;quot; ALIGN=&amp;quot;Center&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TH&amp;gt;SQL Field&amp;lt;/TH&amp;gt;&lt;br /&gt;
 &amp;lt;TH&amp;gt;BR Equivilant&amp;lt;/TH&amp;gt;&lt;br /&gt;
 &amp;lt;TH&amp;gt;Example&amp;lt;/TH&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;COUNTER&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N 6&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;INTEGER&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N 6&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;LONG INTEGER&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N 12&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;SINGLE&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;S&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;S&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;DOUBLE&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;D&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;D&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;BINGINT&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N/A&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N 10&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;SMALLINT&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;BH&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;BH 2&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;FLOAT&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;L&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N 6&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;DECIMAL&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N or PD&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N 12.2 or PD 6.2&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;DATETIME&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N/A&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;Typically Stored as separate fields&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;DATE&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;C or D&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;C 8 or D&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;CHAR&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;C&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;C 30&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/TABLE&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Field Specifications]]&lt;br /&gt;
[[Category:All Parameters]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Category:Format_Specifications&amp;diff=11417</id>
		<title>Category:Format Specifications</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Category:Format_Specifications&amp;diff=11417"/>
		<updated>2023-04-11T14:23:26Z</updated>

		<summary type="html">&lt;p&gt;GomezL: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See the format specifications below for more details on each.&lt;br /&gt;
&lt;br /&gt;
See also [[Format specifications]] for a chart comparing their uses.&lt;br /&gt;
&lt;br /&gt;
Format specifications tell Business Rules the form that a particular data field will be in. A format specification is required whenever data is input into or output from a program. It is also required with the full screen processing statements. Format specs are not required in the following situations: with unformatted internal files, with all display files, and when unformatted PRINT statements are used.&lt;br /&gt;
&lt;br /&gt;
Not all format specifications are alike in their uses. Some can be used with internal and external files, but not with display files. Some can be used only with full screen formatting. And some format specifications behave differently depending on whether they are used for input or output.&lt;br /&gt;
&lt;br /&gt;
Common SQL Fields and BR Equivilants&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TABLE BORDER=&amp;quot;0&amp;quot; CELLSPACING=&amp;quot;1&amp;quot; CELLPADDING=&amp;quot;3&amp;quot; WIDTH=&amp;quot;100%&amp;quot; ALIGN=&amp;quot;Center&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TH&amp;gt;SQL Field&amp;lt;/TH&amp;gt;&lt;br /&gt;
 &amp;lt;TH&amp;gt;BR Equivilant&amp;lt;/TH&amp;gt;&lt;br /&gt;
 &amp;lt;TH&amp;gt;Example&amp;lt;/TH&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;COUNTER&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N 6&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;INTEGER&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N 6&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;LONG INTEGER&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N 12&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;SINGLE&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;S&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;S&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;DOUBLE&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;D&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;D&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;BINGINT&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N/A&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N 10&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;SMALLINT&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;BH&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;BH 2&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;FLOAT&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;L&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N 6&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;DECIMAL&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N or PD&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N 12.2 or PD 6.2&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;DATETIME&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N/A&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;Typically Stored as separate fields&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;DATE&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;C or D&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;C 8 or D&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;CHAR&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;C&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;C 30&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/TABLE&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Field Specifications]]&lt;br /&gt;
[[Category:All Parameters]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Category:Format_Specifications&amp;diff=11416</id>
		<title>Category:Format Specifications</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Category:Format_Specifications&amp;diff=11416"/>
		<updated>2023-04-11T14:22:16Z</updated>

		<summary type="html">&lt;p&gt;GomezL: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See the format specifications below for more details on each.&lt;br /&gt;
&lt;br /&gt;
See also [[Format specifications]] for a chart comparing their uses.&lt;br /&gt;
&lt;br /&gt;
Format specifications tell Business Rules the form that a particular data field will be in. A format specification is required whenever data is input into or output from a program. It is also required with the full screen processing statements. Format specs are not required in the following situations: with unformatted internal files, with all display files, and when unformatted PRINT statements are used.&lt;br /&gt;
&lt;br /&gt;
Not all format specifications are alike in their uses. Some can be used with internal and external files, but not with display files. Some can be used only with full screen formatting. And some format specifications behave differently depending on whether they are used for input or output.&lt;br /&gt;
&lt;br /&gt;
Common SQL Fields and BR Equivilants&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TABLE BORDER=&amp;quot;0&amp;quot; CELLSPACING=&amp;quot;1&amp;quot; CELLPADDING=&amp;quot;3&amp;quot; WIDTH=&amp;quot;100%&amp;quot; ALIGN=&amp;quot;Center&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TH&amp;gt;SQL Field&amp;lt;/TH&amp;gt;&lt;br /&gt;
 &amp;lt;TH&amp;gt;BR Equivilant&amp;lt;/TH&amp;gt;&lt;br /&gt;
 &amp;lt;TH&amp;gt;Example&amp;lt;/TH&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;COUNTER&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N 6&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;INTEGER&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N 6&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;LONG INTEGER&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N 12&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;SINGLE&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;S&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;S&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;DOUBLE&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;D&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;D&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;BINGINT&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N/A&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N 10&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;SMALLINT&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;BH&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;VH 2&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;FLOAT&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;L&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N 6&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;DECIMAL&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N 12.2&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;DATETIME&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;N/A&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;Typically Stored as separate fields&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TR&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;DATE&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;C or D&amp;lt;/TD&amp;gt;&lt;br /&gt;
 &amp;lt;TD&amp;gt;C 8 or D&amp;lt;/TD&amp;gt;&lt;br /&gt;
&amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/TABLE&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Field Specifications]]&lt;br /&gt;
[[Category:All Parameters]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=BR_Forum&amp;diff=11088</id>
		<title>BR Forum</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=BR_Forum&amp;diff=11088"/>
		<updated>2019-05-21T13:16:20Z</updated>

		<summary type="html">&lt;p&gt;GomezL: Link to Register on Forum was broken.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The &#039;&#039;&#039;BR Forum&#039;&#039;&#039; ([http://brforum.brulescorp.com brforum.brulescorp.com]) is the place to post your questions, answers and other discussions about the Business Rules! programming language.&lt;br /&gt;
&lt;br /&gt;
To keep up to date with what is going on on the BR Forum, it is suggested that you subscribe to the [http://brforum.brulescorp.com/rss.php BR Forum&#039;s RSS feed].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===New Users===&lt;br /&gt;
*[http://brforum.brulescorp.com/ucp.php?mode=register Register]&lt;br /&gt;
*[http://brforum.brulescorp.com/viewforum.php?f=20&amp;amp;sid=60fc6da8b23fc4ddab1355116d9e3906 Help using the BR forum]&lt;br /&gt;
&lt;br /&gt;
When you get there, please check out the &amp;quot;[http://brforum.brulescorp.com/viewforum.php?f=20&amp;amp;sid=60fc6da8b23fc4ddab1355116d9e3906 Using this forum]&amp;quot; section for a few pointers to help you get started.&lt;br /&gt;
&lt;br /&gt;
You must be registered in the new forum in order to post messages. To do so, go to [http://brforum.brulescorp.com/ brforum.brulescorp.com]  and [http://brforum.brulescorp.com/profile.php?mode=register&amp;amp;sid=ee5bc51d99c90d7865769931e18acb22 Register]. New registrations must be approved by a moderator, so there could possibly be a slight delay before that takes place. Once you are registered, log in using the [http://brforum.brulescorp.com/login.php Log in] link in the upper right corner and you&#039;re ready to go.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Older Forum: the Maillist==&lt;br /&gt;
The older &amp;quot;BR_forum&amp;quot; maillist is still in wide spread use as a portal to the online forum, just remember that every email you send or receive here will be published.&lt;br /&gt;
&lt;br /&gt;
*[http://brulescorp.com/mailman/listinfo/br_forum_ads.net maillist]&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Floating_Point_Numbers&amp;diff=11083</id>
		<title>Floating Point Numbers</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Floating_Point_Numbers&amp;diff=11083"/>
		<updated>2019-04-29T17:42:33Z</updated>

		<summary type="html">&lt;p&gt;GomezL: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Floating point numbers are numbers which allow the decimal point to &amp;quot;float&amp;quot; to any position. &lt;br /&gt;
&lt;br /&gt;
The Business Rules syntax is nEm, where n is a numeric constant indicating the sign and significant digits in the number, E represents base 10, and m is a signed integer representing the power to which 10 is raised. &lt;br /&gt;
&lt;br /&gt;
The largest and smallest numbers available to the system vary according to the hardware and operating system being used. The system function [[INF]] can be used to print the largest possible number on any given system; 1/INF generates the smallest number. Some caution should be used in working with numbers near these minimum and maximum extremes (e.g., using exponential notation in SORT). Also, for any given combination of hardware and Business Rules, the system infinity function INF and some testing should be combined to determine whether or not intermediate values used in calculations will be truncated. &lt;br /&gt;
&lt;br /&gt;
All numbers in memory are floating point numbers. The form of the number when written to disk or printed depends on the format or mask used in writing the number. Number variables are designated by NOT ending with a dollar sign in Business Rules.&lt;br /&gt;
&lt;br /&gt;
The fact that floating-point numbers cannot precisely represent all real numbers, and that floating-point operations cannot precisely represent true arithmetic operations, leads to many surprising situations. This is related to the finite precision with which computers generally represent numbers. in BUsiness Rules, floating point numbers can only provide 16 digits of precision, this is before or after the decimal place.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
Values that fit in Floating Point:&lt;br /&gt;
print using &#039;form n 20.2&#039;:1234567890123.45 --&amp;gt;     1234567890123.45&lt;br /&gt;
print using &#039;form n 20.8&#039;:1234567.89012345 --&amp;gt;     1234567.89012345&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Values that do not fit in Floating Point: &lt;br /&gt;
print using &#039;form n 20.2&#039;:123456789012345.67 --&amp;gt;   123456789012346.00&lt;br /&gt;
print using &#039;form n 20.8&#039;:1234567890.1234567 --&amp;gt;   1234567890.12346000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Definitions]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=System_(command)&amp;diff=11079</id>
		<title>System (command)</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=System_(command)&amp;diff=11079"/>
		<updated>2019-03-26T06:54:53Z</updated>

		<summary type="html">&lt;p&gt;GomezL: /* Using SYSTEM to exit BR */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The &#039;&#039;&#039;System (SY)&#039;&#039;&#039; [[:Category:commands|command]] can do two things:&lt;br /&gt;
#Exit BR and return control to the [[operating system]], or &lt;br /&gt;
#Perform a &#039;&#039;&#039;shell call&#039;&#039;&#039; (an operating system command) while BR is active. &lt;br /&gt;
&lt;br /&gt;
System can be executed from [[READY mode]], from a [[procedure file]], or with the [[Execute]] [[statement]].&lt;br /&gt;
&lt;br /&gt;
==Using SYSTEM to exit BR==&lt;br /&gt;
&lt;br /&gt;
Entering SYSTEM or it&#039;s short form, SY into the command line while in ready mode will exit BR. The same can be done using an [[Execute]] Statement or a procedure file. Optionally, the SYSTEM LOGOFF may be used when in client server to clear the login credentials.   The next time client server is started, the user will be requested to enter their credentials.&lt;br /&gt;
&lt;br /&gt;
[[image:Sy.jpg]]&lt;br /&gt;
[[image:System2.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Using SYSTEM to send commands to the operating system==&lt;br /&gt;
===Comments and Examples===&lt;br /&gt;
One use of the SYSTEM command is to run a program. In the following example, the SYSTEM command runs a program called BACKUP. By default, the first program waits until the other program has finished running, and then continues where it left off. The syntax includes the SYSTEM keyword and then the OS command, which in this case is the program name and location of the data to handle. &lt;br /&gt;
&lt;br /&gt;
 SYSTEM BACKUP C:\\*.DAT A: /S&lt;br /&gt;
&lt;br /&gt;
When the same command is used with an asterisks preceding the program name, BACKUP, the BR program restores its own screen upon re-entry:&lt;br /&gt;
&lt;br /&gt;
 SYSTEM *BACKUP C:\\*.DAT A: /S&lt;br /&gt;
&lt;br /&gt;
The statement below tests to see what type of operating system the program is running on, then executes the appropriate SYSTEM command for the operating system:&lt;br /&gt;
&lt;br /&gt;
 00100 IF FILE$(0)(1:3)=&amp;quot;CON:&amp;quot; THEN EXECUTE &amp;quot;SYSTEM DIR&amp;quot; :!ELSE EXECUTE &amp;quot;SYSTEM ls -al /usr/BR&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===Using Batch Files with System Exits===&lt;br /&gt;
&lt;br /&gt;
One use of the System command is to pass a return code to the host operating system as it permanently exits from BR. In the following example, a DOS [[batch file]] tests the return code ([[ERRORLEVEL]]) and performs a specific action according to its value.&lt;br /&gt;
&lt;br /&gt;
 BR PROC START&lt;br /&gt;
 IF ERRORLEVEL 101 GOTO BADERROR&lt;br /&gt;
 IF ERRORLEVEL 100 GOTO BACKUP&lt;br /&gt;
 IF ERRORLEVEL 99 GOTO FORMAT&lt;br /&gt;
 GOTO DONE&lt;br /&gt;
 :BACKUP&lt;br /&gt;
 BACKUPBR&lt;br /&gt;
 :FORMAT&lt;br /&gt;
 FORMAT A:&lt;br /&gt;
 BRSTART&lt;br /&gt;
 :BADERROR&lt;br /&gt;
 ECHO BAD ERROR RETURN CODE &amp;gt;100&lt;br /&gt;
 :DONE&lt;br /&gt;
&lt;br /&gt;
If the command SYSTEM 100 were used to exit from BR while the above batch file was active, DOS would start a back-up procedure as soon as the BR exit was complete.&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
 SYSTEM [&amp;lt; code for OS&amp;gt;|[*]&amp;lt;OS command&amp;gt;]&lt;br /&gt;
[[Image:System.png]]&lt;br /&gt;
&lt;br /&gt;
==Defaults==&lt;br /&gt;
:1) Return control to the operating system with a return code of zero.&lt;br /&gt;
:2) Do not restore screen.&lt;br /&gt;
&lt;br /&gt;
==Parameters==&lt;br /&gt;
&#039;&#039;&#039;Code returned to OS&#039;&#039;&#039; parameter sets the value of the operating system return code which may be accessed using ERRORLEVEL in DOS batch files, and through the $? substitution in a Linux shell.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;OS command&#039;&#039;&#039; parameter is an operating system command which BR passes to the operating system for execution. If the result of the command requires no operator action, BR is immediately reentered after the command finishes execution. Since BR is active during the entire process, all variable values and memory remain the same. When the &#039;&#039;&#039;OS command&#039;&#039;&#039; parameter is preceded by an asterisk, the BR screen is restored upon re-entry. The &#039;&#039;&#039;OS command&#039;&#039;&#039; parameter must be a &#039;&#039;&#039;string variable&#039;&#039;&#039; or a string enclosed in quotes.&lt;br /&gt;
&lt;br /&gt;
Additional Flags that can alter the behavior of the shell call as follows:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;|&#039;&#039;&#039;-E or -e&#039;&#039;&#039;||&amp;quot;Errors&amp;quot; indicates that any Operating System errors returned from the shell should be reported (as error 4300). Otherwise shell call operating errors are ignored. Occasionally Windows returns error values for fairly nominal exceptions. So the -e is provided as an error return sensitivity level flag.  Further information can be obtained by querying SYSERR or SYSERR$&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;|&#039;&#039;&#039;-M or -m&#039;&#039;&#039;|| Run the program &amp;quot;minimized&amp;quot;.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;| ||If a lower case m is specified, the process or program runs in a DOS command shell without displaying the DOS window, but with a corresponding icon on the task bar (effectively running the shelled process/program &amp;quot;minimized&amp;quot;) This is only applicable in Windows. It is ignored on all other systems.  If -m is omitted, the shelled program will open in a separate application window.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;| ||If an upper case M is specified, the same thing happens except the task does not appear on the taskbar. It runs invisibly. Furthermore [[SPOOLCMD]] calls use lowercase m.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;|&#039;&#039;&#039;-s&#039;&#039;&#039;||Server Shell Call (this is the default for Unix). If -s is omitted on Windows, then this shell call is performed on the client.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;|&#039;&#039;&#039;-@&#039;&#039;&#039;||If using Client Server, then it runs the program on the  client. Client Shell Call is the default for Windows. If -@ is omitted, on Unix the shell call is performed on the server.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;| ||(search path not implemented  on client)&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;| ||Note- Ctrl-] ALWAYS performs a DOS shell call on the client.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;|&#039;&#039;&#039;-c&#039;&#039;&#039;||The main program &amp;quot;continues&amp;quot; to run while running the called one.  Windows launches the task and resumes BR operation where it left off. For Unix, the command is framed with NOHUP and &amp;amp;. If -c is omitted, then the shell call waits til the process is finished (up to the # seconds specified in SHELL LIMITS) before returning to BR.&lt;br /&gt;
&lt;br /&gt;
For [[OSX]] 10.6 you need&lt;br /&gt;
&lt;br /&gt;
sys -c | (pipe) Shell commands with a pipe make BR Continue after executing the sys -c (continue), if you do not insert the | pipe, then the script does not run under Br [[4.18]] and up.&lt;br /&gt;
This was found on a Macintosh client that just updated to OSX 10.6.x&lt;br /&gt;
&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;|&#039;&#039;&#039;-r&#039;&#039;&#039;||&amp;quot;Restore&amp;quot; means that Windows always performs shell in a separate window. (Unix ignores shell standard out data). If -r is omitted. then Unix forwards standard out and stdin data to and from the client window.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;| ||Restores screen after running command on all systems.  In windows, the screen is always restored, so this flag is essentially ignored. This is the same as sys *command.  The newer syntax is more readable and preferred.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;|&#039;&#039;&#039;-w&#039;&#039;&#039;||(&amp;quot;without shell&amp;quot;) When a Windows application is called, use a -w flag to tell BR not to call COMMAND.COM, but to call the application directly.  It must be a program (i.e. &amp;quot;exe&amp;quot;) and not a script. The Search Path is used ON SERVER only (if no slashes). This option does NOT open a DOS window. It does not use Bourne shell. It enables unfiltered return values. A Timeout or Ctrl-A kills the process. If -w is omitted, then a timeout or Ctrl-A does NOT kill the process, which can leave orphans.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;| ||Note- Currently -w is ignored in Unix standard models.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;|&#039;&#039;&#039;blank&#039;&#039;&#039;||Application standard output is forwarded to the client. However the Bourne shell is utilized to initiate the process. The shelled program CAN be an executable script.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;|&#039;&#039;&#039;-p&#039;&#039;&#039;||(&amp;quot;Page Standard Output&amp;quot;) - This option applies to Unix server only. If -p is omitted, then output goes to screen without pausing&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;|&#039;&#039;&#039;-t9999&#039;&#039;&#039;||Wait up to the specified number of seconds (for client server only). If -t is omitted, wait the number of seconds specified in the [[SHELL LIMIT]] statement (see [[BRConfig.sys]] chapter for more information on [[SHELL LIMIT]])&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Technical Considerations==&lt;br /&gt;
:1) Simultaneous pressing of the Ctrl key and the right- bracket (]) key has the same effect as the SYSTEM command&#039;s shell call, except that no command string is automatically executed upon access to the operating system. Pressing of these keys causes BR immediately access the operating system and display the system prompt. Between each operating system operation, a message about what action is required to return to BR will be displayed.&lt;br /&gt;
:2) Too frequent or careless use of the SYSTEM command can make it more difficult to move your program to a new operating system. ADS strongly recommends the use of the FILE$ function in programs and procedures which access the resident operating system. This function allows programs to test the type of operating system before proceeding with a system-dependent sequence of commands. While the FILE$ function can always be programmed in at a later date, you may be able to save a great deal of time and recoding by placing it in programs as they are written.&lt;br /&gt;
:3) When the system call (either Ctrl-] or the [[SYSTEM]] command) starts and then exits a secondary software program before returning to [[BR]], the [[CODE]] function will reflect any return code that the secondary program has passed to the operating system. As soon as BR is reactivated, the value of [[CODE]] can be tested to Verify whether or not the secondary program was successful. This is currently valid for Linux versions of [[BR]] only.&lt;br /&gt;
:4) [[BR]] passes all quotation marks within or surrounding the &amp;quot;string-expr&amp;quot; parameter back to the operating system.&lt;br /&gt;
:5) The screen may be cleared on some Linux terminals when the [[SYSTEM]] call is completed. If this is undesirable, see [[Terminal Considerations]] for a possible remedy.&lt;br /&gt;
:6) BR now searches PATHs during Windows shell call.&lt;br /&gt;
:7) Shell calls to Windows applications are no longer maximized.&lt;br /&gt;
:8) System calls -M -W -C -R now operate like their corresponding lower case flags.  This case sensitivity had been suppressed to allow passing the flags to DOS, but that made the rules too obscure.&lt;br /&gt;
:9) Concerning Unix shell calls, the following flag combinations are prevented-&lt;br /&gt;
:-W and -C&amp;lt;br&amp;gt;&lt;br /&gt;
:-R and -C&amp;lt;br&amp;gt;&lt;br /&gt;
:-W and -R&amp;lt;br&amp;gt;&lt;br /&gt;
:In other words Without Shell, Restore Screen, and Continue are mutually exclusive options.  If more than one is specified at a time, error [[2222]] is generated.&lt;br /&gt;
&lt;br /&gt;
For disambiguation purposes, also see [[System Parameter]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Commands]]&lt;br /&gt;
[[Category:Executive Commands]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=BRlistener.exe&amp;diff=11043</id>
		<title>BRlistener.exe</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=BRlistener.exe&amp;diff=11043"/>
		<updated>2019-01-18T17:23:38Z</updated>

		<summary type="html">&lt;p&gt;GomezL: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The &#039;&#039;&#039;BRListener.exe&#039;&#039;&#039; file is a [[32 bit]] C++ application which serves as the [[connection agent]] for the server side of [[Business Rules!]] [[Client Server]] installations.&lt;br /&gt;
&lt;br /&gt;
GENERAL: You must be logged in as [[Administrator]] in order to run Setup (BRListener.exe). (Or [[superuser]] for [[SCO]]) &lt;br /&gt;
&lt;br /&gt;
In order to run BRListener.exe, [[BRListener.conf]] must be properly configured.&lt;br /&gt;
&lt;br /&gt;
Copy BRListener.exe to the proper [[System32]] folder.&lt;br /&gt;
&lt;br /&gt;
If you have a BR Service running:&lt;br /&gt;
&lt;br /&gt;
# Stop the BR Service on the machine where you intend to install. If your previous installation was done using InstallShield, use &amp;quot;stop BR service&amp;quot; from the Programs/BR Service icon list. &lt;br /&gt;
# You can also stop the BR Service by going to start, run, and typing &amp;quot;install /release&amp;quot;. &lt;br /&gt;
# If your previous installation was done using InstallShield, you can remove it by using the Add/Remove Programs feature in the Control Panel. In this case, your [[BRConfig.sys]] and [[license file]] will not be removed. This is to make them available for subsequent use. &lt;br /&gt;
# When you run install, installation will modify your BRListener.conf file if your target directory is different from the one previously specified. &lt;br /&gt;
&lt;br /&gt;
*BRListener ([[4.13]]) was changed to allow multiple label statements. It works in conjunction with a new build of the Client ([[4.12c]]).&lt;br /&gt;
&lt;br /&gt;
The listeners recognize a qualifying prefix on [[brlistener.conf|CONF]] file statements. This supports having different listeners active at the same time. This permits testing in production client-server environments.&lt;br /&gt;
&lt;br /&gt;
 @release = 1.2        PORT=8555&lt;br /&gt;
 @release = 2.0        PORT=8557&lt;br /&gt;
 @release &amp;lt; 2.0 EXECUTABLE = /ads/sys/br.d/brserver&lt;br /&gt;
 @release &amp;gt;= 2.0 EXECUTABLE = /ads/sys/br.d/brserver.new&lt;br /&gt;
&lt;br /&gt;
The full syntax for the Windows brlistenerinstaller is:&lt;br /&gt;
&lt;br /&gt;
brlistenerinstaller [/RELEASE] [/ALTERNATE alternate] [brlistener-path]&lt;br /&gt;
 &lt;br /&gt;
[/RELEASE] removes this service.&lt;br /&gt;
[/ALTERNATE alternate] uses an alternate service name. This will result in a service named BR_Listener-(alternate).&lt;br /&gt;
&lt;br /&gt;
The second brlistener must be installed using the ALTERNATE keyword followed by a number. Under Linux this is handled by naming the listeners differently. &lt;br /&gt;
&lt;br /&gt;
Persistent Login – Brlistener Release 2.0 in MULTISESSION Mode&lt;br /&gt;
&lt;br /&gt;
A Client session ID is stored in the registry on the client side and associated with the user login name. This is maintained in memory by the BRlistener along with the user&#039;s login-name and password. The listener first checks the user&#039;s client session ID before prompting for login info.&lt;br /&gt;
&lt;br /&gt;
[BRclient] communicates with [BRlistener] over TCP encrypted by TLS.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Files]]&lt;br /&gt;
[[Category:Client Server]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=System_(command)&amp;diff=11029</id>
		<title>System (command)</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=System_(command)&amp;diff=11029"/>
		<updated>2018-11-01T15:50:30Z</updated>

		<summary type="html">&lt;p&gt;GomezL: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The &#039;&#039;&#039;System (SY)&#039;&#039;&#039; [[:Category:commands|command]] can do two things:&lt;br /&gt;
#Exit BR and return control to the [[operating system]], or &lt;br /&gt;
#Perform a &#039;&#039;&#039;shell call&#039;&#039;&#039; (an operating system command) while BR is active. &lt;br /&gt;
&lt;br /&gt;
System can be executed from [[READY mode]], from a [[procedure file]], or with the [[Execute]] [[statement]].&lt;br /&gt;
&lt;br /&gt;
==Using SYSTEM to exit BR==&lt;br /&gt;
&lt;br /&gt;
Entering SYSTEM or it&#039;s short form, SY into the command line while in ready mode will exit BR. The same can be done using an [[Execute]] Statement or a procedure file. &lt;br /&gt;
&lt;br /&gt;
[[image:Sy.jpg]]&lt;br /&gt;
[[image:System2.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Using SYSTEM to send commands to the operating system==&lt;br /&gt;
===Comments and Examples===&lt;br /&gt;
One use of the SYSTEM command is to run a program. In the following example, the SYSTEM command runs a program called BACKUP. By default, the first program waits until the other program has finished running, and then continues where it left off. The syntax includes the SYSTEM keyword and then the OS command, which in this case is the program name and location of the data to handle. &lt;br /&gt;
&lt;br /&gt;
 SYSTEM BACKUP C:\\*.DAT A: /S&lt;br /&gt;
&lt;br /&gt;
When the same command is used with an asterisks preceding the program name, BACKUP, the BR program restores its own screen upon re-entry:&lt;br /&gt;
&lt;br /&gt;
 SYSTEM *BACKUP C:\\*.DAT A: /S&lt;br /&gt;
&lt;br /&gt;
The statement below tests to see what type of operating system the program is running on, then executes the appropriate SYSTEM command for the operating system:&lt;br /&gt;
&lt;br /&gt;
 00100 IF FILE$(0)(1:3)=&amp;quot;CON:&amp;quot; THEN EXECUTE &amp;quot;SYSTEM DIR&amp;quot; :!ELSE EXECUTE &amp;quot;SYSTEM ls -al /usr/BR&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===Using Batch Files with System Exits===&lt;br /&gt;
&lt;br /&gt;
One use of the System command is to pass a return code to the host operating system as it permanently exits from BR. In the following example, a DOS [[batch file]] tests the return code ([[ERRORLEVEL]]) and performs a specific action according to its value.&lt;br /&gt;
&lt;br /&gt;
 BR PROC START&lt;br /&gt;
 IF ERRORLEVEL 101 GOTO BADERROR&lt;br /&gt;
 IF ERRORLEVEL 100 GOTO BACKUP&lt;br /&gt;
 IF ERRORLEVEL 99 GOTO FORMAT&lt;br /&gt;
 GOTO DONE&lt;br /&gt;
 :BACKUP&lt;br /&gt;
 BACKUPBR&lt;br /&gt;
 :FORMAT&lt;br /&gt;
 FORMAT A:&lt;br /&gt;
 BRSTART&lt;br /&gt;
 :BADERROR&lt;br /&gt;
 ECHO BAD ERROR RETURN CODE &amp;gt;100&lt;br /&gt;
 :DONE&lt;br /&gt;
&lt;br /&gt;
If the command SYSTEM 100 were used to exit from BR while the above batch file was active, DOS would start a back-up procedure as soon as the BR exit was complete.&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
 SYSTEM [&amp;lt; code for OS&amp;gt;|[*]&amp;lt;OS command&amp;gt;]&lt;br /&gt;
[[Image:System.png]]&lt;br /&gt;
&lt;br /&gt;
==Defaults==&lt;br /&gt;
:1) Return control to the operating system with a return code of zero.&lt;br /&gt;
:2) Do not restore screen.&lt;br /&gt;
&lt;br /&gt;
==Parameters==&lt;br /&gt;
&#039;&#039;&#039;Code returned to OS&#039;&#039;&#039; parameter sets the value of the operating system return code which may be accessed using ERRORLEVEL in DOS batch files, and through the $? substitution in a Linux shell.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;OS command&#039;&#039;&#039; parameter is an operating system command which BR passes to the operating system for execution. If the result of the command requires no operator action, BR is immediately reentered after the command finishes execution. Since BR is active during the entire process, all variable values and memory remain the same. When the &#039;&#039;&#039;OS command&#039;&#039;&#039; parameter is preceded by an asterisk, the BR screen is restored upon re-entry. The &#039;&#039;&#039;OS command&#039;&#039;&#039; parameter must be a &#039;&#039;&#039;string variable&#039;&#039;&#039; or a string enclosed in quotes.&lt;br /&gt;
&lt;br /&gt;
Additional Flags that can alter the behavior of the shell call as follows:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;|&#039;&#039;&#039;-E or -e&#039;&#039;&#039;||&amp;quot;Errors&amp;quot; indicates that any Operating System errors returned from the shell should be reported (as error 4300). Otherwise shell call operating errors are ignored. Occasionally Windows returns error values for fairly nominal exceptions. So the -e is provided as an error return sensitivity level flag.  Further information can be obtained by querying SYSERR or SYSERR$&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;|&#039;&#039;&#039;-M or -m&#039;&#039;&#039;|| Run the program &amp;quot;minimized&amp;quot;.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;| ||If a lower case m is specified, the process or program runs in a DOS command shell without displaying the DOS window, but with a corresponding icon on the task bar (effectively running the shelled process/program &amp;quot;minimized&amp;quot;) This is only applicable in Windows. It is ignored on all other systems.  If -m is omitted, the shelled program will open in a separate application window.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;| ||If an upper case M is specified, the same thing happens except the task does not appear on the taskbar. It runs invisibly. Furthermore [[SPOOLCMD]] calls use lowercase m.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;|&#039;&#039;&#039;-s&#039;&#039;&#039;||Server Shell Call (this is the default for Unix). If -s is omitted on Windows, then this shell call is performed on the client.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;|&#039;&#039;&#039;-@&#039;&#039;&#039;||If using Client Server, then it runs the program on the  client. Client Shell Call is the default for Windows. If -@ is omitted, on Unix the shell call is performed on the server.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;| ||(search path not implemented  on client)&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;| ||Note- Ctrl-] ALWAYS performs a DOS shell call on the client.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;|&#039;&#039;&#039;-c&#039;&#039;&#039;||The main program &amp;quot;continues&amp;quot; to run while running the called one.  Windows launches the task and resumes BR operation where it left off. For Unix, the command is framed with NOHUP and &amp;amp;. If -c is omitted, then the shell call waits til the process is finished (up to the # seconds specified in SHELL LIMITS) before returning to BR.&lt;br /&gt;
&lt;br /&gt;
For [[OSX]] 10.6 you need&lt;br /&gt;
&lt;br /&gt;
sys -c | (pipe) Shell commands with a pipe make BR Continue after executing the sys -c (continue), if you do not insert the | pipe, then the script does not run under Br [[4.18]] and up.&lt;br /&gt;
This was found on a Macintosh client that just updated to OSX 10.6.x&lt;br /&gt;
&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;|&#039;&#039;&#039;-r&#039;&#039;&#039;||&amp;quot;Restore&amp;quot; means that Windows always performs shell in a separate window. (Unix ignores shell standard out data). If -r is omitted. then Unix forwards standard out and stdin data to and from the client window.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;| ||Restores screen after running command on all systems.  In windows, the screen is always restored, so this flag is essentially ignored. This is the same as sys *command.  The newer syntax is more readable and preferred.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;|&#039;&#039;&#039;-w&#039;&#039;&#039;||(&amp;quot;without shell&amp;quot;) When a Windows application is called, use a -w flag to tell BR not to call COMMAND.COM, but to call the application directly.  It must be a program (i.e. &amp;quot;exe&amp;quot;) and not a script. The Search Path is used ON SERVER only (if no slashes). This option does NOT open a DOS window. It does not use Bourne shell. It enables unfiltered return values. A Timeout or Ctrl-A kills the process. If -w is omitted, then a timeout or Ctrl-A does NOT kill the process, which can leave orphans.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;| ||Note- Currently -w is ignored in Unix standard models.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;|&#039;&#039;&#039;blank&#039;&#039;&#039;||Application standard output is forwarded to the client. However the Bourne shell is utilized to initiate the process. The shelled program CAN be an executable script.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;|&#039;&#039;&#039;-p&#039;&#039;&#039;||(&amp;quot;Page Standard Output&amp;quot;) - This option applies to Unix server only. If -p is omitted, then output goes to screen without pausing&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;60&amp;quot;|&#039;&#039;&#039;-t9999&#039;&#039;&#039;||Wait up to the specified number of seconds (for client server only). If -t is omitted, wait the number of seconds specified in the [[SHELL LIMIT]] statement (see [[BRConfig.sys]] chapter for more information on [[SHELL LIMIT]])&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Technical Considerations==&lt;br /&gt;
:1) Simultaneous pressing of the Ctrl key and the right- bracket (]) key has the same effect as the SYSTEM command&#039;s shell call, except that no command string is automatically executed upon access to the operating system. Pressing of these keys causes BR immediately access the operating system and display the system prompt. Between each operating system operation, a message about what action is required to return to BR will be displayed.&lt;br /&gt;
:2) Too frequent or careless use of the SYSTEM command can make it more difficult to move your program to a new operating system. ADS strongly recommends the use of the FILE$ function in programs and procedures which access the resident operating system. This function allows programs to test the type of operating system before proceeding with a system-dependent sequence of commands. While the FILE$ function can always be programmed in at a later date, you may be able to save a great deal of time and recoding by placing it in programs as they are written.&lt;br /&gt;
:3) When the system call (either Ctrl-] or the [[SYSTEM]] command) starts and then exits a secondary software program before returning to [[BR]], the [[CODE]] function will reflect any return code that the secondary program has passed to the operating system. As soon as BR is reactivated, the value of [[CODE]] can be tested to Verify whether or not the secondary program was successful. This is currently valid for Linux versions of [[BR]] only.&lt;br /&gt;
:4) [[BR]] passes all quotation marks within or surrounding the &amp;quot;string-expr&amp;quot; parameter back to the operating system.&lt;br /&gt;
:5) The screen may be cleared on some Linux terminals when the [[SYSTEM]] call is completed. If this is undesirable, see [[Terminal Considerations]] for a possible remedy.&lt;br /&gt;
:6) BR now searches PATHs during Windows shell call.&lt;br /&gt;
:7) Shell calls to Windows applications are no longer maximized.&lt;br /&gt;
:8) System calls -M -W -C -R now operate like their corresponding lower case flags.  This case sensitivity had been suppressed to allow passing the flags to DOS, but that made the rules too obscure.&lt;br /&gt;
:9) Concerning Unix shell calls, the following flag combinations are prevented-&lt;br /&gt;
:-W and -C&amp;lt;br&amp;gt;&lt;br /&gt;
:-R and -C&amp;lt;br&amp;gt;&lt;br /&gt;
:-W and -R&amp;lt;br&amp;gt;&lt;br /&gt;
:In other words Without Shell, Restore Screen, and Continue are mutually exclusive options.  If more than one is specified at a time, error [[2222]] is generated.&lt;br /&gt;
&lt;br /&gt;
For disambiguation purposes, also see [[System Parameter]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Commands]]&lt;br /&gt;
[[Category:Executive Commands]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Multi-Line_Textbox&amp;diff=11028</id>
		<title>Multi-Line Textbox</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Multi-Line_Textbox&amp;diff=11028"/>
		<updated>2018-10-20T18:30:43Z</updated>

		<summary type="html">&lt;p&gt;GomezL: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&#039;&#039;&#039;Multi-Line TextBoxes&#039;&#039;&#039; are accomplished in BR! by using an [[Input Fields]] [[statement]].  Here is a sample:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  00010   DIM Buff$*2048&lt;br /&gt;
  00012   LET Buff$=&#039;start with something&#039;&lt;br /&gt;
  00020   RINPUT FIELDS &#039;#0,5,2,text 14/58/20,[D]s&#039;: Buff$&lt;br /&gt;
&lt;br /&gt;
Syntax: Text [Rows]/[Columns]/[Max Char]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Widget]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Multi-Line_Textbox&amp;diff=11027</id>
		<title>Multi-Line Textbox</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Multi-Line_Textbox&amp;diff=11027"/>
		<updated>2018-10-20T18:30:28Z</updated>

		<summary type="html">&lt;p&gt;GomezL: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&#039;&#039;&#039;Multi-Line TextBoxes&#039;&#039;&#039; are accomplished in BR! by using an [[Input Fields]] [[statement]].  Here is a sample:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  00010   DIM Buff$*2048&lt;br /&gt;
  00012   LET Buff$=&#039;start with something&#039;&lt;br /&gt;
  00020   RINPUT FIELDS &#039;#0,5,2,text 14/58/20,[D]s&#039;: Buff$&lt;br /&gt;
&lt;br /&gt;
Syntax: Text [Rows]/[Columns]/[Max Charr]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Widget]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Text&amp;diff=10952</id>
		<title>Text</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Text&amp;diff=10952"/>
		<updated>2018-07-09T17:06:39Z</updated>

		<summary type="html">&lt;p&gt;GomezL: /* TEXT FIELD FORMAT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==  TEXT FIELD FORMAT==&lt;br /&gt;
As of 4.3&lt;br /&gt;
&lt;br /&gt;
 10  (R)INPUT FIELDS “row, col, TEXT rows/cols[/capacity],  leading-attr,  …”:&lt;br /&gt;
&lt;br /&gt;
This format is similar to the C/V/G format with the ^ENTER_LF attribute except:&lt;br /&gt;
No trailing space padding or trimming occurs.&lt;br /&gt;
&lt;br /&gt;
Rows and columns are specified.&lt;br /&gt;
Field capacity or newlines can cause a vertical scrollbar to appear.&lt;br /&gt;
&lt;br /&gt;
Supported leading attributes are ^ENTER_LF (the default), ^ENTER_CRLF and ^NOWRAP.&lt;br /&gt;
The TEXT keyword will imply ^ENTER_LF unless ^ENTER_CRLF is specified.&lt;br /&gt;
&lt;br /&gt;
^ENTER_LF (the default) causes the ENTER key to add LF characters to the data and to go to a new line left justified. The cursor will retrace the data when backspace or left-arrow is keyed, meaning the on-screen LF characters are represented by moving the cursor, instead of allowing it to rest on invisible LF characters.&lt;br /&gt;
&lt;br /&gt;
^ENTER_CRLF may be specified in lieu of ^ENTER_LF. When that is the case, carriage returns entered are represented in the data as carriage-return-linefeed (CRLF) character pairs.  ^NOWRAP may be specified to suppress word wrapping. When ^NOWRAP is active, data is entered on the current line until ENTER is keyed to go to the next line. Both horizontal and vertical scroll bars appear as needed.&lt;br /&gt;
&lt;br /&gt;
Tabs are entered into the text. Shift-tab is ignored.&lt;br /&gt;
&lt;br /&gt;
Home, End and the arrow keys all operate relative to the current line as opposed to operating on the text box as a whole.&lt;br /&gt;
&lt;br /&gt;
Depressing the Control key causes the following keys to operate in the normal string entry mode:&lt;br /&gt;
&lt;br /&gt;
*Enter – Returns control to the BR program&lt;br /&gt;
*Tab – Goes to the next control&lt;br /&gt;
*Shift-Tab – Goes to the prior control&lt;br /&gt;
*Home – Goes to the beginning of data or the first field&lt;br /&gt;
*End – Goes to the end of data or the last field&lt;br /&gt;
*Left-Arrow/Up-Arrow – Goes to the prior control&lt;br /&gt;
*Right-Arrow/Down-Arrow – Goes to the next control&lt;br /&gt;
* [[CurPos]] introduced.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A sample program to demonstrate TEXT entry is:&lt;br /&gt;
 01000 ! Rep Text&lt;br /&gt;
 01020 ! Test New Text Field Type&lt;br /&gt;
 01040    dim TEXT$*300, TEXT$(1)*80&lt;br /&gt;
 01060    print NEWPAGE&lt;br /&gt;
 01080    rinput fields &amp;quot;3,10,text 4/40/300,uh&amp;quot;: TEXT$&lt;br /&gt;
 01100    print fields &amp;quot;10,10,c&amp;quot;: TEXT$&lt;br /&gt;
 01120    print TEXT$&lt;br /&gt;
 01140    let STR2MAT(TEXT$, MAT TEXT$, CHR$(10))&lt;br /&gt;
 01160   print MAT TEXT$&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Format Specifications]]&lt;br /&gt;
[[Category:All Parameters]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Text&amp;diff=10951</id>
		<title>Text</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Text&amp;diff=10951"/>
		<updated>2018-07-09T17:05:07Z</updated>

		<summary type="html">&lt;p&gt;GomezL: /* TEXT FIELD FORMAT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==  TEXT FIELD FORMAT==&lt;br /&gt;
As of 4.3&lt;br /&gt;
&lt;br /&gt;
 10  (R)INPUT FIELDS “row, col, TEXT rows/cols[/capacity],  leading-attr,  …”:&lt;br /&gt;
&lt;br /&gt;
This format is similar to the C/V/G format with the ^ENTER_LF attribute except:&lt;br /&gt;
No trailing space padding or trimming occurs.&lt;br /&gt;
&lt;br /&gt;
Rows and columns are specified.&lt;br /&gt;
Field capacity or newlines can cause a vertical scrollbar to appear.&lt;br /&gt;
&lt;br /&gt;
Supported leading attributes are ^ENTER_LF (the default), ^ENTER_CRLF and ^NOWRAP.&lt;br /&gt;
The TEXT keyword will imply ^ENTER_LF unless ^ENTER_CRLF is specified.&lt;br /&gt;
&lt;br /&gt;
^ENTER_LF (the default) causes the ENTER key to add LF characters to the data and to go to a new line left justified. The cursor will retrace the data when backspace or left-arrow is keyed, meaning the on-screen LF characters are represented by moving the cursor, instead of allowing it to rest on invisible LF characters.&lt;br /&gt;
&lt;br /&gt;
^ENTER_CRLF may be specified in lieu of ^ENTER_LF. When that is the case, carriage returns entered are represented in the data as carriage-return-linefeed (CRLF) character pairs.  ^NOWRAP may be specified to suppress word wrapping. When ^NOWRAP is active, data is entered on the current line until ENTER is keyed to go to the next line. Both horizontal and vertical scroll bars appear as needed.&lt;br /&gt;
&lt;br /&gt;
Tabs are entered into the text. Shift-tab is ignored.&lt;br /&gt;
&lt;br /&gt;
Home, End and the arrow keys all operate relative to the current line as opposed to operating on the text box as a whole.&lt;br /&gt;
&lt;br /&gt;
Depressing the Control key causes the following keys to operate in the normal string entry mode:&lt;br /&gt;
&lt;br /&gt;
*Enter – Returns control to the BR program&lt;br /&gt;
*Tab – Goes to the next control&lt;br /&gt;
*Shift-Tab – Goes to the prior control&lt;br /&gt;
*Home – Goes to the beginning of data or the first field&lt;br /&gt;
*End – Goes to the end of data or the last field&lt;br /&gt;
*Left-Arrow/Up-Arrow – Goes to the prior control&lt;br /&gt;
*Right-Arrow/Down-Arrow – Goes to the next control&lt;br /&gt;
* [[CurPos]] introduced.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A sample program to demonstrate TEXT entry is:&lt;br /&gt;
 01000 ! Rep Text&lt;br /&gt;
 01020 ! Test New Text Field Type&lt;br /&gt;
 01040    dim TEXT$*300, TEXT$(1)*80&lt;br /&gt;
 01060    print NEWPAGE&lt;br /&gt;
 01080    rinput fields &amp;quot;3,10,text 4/40/300,uh&amp;quot;: TEXT$&lt;br /&gt;
 01100    print fields &amp;quot;10,10,c&amp;quot;: TEXT$&lt;br /&gt;
 01120    print TEXT$&lt;br /&gt;
 01140    let STR2MAT(TEXT$, MAT TEXT$, CHR$(10))&lt;br /&gt;
 01160   print MAT TEXT$&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Format Specifications]]&lt;br /&gt;
[[Category:Field Specifications]]&lt;br /&gt;
[[Category:All Parameters]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Text&amp;diff=10950</id>
		<title>Text</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Text&amp;diff=10950"/>
		<updated>2018-07-09T17:04:02Z</updated>

		<summary type="html">&lt;p&gt;GomezL: /* TEXT FIELD FORMAT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==  TEXT FIELD FORMAT==&lt;br /&gt;
As of 4.3&lt;br /&gt;
&lt;br /&gt;
 10  (R)INPUT FIELDS “row, col, TEXT rows/cols[/capacity],  leading-attr,  …”:&lt;br /&gt;
&lt;br /&gt;
This format is similar to the C/V/G format with the ^ENTER_LF attribute except:&lt;br /&gt;
No trailing space padding or trimming occurs.&lt;br /&gt;
&lt;br /&gt;
Rows and columns are specified.&lt;br /&gt;
Field capacity or newlines can cause a vertical scrollbar to appear.&lt;br /&gt;
&lt;br /&gt;
Supported leading attributes are ^ENTER_LF (the default), ^ENTER_CRLF and ^NOWRAP.&lt;br /&gt;
The TEXT keyword will imply ^ENTER_LF unless ^ENTER_CRLF is specified.&lt;br /&gt;
&lt;br /&gt;
^ENTER_LF (the default) causes the ENTER key to add LF characters to the data and to go to a new line left justified. The cursor will retrace the data when backspace or left-arrow is keyed, meaning the on-screen LF characters are represented by moving the cursor, instead of allowing it to rest on invisible LF characters.&lt;br /&gt;
&lt;br /&gt;
^ENTER_CRLF may be specified in lieu of ^ENTER_LF. When that is the case, carriage returns entered are represented in the data as carriage-return-linefeed (CRLF) character pairs.  ^NOWRAP may be specified to suppress word wrapping. When ^NOWRAP is active, data is entered on the current line until ENTER is keyed to go to the next line. Both horizontal and vertical scroll bars appear as needed.&lt;br /&gt;
&lt;br /&gt;
Tabs are entered into the text. Shift-tab is ignored.&lt;br /&gt;
&lt;br /&gt;
Home, End and the arrow keys all operate relative to the current line as opposed to operating on the text box as a whole.&lt;br /&gt;
&lt;br /&gt;
Depressing the Control key causes the following keys to operate in the normal string entry mode:&lt;br /&gt;
&lt;br /&gt;
*Enter – Returns control to the BR program&lt;br /&gt;
*Tab – Goes to the next control&lt;br /&gt;
*Shift-Tab – Goes to the prior control&lt;br /&gt;
*Home – Goes to the beginning of data or the first field&lt;br /&gt;
*End – Goes to the end of data or the last field&lt;br /&gt;
*Left-Arrow/Up-Arrow – Goes to the prior control&lt;br /&gt;
*Right-Arrow/Down-Arrow – Goes to the next control&lt;br /&gt;
* [[CurPos]] introduced.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A sample program to demonstrate TEXT entry is:&lt;br /&gt;
 01000 ! Rep Text&lt;br /&gt;
 01020 ! Test New Text Field Type&lt;br /&gt;
 01040    dim TEXT$*300, TEXT$(1)*80&lt;br /&gt;
 01060    print NEWPAGE&lt;br /&gt;
 01080    rinput fields &amp;quot;3,10,text 4/40/300,uh&amp;quot;: TEXT$&lt;br /&gt;
 01100    print fields &amp;quot;10,10,c&amp;quot;: TEXT$&lt;br /&gt;
 01120    print TEXT$&lt;br /&gt;
 01140    let STR2MAT(TEXT$, MAT TEXT$, CHR$(10))&lt;br /&gt;
 01160   print MAT TEXT$&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Field Specifications]]&lt;br /&gt;
[[Category:All Parameters]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Copy&amp;diff=10909</id>
		<title>Copy</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Copy&amp;diff=10909"/>
		<updated>2017-09-25T14:35:37Z</updated>

		<summary type="html">&lt;p&gt;GomezL: /* Technical Considerations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The &#039;&#039;&#039;Copy (COP)&#039;&#039;&#039; [[command]] copies one or more files in numerous ways:&lt;br /&gt;
# From one directory to another on the same or different disks.&lt;br /&gt;
# From one place on a directory to another place on the same directory. In this case you must give the resultant copy a different name.&lt;br /&gt;
# From a file to a printer.&lt;br /&gt;
# The -S option has been added to allow copying of a file which is currently open. The file to be copied must be opened for sharing ([[Shr]] or [[ShrI]]). If it is opened [[NoShr]], a file sharing violation error [[4148]] will occur when Copy with -S is attempted.&lt;br /&gt;
&lt;br /&gt;
==Comments and Examples==&lt;br /&gt;
&lt;br /&gt;
When using the copy command, you may specify a drive letter or number, and a path. You may also use [[wildcard characters]] &#039;&#039;&#039;?&#039;&#039;&#039; and &#039;&#039;&#039;*&#039;&#039;&#039; in place of alphanumeric characters in file names. [[Redirection symbols]] &#039;&#039;&#039;&amp;gt;&#039;&#039;&#039; and &#039;&#039;&#039;&amp;gt;&amp;gt;&#039;&#039;&#039; redirect screen output to a printer, a file, or another device.&lt;br /&gt;
&lt;br /&gt;
The following command copies the file SAMPLE from the default directory of a disk in drive A to the default directory of a disk in drive B. The file name remains the same:&lt;br /&gt;
&lt;br /&gt;
 COPY A:SAMPLE B:&lt;br /&gt;
&lt;br /&gt;
The next command copies the file SAMPLE from the subdirectory \TEST1 on a disk in drive A to the subdirectory \TEST2 on the same disk. If TEST2 does not exist as a subdirectory, Business Rules names the file TEST2 and places it in the default directory on the default drive:&lt;br /&gt;
&lt;br /&gt;
 COPY A:\TEST1\SAMPLE A:\TEST2&lt;br /&gt;
&lt;br /&gt;
The following command copies SAMPLE from one place in the subdirectory \TEST1 on a disk in drive A to another place in the same subdirectory. The copied file is renamed SAMPLE1:&lt;br /&gt;
&lt;br /&gt;
 COPY A:\TEST1\SAMPLE A:\TEST1\SAMPLE1&lt;br /&gt;
&lt;br /&gt;
The next command copies the file SAMPLE from the default directory of a disk in drive B to a printer attached to the first parallel port:&lt;br /&gt;
&lt;br /&gt;
 COPY B:SAMPLE PRN:&lt;br /&gt;
&lt;br /&gt;
The same file can be copied to the printer at the first serial port with the following command:&lt;br /&gt;
&lt;br /&gt;
 COPY B:SAMPLE AUX:&lt;br /&gt;
&lt;br /&gt;
The next command copies all files with names starting with SAMPLE, a period and any extension from a disk in drive A to a disk in drive B. The &#039;&#039;&#039;D&#039;&#039;&#039; in the command causes deleted records to be removed from any of the SAMPLE files which are internal files. The &#039;&#039;&#039;C&#039;&#039;&#039; in the command causes Business Rules! to prompt for a diskette change if the disk in drive B fills up before the copying process is completed.&lt;br /&gt;
&lt;br /&gt;
 COPY A:SAMPLE.* B: -DC&lt;br /&gt;
&lt;br /&gt;
The following example copies the internal file SAMPLE from a disk in drive A to a disk in drive B, setting the record length of the new file at 128:&lt;br /&gt;
&lt;br /&gt;
 COPY A:SAMPLE B: -128&lt;br /&gt;
&lt;br /&gt;
As of 4.2, COPY supports copying a print file unaltered to a printer:&lt;br /&gt;
 COPY PRT\EDITLIST.255  DIRECT:/HP4&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
 COPY &amp;lt;from file&amp;gt; {[AUX:]|[PRN:]|[&amp;lt;to file&amp;gt;]} {[&amp;gt;[&amp;gt;]&amp;lt;output file&amp;gt;]|[PRINT]} [&amp;lt;[[copy option|-option]]&amp;gt;][-...]&lt;br /&gt;
&lt;br /&gt;
[[Image:Copy.png]]&lt;br /&gt;
&lt;br /&gt;
==Defaults==&lt;br /&gt;
# Copy the file, using the current file name, into the current directory on the current drive.&lt;br /&gt;
# Display a log of all performed actions in the [[command console]].&lt;br /&gt;
&lt;br /&gt;
==Parameters==&lt;br /&gt;
&lt;br /&gt;
Copy requires the &#039;&#039;&#039;from file&#039;&#039;&#039; parameter, which provides the information necessary for identifying the file or files you wish to copy.&lt;br /&gt;
&lt;br /&gt;
After the &#039;&#039;&#039;from file&#039;&#039;&#039;, you may specify the optional parameter &#039;&#039;&#039;to file&#039;&#039;&#039;, which is the name (and path, if required) of the file you are creating.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PRN:&#039;&#039;&#039; allows you to copy the file indicated in the &#039;&#039;&#039;from file&#039;&#039;&#039; to the printer attached to the first parallel port on DOS systems. This string must be translated with the [[SUBSTITUTE]] specification in [[BRConfig.sys]] to specify the appropriate output device on [[Linux]] systems.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;AUX:&#039;&#039;&#039; copies the &#039;&#039;&#039;from file&#039;&#039;&#039; file to the printer attached to the first [[serial port]]. This string must be translated with the SUBSTITUTE specification for Business Rules! Linux versions.&lt;br /&gt;
&lt;br /&gt;
In place of the &#039;&#039;&#039;PRN:&#039;&#039;&#039; or &#039;&#039;&#039;AUX:&#039;&#039;&#039; parameters, you may also specify COM1:, COM2:, LPT1:, LPT2:, etc. to indicate the port to which your printer is attached (see the drive discussion in the Definitions chapter for more information). These device references will operate properly only on Business Rules DOS versions. They may be mapped to new references with the BRConfig.sys file&#039;s SUBSTITUTE specification.&lt;br /&gt;
&lt;br /&gt;
The redirection symbol in the &#039;&#039;&#039;&amp;gt;file-ref&#039;&#039;&#039; parameter saves messages that normally appear on the screen to the specified file. The &#039;&#039;&#039;PRINT&#039;&#039;&#039; parameter sends these same messages to the printer rather than to the screen or a file.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Option&#039;&#039;&#039; may be one or more of several optional parameters. Such option(s) can follow the copy command when separated from the rest of the command with a dash:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;-A&#039;&#039;&#039;||tells the system to copy only files that have the archive bit on. The system turns the archive bits in the original files off when the copying process is complete. This option applies to Business Rules! [[DOS]] versions only.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;-C&#039;&#039;&#039;||prompts for a diskette change if the disk is full.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;-D&#039;&#039;&#039;||omits deleted records from the copy, but responds only when used with internal files. It is important to rebuild all related index files after using this option.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;-N&#039;&#039;&#039;||prevents the screen from showing a log of performed actions.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;-P&#039;&#039;&#039;||causes scrolling to pause after a full screen of information has been displayed. (Press &amp;lt;CR&amp;gt; for next screen.)&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;-S&#039;&#039;&#039;||option has been added to allow copying of a file which is currently open. The file to be copied must be opened for sharing (SHR or SHRI) if it is opened NOSHR, error [[4148]] (file sharing violation) will occur when COPY with the -S is attempted.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;-V&#039;&#039;&#039;||requires the operator to Verify each action before Business Rules! performs it.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;-#&#039;&#039;&#039;||represents output file record length. Internal file record lengths are shortened or expanded (with blanks) to match the number you indicate (version [[2.04]]+). When specified with other options, the record length must always be last.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Technical Considerations==&lt;br /&gt;
Prior to version [[3.0]] the -S switch meant preserve space.  That syntax is no longer supported. -s now refers to file sharing as noted above.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
COPY to a printer :DEVICE was being rejected. COPY to a PRN: or WIN: device is still illegal. (Use TYPE with redirection for PRN: and WIN:)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
While the [Source] Directory is very flexible supporting *, *.* &amp;amp; *.*.* to include &amp;quot;All Files&amp;quot;, the [Destination] Directory is less flexibe.    &lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
 Copy Source\* Destination&lt;br /&gt;
* This sample will copy all files to Destination - This is the preferred syntax for copy&lt;br /&gt;
&lt;br /&gt;
 Copy Source\* Destination\*&lt;br /&gt;
* This sample will copy all files to Destination but will Remove any Extension so &amp;quot;Sample.wb&amp;quot; will become &amp;quot;Sample&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 Copy Source\* Destination\*.*&lt;br /&gt;
* This sample will copy all files to Destination but complex files like &amp;quot;Sample.wb.brs&amp;quot; will become &amp;quot;Sample.wb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 Copy Source\* Destination\*.*.*&lt;br /&gt;
* This sample will copy all files to Destination complex files like &amp;quot;Sample.wb.brs&amp;quot; will become &amp;quot;Sample.wb.brs&amp;quot;  - Files with more &amp;quot;.&amp;quot; would also be truncated.&lt;br /&gt;
&lt;br /&gt;
==Client Server==&lt;br /&gt;
&lt;br /&gt;
 COPY    filename      @:filename      (@ indicates Client system)&lt;br /&gt;
&lt;br /&gt;
Copies filename TO client current directory&lt;br /&gt;
&lt;br /&gt;
(Or specify @:pathname relative to client current directory.)&lt;br /&gt;
&lt;br /&gt;
 COPY      @:filename      filename&lt;br /&gt;
&lt;br /&gt;
Copies filename FROM client current directory.&lt;br /&gt;
&lt;br /&gt;
If you are trying to use [[absolute paths]] on the [[client]], specify @::&lt;br /&gt;
&lt;br /&gt;
This is really most useful with [[OPEN:]] and [[SAVE:]] file selection browsers.&lt;br /&gt;
&lt;br /&gt;
Use caution when using absolute paths on the client because [[permissions]] and [[file systems]] can be different from one computer to another.&lt;br /&gt;
&lt;br /&gt;
Normally BR will use the [[startup directory]] to copy things and you can change this in the shortcut if needed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Commands]]&lt;br /&gt;
[[Category:File Management Commands]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Copy&amp;diff=10908</id>
		<title>Copy</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Copy&amp;diff=10908"/>
		<updated>2017-09-25T14:34:44Z</updated>

		<summary type="html">&lt;p&gt;GomezL: /* Technical Considerations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The &#039;&#039;&#039;Copy (COP)&#039;&#039;&#039; [[command]] copies one or more files in numerous ways:&lt;br /&gt;
# From one directory to another on the same or different disks.&lt;br /&gt;
# From one place on a directory to another place on the same directory. In this case you must give the resultant copy a different name.&lt;br /&gt;
# From a file to a printer.&lt;br /&gt;
# The -S option has been added to allow copying of a file which is currently open. The file to be copied must be opened for sharing ([[Shr]] or [[ShrI]]). If it is opened [[NoShr]], a file sharing violation error [[4148]] will occur when Copy with -S is attempted.&lt;br /&gt;
&lt;br /&gt;
==Comments and Examples==&lt;br /&gt;
&lt;br /&gt;
When using the copy command, you may specify a drive letter or number, and a path. You may also use [[wildcard characters]] &#039;&#039;&#039;?&#039;&#039;&#039; and &#039;&#039;&#039;*&#039;&#039;&#039; in place of alphanumeric characters in file names. [[Redirection symbols]] &#039;&#039;&#039;&amp;gt;&#039;&#039;&#039; and &#039;&#039;&#039;&amp;gt;&amp;gt;&#039;&#039;&#039; redirect screen output to a printer, a file, or another device.&lt;br /&gt;
&lt;br /&gt;
The following command copies the file SAMPLE from the default directory of a disk in drive A to the default directory of a disk in drive B. The file name remains the same:&lt;br /&gt;
&lt;br /&gt;
 COPY A:SAMPLE B:&lt;br /&gt;
&lt;br /&gt;
The next command copies the file SAMPLE from the subdirectory \TEST1 on a disk in drive A to the subdirectory \TEST2 on the same disk. If TEST2 does not exist as a subdirectory, Business Rules names the file TEST2 and places it in the default directory on the default drive:&lt;br /&gt;
&lt;br /&gt;
 COPY A:\TEST1\SAMPLE A:\TEST2&lt;br /&gt;
&lt;br /&gt;
The following command copies SAMPLE from one place in the subdirectory \TEST1 on a disk in drive A to another place in the same subdirectory. The copied file is renamed SAMPLE1:&lt;br /&gt;
&lt;br /&gt;
 COPY A:\TEST1\SAMPLE A:\TEST1\SAMPLE1&lt;br /&gt;
&lt;br /&gt;
The next command copies the file SAMPLE from the default directory of a disk in drive B to a printer attached to the first parallel port:&lt;br /&gt;
&lt;br /&gt;
 COPY B:SAMPLE PRN:&lt;br /&gt;
&lt;br /&gt;
The same file can be copied to the printer at the first serial port with the following command:&lt;br /&gt;
&lt;br /&gt;
 COPY B:SAMPLE AUX:&lt;br /&gt;
&lt;br /&gt;
The next command copies all files with names starting with SAMPLE, a period and any extension from a disk in drive A to a disk in drive B. The &#039;&#039;&#039;D&#039;&#039;&#039; in the command causes deleted records to be removed from any of the SAMPLE files which are internal files. The &#039;&#039;&#039;C&#039;&#039;&#039; in the command causes Business Rules! to prompt for a diskette change if the disk in drive B fills up before the copying process is completed.&lt;br /&gt;
&lt;br /&gt;
 COPY A:SAMPLE.* B: -DC&lt;br /&gt;
&lt;br /&gt;
The following example copies the internal file SAMPLE from a disk in drive A to a disk in drive B, setting the record length of the new file at 128:&lt;br /&gt;
&lt;br /&gt;
 COPY A:SAMPLE B: -128&lt;br /&gt;
&lt;br /&gt;
As of 4.2, COPY supports copying a print file unaltered to a printer:&lt;br /&gt;
 COPY PRT\EDITLIST.255  DIRECT:/HP4&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
 COPY &amp;lt;from file&amp;gt; {[AUX:]|[PRN:]|[&amp;lt;to file&amp;gt;]} {[&amp;gt;[&amp;gt;]&amp;lt;output file&amp;gt;]|[PRINT]} [&amp;lt;[[copy option|-option]]&amp;gt;][-...]&lt;br /&gt;
&lt;br /&gt;
[[Image:Copy.png]]&lt;br /&gt;
&lt;br /&gt;
==Defaults==&lt;br /&gt;
# Copy the file, using the current file name, into the current directory on the current drive.&lt;br /&gt;
# Display a log of all performed actions in the [[command console]].&lt;br /&gt;
&lt;br /&gt;
==Parameters==&lt;br /&gt;
&lt;br /&gt;
Copy requires the &#039;&#039;&#039;from file&#039;&#039;&#039; parameter, which provides the information necessary for identifying the file or files you wish to copy.&lt;br /&gt;
&lt;br /&gt;
After the &#039;&#039;&#039;from file&#039;&#039;&#039;, you may specify the optional parameter &#039;&#039;&#039;to file&#039;&#039;&#039;, which is the name (and path, if required) of the file you are creating.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PRN:&#039;&#039;&#039; allows you to copy the file indicated in the &#039;&#039;&#039;from file&#039;&#039;&#039; to the printer attached to the first parallel port on DOS systems. This string must be translated with the [[SUBSTITUTE]] specification in [[BRConfig.sys]] to specify the appropriate output device on [[Linux]] systems.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;AUX:&#039;&#039;&#039; copies the &#039;&#039;&#039;from file&#039;&#039;&#039; file to the printer attached to the first [[serial port]]. This string must be translated with the SUBSTITUTE specification for Business Rules! Linux versions.&lt;br /&gt;
&lt;br /&gt;
In place of the &#039;&#039;&#039;PRN:&#039;&#039;&#039; or &#039;&#039;&#039;AUX:&#039;&#039;&#039; parameters, you may also specify COM1:, COM2:, LPT1:, LPT2:, etc. to indicate the port to which your printer is attached (see the drive discussion in the Definitions chapter for more information). These device references will operate properly only on Business Rules DOS versions. They may be mapped to new references with the BRConfig.sys file&#039;s SUBSTITUTE specification.&lt;br /&gt;
&lt;br /&gt;
The redirection symbol in the &#039;&#039;&#039;&amp;gt;file-ref&#039;&#039;&#039; parameter saves messages that normally appear on the screen to the specified file. The &#039;&#039;&#039;PRINT&#039;&#039;&#039; parameter sends these same messages to the printer rather than to the screen or a file.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Option&#039;&#039;&#039; may be one or more of several optional parameters. Such option(s) can follow the copy command when separated from the rest of the command with a dash:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;-A&#039;&#039;&#039;||tells the system to copy only files that have the archive bit on. The system turns the archive bits in the original files off when the copying process is complete. This option applies to Business Rules! [[DOS]] versions only.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;-C&#039;&#039;&#039;||prompts for a diskette change if the disk is full.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;-D&#039;&#039;&#039;||omits deleted records from the copy, but responds only when used with internal files. It is important to rebuild all related index files after using this option.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;-N&#039;&#039;&#039;||prevents the screen from showing a log of performed actions.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;-P&#039;&#039;&#039;||causes scrolling to pause after a full screen of information has been displayed. (Press &amp;lt;CR&amp;gt; for next screen.)&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;-S&#039;&#039;&#039;||option has been added to allow copying of a file which is currently open. The file to be copied must be opened for sharing (SHR or SHRI) if it is opened NOSHR, error [[4148]] (file sharing violation) will occur when COPY with the -S is attempted.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;-V&#039;&#039;&#039;||requires the operator to Verify each action before Business Rules! performs it.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;-#&#039;&#039;&#039;||represents output file record length. Internal file record lengths are shortened or expanded (with blanks) to match the number you indicate (version [[2.04]]+). When specified with other options, the record length must always be last.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Technical Considerations==&lt;br /&gt;
Prior to version [[3.0]] the -S switch meant preserve space.  That syntax is no longer supported. -s now refers to file sharing as noted above.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
COPY to a printer :DEVICE was being rejected. COPY to a PRN: or WIN: device is still illegal. (Use TYPE with redirection for PRN: and WIN:)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
While the [Source] Directory is very flexible supporting *, *.* &amp;amp; *.*.* to include &amp;quot;All Files&amp;quot;, the [Destination] Directory is less flexibe.    &lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
Copy Source\* Destination&lt;br /&gt;
* This sample will copy all files to Destination - This is the preferred syntax for copy&lt;br /&gt;
&lt;br /&gt;
Copy Source\* Destination\*&lt;br /&gt;
* This sample will copy all files to Destination but will Remove any Extension so &amp;quot;Sample.wb&amp;quot; will become &amp;quot;Sample&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Copy Source\* Destination\*.*&lt;br /&gt;
* This sample will copy all files to Destination but complex files like &amp;quot;Sample.wb.brs&amp;quot; will become &amp;quot;Sample.wb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Copy Source\* Destination\*.*.*&lt;br /&gt;
* This sample will copy all files to Destination complex files like &amp;quot;Sample.wb.brs&amp;quot; will become &amp;quot;Sample.wb.brs&amp;quot;  - Files with more &amp;quot;.&amp;quot; would also be truncated.&lt;br /&gt;
&lt;br /&gt;
==Client Server==&lt;br /&gt;
&lt;br /&gt;
 COPY    filename      @:filename      (@ indicates Client system)&lt;br /&gt;
&lt;br /&gt;
Copies filename TO client current directory&lt;br /&gt;
&lt;br /&gt;
(Or specify @:pathname relative to client current directory.)&lt;br /&gt;
&lt;br /&gt;
 COPY      @:filename      filename&lt;br /&gt;
&lt;br /&gt;
Copies filename FROM client current directory.&lt;br /&gt;
&lt;br /&gt;
If you are trying to use [[absolute paths]] on the [[client]], specify @::&lt;br /&gt;
&lt;br /&gt;
This is really most useful with [[OPEN:]] and [[SAVE:]] file selection browsers.&lt;br /&gt;
&lt;br /&gt;
Use caution when using absolute paths on the client because [[permissions]] and [[file systems]] can be different from one computer to another.&lt;br /&gt;
&lt;br /&gt;
Normally BR will use the [[startup directory]] to copy things and you can change this in the shortcut if needed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Commands]]&lt;br /&gt;
[[Category:File Management Commands]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=TRANSLATE&amp;diff=10892</id>
		<title>TRANSLATE</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=TRANSLATE&amp;diff=10892"/>
		<updated>2017-06-25T18:33:15Z</updated>

		<summary type="html">&lt;p&gt;GomezL: Sample program to create a &amp;quot;Translate&amp;quot; file.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; TRANSLATE=&amp;lt;file ref&amp;gt;&lt;br /&gt;
The &amp;quot;TRANSLATE=file-ref&amp;quot; parameter indicates that character translation is required for all input or output of C, V, G, N, ZD or PIC strings. The file-ref must identify either a 256- or 512-byte file. The first 256 bytes are used as an input translation table. &lt;br /&gt;
&lt;br /&gt;
This optional parameter allows the translation of data to or from another collating sequence. Internally, all computers represent letters of the alphabet, punctuation marks and even digits according to an arbitrary numbering scheme. Today, the common coding schemes is ASCII (American Standard Code for Information Interchange). In the past, EBCDIC (Extended Binary Coded Decimal Interchange Code) was used, especially for main frames. Probably the most common use of the TRANSLATE= capability is translating files between ASCII and EBCDIC.&lt;br /&gt;
&lt;br /&gt;
An example of the difference between ASCII and EBCDIC is that the uppercase letters A, B and C are represented by 65, 66 and 67 respectively in ASCII; but in EBCDIC, they are 193, 194 and 195. Also, in ASCII, the blank or space character is represented by the number 32 while in EBCDIC it is number 64. Although all systems that currently run Business Rules the ASCII coding scheme, some older computer systems use EBCDIC.&lt;br /&gt;
&lt;br /&gt;
Used in [[Open]] statements: [[Open Display|Display]], [[Open Internal|Internal]], [[Open external|external]], and [[Open communications|communications]].&lt;br /&gt;
&lt;br /&gt;
The translate table is made up of 256 characters starting with the replacement value for CHR$(0), and ending with CHR$(255).  &lt;br /&gt;
&lt;br /&gt;
See also the [[XLATE$]] internal function.&lt;br /&gt;
&lt;br /&gt;
Sample Programs to create &amp;quot;TRANSLATE&amp;quot; tables:&lt;br /&gt;
* This program created a TRANSLATE table that will only allow &amp;quot;Common Characters&amp;quot;, and filter out unwanted symbols.   Tihs is commonly used when importing data from Electronic Data files.&lt;br /&gt;
&lt;br /&gt;
 00100   DIM Tbl$*512,Edi_Xlate$*512&lt;br /&gt;
 00110   LET Edi_Xlate$ = Rpt$(&amp;quot; &amp;quot;, 32)&amp;amp;&amp;quot; !&amp;quot;&amp;amp;Chr$(34)&amp;amp;&amp;quot;#$%&amp;amp;&#039;()*+,-./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~*&amp;quot;&amp;amp;Rpt$(&amp;quot; &amp;quot;, 128)&lt;br /&gt;
 00120   LET Edi_Xlate$(11:11)=Chr$(10) : LET Edi_Xlate$(14:14)=Chr$(13)&lt;br /&gt;
 00130   LET Tbl$=Edi_Xlate$&amp;amp;Edi_Xlate$&lt;br /&gt;
 00140   OPEN #1: &amp;quot;NAME=EDI_XLATE,RECL=512,replace&amp;quot;,EXTERNAL,OUTPUT&lt;br /&gt;
 00150   WRITE #1,USING 160: Tbl$&lt;br /&gt;
 00160   FORM Pos 1,C 512&lt;br /&gt;
 00170   CLOSE #1:&lt;br /&gt;
 00180   END&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:All Parameters]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=TimeOut&amp;diff=10834</id>
		<title>TimeOut</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=TimeOut&amp;diff=10834"/>
		<updated>2017-01-26T14:54:59Z</updated>

		<summary type="html">&lt;p&gt;GomezL: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The TIMEOUT error trap can be used with the WAIT parameter The WAIT= parameter on INPUT/RINPUT statements will trigger an error based on the [WAIT] settings. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Terminology]]&lt;br /&gt;
[[Category:Error Conditions]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=4.31&amp;diff=10833</id>
		<title>4.31</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=4.31&amp;diff=10833"/>
		<updated>2017-01-26T14:49:15Z</updated>

		<summary type="html">&lt;p&gt;GomezL: /* Version 431ga */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Release Notes 4.31h&lt;br /&gt;
&lt;br /&gt;
The prior versions were [[4.1]] and [[4.2]] and [[4.30]].&lt;br /&gt;
&lt;br /&gt;
As Of 06/30/2015&lt;br /&gt;
&lt;br /&gt;
===Version 430+zmf===&lt;br /&gt;
Added final keepalive send before turning off the copy_sort_index_sys_cmd flag.&amp;lt;br&amp;gt;&lt;br /&gt;
Revised SSL shutdown wait loop.&amp;lt;br&amp;gt;&lt;br /&gt;
Set SSL shutdown start time (this was causing a reconnect timeout because it wasn&#039;t set).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Changed close listener wait from 5 seconds down to 2 seconds.&lt;br /&gt;
&lt;br /&gt;
===Version 431===&lt;br /&gt;
Made connection status global.&amp;lt;br&amp;gt;&lt;br /&gt;
Prevented sending KB char to server when reconnecting.&amp;lt;br&amp;gt;&lt;br /&gt;
Level 14 logging of client-server messages (debug version only).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Version 431a===&lt;br /&gt;
Error [[413]] message (window not on top) clarified.&amp;lt;br&amp;gt;&lt;br /&gt;
Suppressed logging in checkSSL until CS version match established.&amp;lt;br&amp;gt;&lt;br /&gt;
Polished up source terms and spelling errors - no object affect.&amp;lt;br&amp;gt;&lt;br /&gt;
Revised order of Menu Display responses to brserver.&amp;lt;br&amp;gt;&lt;br /&gt;
Allowed BR MSG() keyboard function to work when Command Console is the active window.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Version 431b===&lt;br /&gt;
Corrected exit pre-processing for both normal and unattended modes.&amp;lt;br&amp;gt;&lt;br /&gt;
Changed &amp;quot;blank&amp;quot; references to &amp;quot;blanksPtr&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
Completely revised UNATTENDED_INPUT_CALL processing.&amp;lt;br&amp;gt;&lt;br /&gt;
Changed HTTP &amp;quot;Client-Inquiry&amp;quot; to &amp;quot;PAGE-URL&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
Added HTTP support for &amp;quot;PAGE-HEADER&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Revised error messages that pertain to system errors to indicate as much.&amp;lt;br&amp;gt;&lt;br /&gt;
Added some DLL errors to the BRERR$ definitions file. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Added support for getting cookies via http. &amp;lt;br&amp;gt;&lt;br /&gt;
Cleaned up some errors causing dumps during termination.&amp;lt;br&amp;gt;&lt;br /&gt;
Switched log information to message boxes for errors that occur while uploading the client DLL.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Revised SYSTEM LOGOFF to not fail to zero session IDs when issued to BRSERVER. &lt;br /&gt;
This is to fix the problem where Windows reports active sessions where there is none, causing WSID&#039;s to be assigned incorrectly.&lt;br /&gt;
&lt;br /&gt;
===br4.31ce===&lt;br /&gt;
Fixed the problem where NOWAIT was being ignored if OPTION 38 was on.&lt;br /&gt;
&lt;br /&gt;
===Version 431d===&lt;br /&gt;
Removed DUPLICATE FLOWSTACK code.&amp;lt;br&amp;gt;&lt;br /&gt;
Revised ENDRUN processing of libraries .. set currentFileChain and currentScreenChain values during library PCB detachment. This fixed a problem detaching a NOFILES library.&amp;lt;br&amp;gt;&lt;br /&gt;
Lots of changes to run.cpp for flowstack processing and readability.&lt;br /&gt;
&lt;br /&gt;
Changes from prior editions:&amp;lt;br&amp;gt;&lt;br /&gt;
*SQL and SYSERR fixes.&lt;br /&gt;
*Suppress error 867 on a radio button.&lt;br /&gt;
*Don&#039;t show LABELS, and BUTTONS in STATUS command when GUI is off.&lt;br /&gt;
*Removed an error trying to close an already closed window. &lt;br /&gt;
&lt;br /&gt;
===Version 431d===&lt;br /&gt;
Removed DUPLICATE FLOWSTACK code.&amp;lt;br&amp;gt;&lt;br /&gt;
Revised ENDRUN processing of libraries .. set currentFileChain and CurrentScreenChain values during library PCB detachment. This fixed a problem detaching a NOFILES library.&amp;lt;br&amp;gt;&lt;br /&gt;
Lots of changes to run.cpp for flowstack processing and readability.&lt;br /&gt;
&lt;br /&gt;
Changes from prior editions:&lt;br /&gt;
*SQL and SYSERR fixes.&lt;br /&gt;
*Suppress error 867 on a radio button.&lt;br /&gt;
*Don&#039;t show LABELS, and BUTTONS in STATUS command when GUI is off.&lt;br /&gt;
*Removed an error trying to close an already closed window. &lt;br /&gt;
&lt;br /&gt;
Mismatched packets are ignored when:&lt;br /&gt;
*Ignore failure or keyboard return or we&#039;re terminating.&lt;br /&gt;
*Ignore failure is now on for cleanupNormalExits and closeWindowZero.&lt;br /&gt;
*When a flow stack error occurs, BR now returns error 9003.&lt;br /&gt;
*Current program name is stored on the client in a global when the status line is updated.&lt;br /&gt;
&lt;br /&gt;
Corrected processing mismatched packets for CALL_FUNCTION_NULL_ACTION.&amp;lt;br&amp;gt;&lt;br /&gt;
Added transfer of current line number to client.&lt;br /&gt;
&lt;br /&gt;
===Version 431e===&lt;br /&gt;
Revised remote.cpp ignoring of unmatched packets.&amp;lt;br&amp;gt;&lt;br /&gt;
Polished up the transfer of program name and line number to the client.&amp;lt;br&amp;gt;&lt;br /&gt;
Renamed clientOnly to ignoreFailureClientOnly&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Added error [[0738]] - SELECT should be a trailing attribute.&amp;lt;br&amp;gt;&lt;br /&gt;
This error occurs when SELECT is used as a leading attribute without the ^.&lt;br /&gt;
&lt;br /&gt;
===Version 431f===&lt;br /&gt;
Added path to log message referencing brCrashDumpUploader.&amp;lt;br&amp;gt;&lt;br /&gt;
Added support for DEBUG INTERNAL COREDUMP_SERVER.&amp;lt;br&amp;gt;&lt;br /&gt;
Now we pass currentUserLineNumber to client in all models.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Version 431fb===&lt;br /&gt;
If an invalid trailing attribute is allowed via OPTION 38 BR was occasionally dumping.&amp;lt;br&amp;gt;&lt;br /&gt;
Keepalive timeouts are prevented when sitting in a message box.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Version 431fc===&lt;br /&gt;
Created and applied MINOR_IO_ERROR (valued at 3). This relates to log levels.&lt;br /&gt;
&lt;br /&gt;
===Version 431fe===&lt;br /&gt;
Ignore mismatched packets on menu display.&amp;lt;br&amp;gt;&lt;br /&gt;
Suppress timeout during MSGBOX call.&amp;lt;br&amp;gt;&lt;br /&gt;
Fix 2D control header font colors.&amp;lt;br&amp;gt;&lt;br /&gt;
Removed V42 references.&amp;lt;br&amp;gt;&lt;br /&gt;
Fixed a problem re loading library modules RELEASE.&amp;lt;br&amp;gt; &lt;br /&gt;
Corrected logging before DLL loaded.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Version 431ff===&lt;br /&gt;
Revised PIC processing.&lt;br /&gt;
&lt;br /&gt;
===Version 431fg===&lt;br /&gt;
Revised PIC, and DATE processing to test formatted field capacity when inserting characters. (FMT runs only in overtype mode so it isn&#039;t affected.)&amp;lt;br&amp;gt;&lt;br /&gt;
Statusline ROWCOL now defaults to off.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Version 4.31g===&lt;br /&gt;
Upgrade to VS 2010.&amp;lt;br&amp;gt;&lt;br /&gt;
Fixed problem with license verification only to first decimal point of version number.&amp;lt;br&amp;gt;&lt;br /&gt;
Change made to prevent looping during shutdown.&amp;lt;br&amp;gt;&lt;br /&gt;
Client changed to let the server determine whether or not to terminate.&amp;lt;br&amp;gt;&lt;br /&gt;
Graceful client shutdown. See build notes for details.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Version 431ga===&lt;br /&gt;
Removed UPGRADE code flag from source.&amp;lt;br&amp;gt;&lt;br /&gt;
Fixed date problem that was created by recent FMT and PIC revisions.&amp;lt;br&amp;gt;&lt;br /&gt;
KREC is updated during printing only when the PUSH level is zero.&amp;lt;br&amp;gt;&lt;br /&gt;
For HTTP client, the log data showing CURL information was extended.&amp;lt;br&amp;gt;&lt;br /&gt;
The HTTP client now does a GET if no printing occurs prior to a LINPUT.&amp;lt;br&amp;gt;&lt;br /&gt;
A display parameter was added to the fldedit function. This function is used &lt;br /&gt;
by FMT, PIC DATE and other field types to see if typing is done in excess of field capacity.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Version 4.31gc===&lt;br /&gt;
More detail is provided when a database connection attempt is unsuccessful.&amp;lt;br&amp;gt;&lt;br /&gt;
Corrected failures pertaining to deleting characters in non-currency PIC masks, especially with backspace. &amp;lt;br&amp;gt;&lt;br /&gt;
ENV$ and STATUS ENV search strings are now enhanced. See the wiki for details.&lt;br /&gt;
Internal documentation updated.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Version 4.31h===&lt;br /&gt;
Removed references to abort. Used CANCEL instead.&amp;lt;br&amp;gt;&lt;br /&gt;
Error 370 was dropping the program file during a REPLACE where OPTION 60 was on and the program contained 4.2+ statements. This is fixed.&amp;lt;br&amp;gt;&lt;br /&gt;
The XLATE system function was extended to support translation to and from UTF-8. &amp;lt;br&amp;gt;&lt;br /&gt;
Added error 438 &amp;quot;Input String not valid UTF-8 format.&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
Removed system functions UPSI, LINEBUFFER, XPOS, CFIELDS$, and CHYRON$.&amp;lt;br&amp;gt;&lt;br /&gt;
Days(date(&amp;quot;H:M:S&amp;quot;),&amp;quot;H:M:S&amp;quot;) was producing a date with the first day of the current month. This was changed to the current day.&amp;lt;br&amp;gt;&lt;br /&gt;
RINPUT was positioning the cursor according to the previous Input. This was fixed.&amp;lt;br&amp;gt;&lt;br /&gt;
The Web Server support now does not tamper with binary data. It was converting to UTF-8.&amp;lt;br&amp;gt;&lt;br /&gt;
An internal pointer was adjusted to prevent crashes when the stack overflows.&amp;lt;br&amp;gt;&lt;br /&gt;
Default stack sizes were revised.&lt;br /&gt;
 work_size = 500000,    /* work stack size */&lt;br /&gt;
 flow_size = 100,       /* flow stack size */&lt;br /&gt;
 rpn_size = 1000,       /* rpn stack size */&lt;br /&gt;
 for_size = 100;        /* for-next stack */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Release 4.3]]&lt;br /&gt;
[[Category:Release Notes]]&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=4340&amp;diff=10832</id>
		<title>4340</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=4340&amp;diff=10832"/>
		<updated>2017-01-26T14:48:30Z</updated>

		<summary type="html">&lt;p&gt;GomezL: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Error&lt;br /&gt;
|4340&lt;br /&gt;
|([[4.2]]+) An HTTP error has occurred / ([[4.16]]-) Novell error 140&lt;br /&gt;
|In BR! version [[4.20]], This error code was re-introduced to be used in conjunction with the [[SysErr]] and [[SysErr$]]. It indicates that an error occurred in the underlying operating system. Reference SysErr$ for a description of the actual error. &lt;br /&gt;
&lt;br /&gt;
As of BR! version 4.16 This Novell error no longer exists.  &lt;br /&gt;
&lt;br /&gt;
|Use the SysErr &amp;amp; Syserr$ to troubleshoot the errors.   The HTTP interface in Business Rules uses the CURL library, and these errors should be documented in the Curl Site.&lt;br /&gt;
}}&lt;br /&gt;
[[Category:Error Codes]]&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=DATABASE&amp;diff=10826</id>
		<title>DATABASE</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=DATABASE&amp;diff=10826"/>
		<updated>2017-01-23T20:20:23Z</updated>

		<summary type="html">&lt;p&gt;GomezL: /* ODBC-MANAGER */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In version 4.3 and higher [[CONFIG]] DATABASE may use one of 3 methods for connecting to SQL Sources:&lt;br /&gt;
*DSN&lt;br /&gt;
*CONNECTSTRING&lt;br /&gt;
*ODBC-MANAGER&lt;br /&gt;
&lt;br /&gt;
===DSN===&lt;br /&gt;
Syntax:&lt;br /&gt;
 CONFIG DATABASE &amp;lt;db-ref&amp;gt;  DSN=&amp;lt;dsn-ref&amp;gt;  [, USER= &amp;lt;department&amp;gt; | LOGIN_NAME | ? ] [, {PASSWORD= &amp;lt;dept-password&amp;gt; | BR_PASSWORD | ? } | PASSWORD=&amp;lt;encrypted-password&amp;gt; ]&lt;br /&gt;
The ? indicates prompt&lt;br /&gt;
&lt;br /&gt;
Example: &lt;br /&gt;
 EXECUTE &#039;CONFIG DATABASE CLS_Data DSN=&amp;quot;MyData&amp;quot;&#039;&lt;br /&gt;
&lt;br /&gt;
===CONNECTSTRING (DSN Less)===&lt;br /&gt;
Syntax:&lt;br /&gt;
 CONFIG DATABASE &amp;lt;db-ref&amp;gt;  CONNECTSTRING=&amp;quot;&amp;lt;Driver&amp;gt;={Microsoft Access Driver (*.mdb)} DBQ=C:\inetpub\wwwroot\BegASP\Chapter.14\Contact.mdb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Sample Connection Strings:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Using a SQL Server /w SQL Login:&lt;br /&gt;
 CONFIG database db-ref connectstring=&amp;quot;DRIVER=SQL Server;SERVER=server;Initial Catalog=database;UID=username;PWD=password&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;db-ref&amp;quot; is the database reference.&lt;br /&gt;
&amp;quot;server&amp;quot; is the SQL Server [FQDN] or IP Address&lt;br /&gt;
&amp;quot;database&amp;quot; is the [SQL Server Database] &lt;br /&gt;
&amp;quot;username&amp;quot; is the [SQL Server User Name]&lt;br /&gt;
&amp;quot;password&amp;quot; is the [SQL Server Password]&lt;br /&gt;
&lt;br /&gt;
Using a SQL Server /w Windows Authentication:&lt;br /&gt;
 CONFIG database db-ref connectstring=&amp;quot;DRIVER=SQL Server;Initial Catalog=database;Persist Security Info=True;MultipleBC_TableResultSets=True; Database=database;SERVER=server;Login Name=username;Password=BR_PASSWORD&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;db-ref&amp;quot; is the database reference.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;server&amp;quot; is the SQL Server [FQDN] or IP Address&lt;br /&gt;
&lt;br /&gt;
&amp;quot;database&amp;quot; is the [SQL Server Database] &lt;br /&gt;
&lt;br /&gt;
&amp;quot;username&amp;quot; is the [SQL Server User Name]&lt;br /&gt;
&lt;br /&gt;
BR_PASSWORD will use the users Active Directory password to connect to the SQL Server.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;SQL Server&amp;quot; is one of several choices for SQL Server, another choice would be SQL Server Native Client 11.0&lt;br /&gt;
&lt;br /&gt;
===ODBC-MANAGER===&lt;br /&gt;
Syntax:&lt;br /&gt;
 CONFIG DATABASE &amp;lt;db-ref&amp;gt; ODBC-MANAGER&lt;br /&gt;
&lt;br /&gt;
Using ODBC Manager as the parameter will allow the end user to select the desired data source.&lt;br /&gt;
&lt;br /&gt;
The following is a sample program that will use the ODBC-MANAGER to identify the proper connection string.&lt;br /&gt;
* Note: This will not work in Client Server&lt;br /&gt;
&lt;br /&gt;
 00010   PRINT Newpage&lt;br /&gt;
 00011   IF Env$(&amp;quot;br_model&amp;quot;)=&amp;quot;CLIENT_SERVER&amp;quot; THEN PRINT &amp;quot;Warning, you cannot connect to ODBC-MANAGER in Client Server Mode&amp;quot;&lt;br /&gt;
 00020   EXECUTE &amp;quot;Config Database Test_DB ODBC-MANAGER&amp;quot; ERROR CONNECT_ERROR&lt;br /&gt;
 00030   PRINT &amp;quot;Connection String is:&amp;quot; !:&lt;br /&gt;
        PRINT Env$(&amp;quot;STATUS.DATABASE.[TEST_DB].CONNECTSTRING&amp;quot;)&lt;br /&gt;
 00099   STOP &lt;br /&gt;
 00100 CONNECT_ERROR: ! &lt;br /&gt;
 00110   PRINT &amp;quot;Error Connecting - Err:&amp;quot;;Err;&amp;quot; Line:&amp;quot;;Line;&amp;quot; Syserr:&amp;quot;;Syserr$&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:All Parameters]]&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=DATABASE&amp;diff=10825</id>
		<title>DATABASE</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=DATABASE&amp;diff=10825"/>
		<updated>2017-01-23T20:19:25Z</updated>

		<summary type="html">&lt;p&gt;GomezL: /* ODBC-MANAGER */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In version 4.3 and higher [[CONFIG]] DATABASE may use one of 3 methods for connecting to SQL Sources:&lt;br /&gt;
*DSN&lt;br /&gt;
*CONNECTSTRING&lt;br /&gt;
*ODBC-MANAGER&lt;br /&gt;
&lt;br /&gt;
===DSN===&lt;br /&gt;
Syntax:&lt;br /&gt;
 CONFIG DATABASE &amp;lt;db-ref&amp;gt;  DSN=&amp;lt;dsn-ref&amp;gt;  [, USER= &amp;lt;department&amp;gt; | LOGIN_NAME | ? ] [, {PASSWORD= &amp;lt;dept-password&amp;gt; | BR_PASSWORD | ? } | PASSWORD=&amp;lt;encrypted-password&amp;gt; ]&lt;br /&gt;
The ? indicates prompt&lt;br /&gt;
&lt;br /&gt;
Example: &lt;br /&gt;
 EXECUTE &#039;CONFIG DATABASE CLS_Data DSN=&amp;quot;MyData&amp;quot;&#039;&lt;br /&gt;
&lt;br /&gt;
===CONNECTSTRING (DSN Less)===&lt;br /&gt;
Syntax:&lt;br /&gt;
 CONFIG DATABASE &amp;lt;db-ref&amp;gt;  CONNECTSTRING=&amp;quot;&amp;lt;Driver&amp;gt;={Microsoft Access Driver (*.mdb)} DBQ=C:\inetpub\wwwroot\BegASP\Chapter.14\Contact.mdb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Sample Connection Strings:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Using a SQL Server /w SQL Login:&lt;br /&gt;
 CONFIG database db-ref connectstring=&amp;quot;DRIVER=SQL Server;SERVER=server;Initial Catalog=database;UID=username;PWD=password&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;db-ref&amp;quot; is the database reference.&lt;br /&gt;
&amp;quot;server&amp;quot; is the SQL Server [FQDN] or IP Address&lt;br /&gt;
&amp;quot;database&amp;quot; is the [SQL Server Database] &lt;br /&gt;
&amp;quot;username&amp;quot; is the [SQL Server User Name]&lt;br /&gt;
&amp;quot;password&amp;quot; is the [SQL Server Password]&lt;br /&gt;
&lt;br /&gt;
Using a SQL Server /w Windows Authentication:&lt;br /&gt;
 CONFIG database db-ref connectstring=&amp;quot;DRIVER=SQL Server;Initial Catalog=database;Persist Security Info=True;MultipleBC_TableResultSets=True; Database=database;SERVER=server;Login Name=username;Password=BR_PASSWORD&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;db-ref&amp;quot; is the database reference.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;server&amp;quot; is the SQL Server [FQDN] or IP Address&lt;br /&gt;
&lt;br /&gt;
&amp;quot;database&amp;quot; is the [SQL Server Database] &lt;br /&gt;
&lt;br /&gt;
&amp;quot;username&amp;quot; is the [SQL Server User Name]&lt;br /&gt;
&lt;br /&gt;
BR_PASSWORD will use the users Active Directory password to connect to the SQL Server.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;SQL Server&amp;quot; is one of several choices for SQL Server, another choice would be SQL Server Native Client 11.0&lt;br /&gt;
&lt;br /&gt;
===ODBC-MANAGER===&lt;br /&gt;
Syntax:&lt;br /&gt;
 CONFIG DATABASE &amp;lt;db-ref&amp;gt; ODBC-MANAGER&lt;br /&gt;
&lt;br /&gt;
Using ODBC Manager as the parameter will allow the end user to select the desired data source.&lt;br /&gt;
&lt;br /&gt;
The following is a sample program that will use the ODBC-MANAGER to identify the proper connection string.&lt;br /&gt;
* Note: This will not work in Client Server *&lt;br /&gt;
&lt;br /&gt;
00010   PRINT Newpage&lt;br /&gt;
00011   IF Env$(&amp;quot;br_model&amp;quot;)=&amp;quot;CLIENT_SERVER&amp;quot; THEN PRINT &amp;quot;Warning, you cannot connect to ODBC-MANAGER in Client Server Mode&amp;quot;&lt;br /&gt;
00020   EXECUTE &amp;quot;config database Test_DB ODBC-MANAGER&amp;quot; ERROR CONNECT_ERROR&lt;br /&gt;
00030   PRINT &amp;quot;Connection String is:&amp;quot; !:&lt;br /&gt;
        PRINT Env$(&amp;quot;STATUS.DATABASE.[TEST_DB].CONNECTSTRING&amp;quot;)&lt;br /&gt;
00099   STOP &lt;br /&gt;
00100 CONNECT_ERROR: ! &lt;br /&gt;
00110   PRINT &amp;quot;Error Connecting - Err:&amp;quot;;Err;&amp;quot; Line:&amp;quot;;Line;&amp;quot; Syserr:&amp;quot;;Syserr$&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:All Parameters]]&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Encryption&amp;diff=10824</id>
		<title>Encryption</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Encryption&amp;diff=10824"/>
		<updated>2017-01-19T01:33:42Z</updated>

		<summary type="html">&lt;p&gt;GomezL: /* Asymmetric Encryption */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;(As of 4.30)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Encryption&#039;&#039;&#039; encompasses a number of different operations.  These operations can be used independently or in combination to meet different needs.  We use industry standard encryption available through OpenSSL.  Three technologies are widely used for encrypting data. BR supports the first two listed below through its [[ENCRYPT]] and [[DECRYPT]] [[internal functions]]. &lt;br /&gt;
&lt;br /&gt;
==Overview of Two Encryption Methods==&lt;br /&gt;
&lt;br /&gt;
1. &#039;&#039;&#039;Symmetric key ciphers&#039;&#039;&#039; – where the same key is used to encrypt and decrypt data. You can specify a key to encrypt some data and later use the same key to decrypt the data.&lt;br /&gt;
&lt;br /&gt;
2. &#039;&#039;&#039;Hashing routines&#039;&#039;&#039; – one way routines that take data and convert it to a hash value.  Sometimes these are thought of as checksums such as MD5 sum.  Hash values are always the same length regardless of how big the hashed data is.  A 10 gb file will have a hash result that is the same length as a 200 byte file. Hashing routines have a number of specific uses, including:&lt;br /&gt;
*Verify that data has not changed.&lt;br /&gt;
*Verifying that two files are the same.&lt;br /&gt;
*Validating passwords – this is based on the concept that if two values have the same hash value the values are equal.  Using this technique improves security because it allows a server to store passwords in an unrecoverable format.  Even the server software is unable to regenerate the original password.  It is only capable of checking if the hash of a password matches the stored password hash.&lt;br /&gt;
&lt;br /&gt;
==Symmetric Key Ciphers==&lt;br /&gt;
There are two encryption functions in the BR language, [[ENCRYPT$]] and [[DECRYPT$]].&lt;br /&gt;
&lt;br /&gt;
 ENCRYPT$(Data$ [,Key$ [,Encryption-type$ [,Initialization-vector$]]])&lt;br /&gt;
 DECRYPT$(Data$ [,Key$ [,Encryption-type$ [,Initialization-vector$]]])&lt;br /&gt;
&lt;br /&gt;
Data$ - The data to be encrypted&lt;br /&gt;
&lt;br /&gt;
Key$ - The secret key to be used for encryption.  If not specified this value will come from an OPTION 66 statement.&lt;br /&gt;
&lt;br /&gt;
Encryption-type$ - The type of encryption to be done.  If not specified, a common high strength encryption type will be employed.  This is described in more detail below, but is generally only useful for interfacing with other typically non-BR programs.&lt;br /&gt;
&lt;br /&gt;
Initialization-vector$ - This is an arcane part of encryption standards. It exists to prevent attackers from being able to tell whether the unencrypted data has changed. This is described in more detail below, but is general only needed when interfacing with other non-BR programs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interfacing With Other Programs (encryption type and initialization vector)==&lt;br /&gt;
There are a number of different types of encryption that BR supports through OpenSSL:  AES, BLOWFISH, DES, triple DES, RC4 and RC2.  Most symmetric key ciphers are block ciphers meaning that they encrypt one block at a time. This means if you have a bit message, it is broken up into multiple blocks and each block is encrypted. The block size can be set as (128, 192, 256) bits. Some encryption types don&#039;t support all of these values so STATUS ENCRYPTION should be checked to see what encryption types are available in BR. Besides block size, there are also various schemes for blocking data. One might expect that using 256 bit blocking would simply take every 32 bytes and call it a block.  This is not done though because there is a possibility that this would cause patterns in the encrypted data. To prevent this, there are various schemes known as codebooks which change the way data is blocked. Wikipedia explains this in more detail. If the encryption type is not specified AES:256:CBC:128 will be used. To be compatible with other programs the entire encryption type must be specified (cipher: key length: codebook: initialization vector length).&lt;br /&gt;
&lt;br /&gt;
Initialization-vector – this is used to cause the same data encrypted with the same key to have a different encrypted result. This is significant because otherwise an attacker looking at data seeing the same encrypted result twice would know that the key and the unencrypted data have not changed. Regardless of whether or not you are concerned about this potential security issue, the standard encryption methods require this value so interfacing with other programs may require you to use it. It is a common practice to use a random number for this value and store the value at the beginning of (ahead of) the encrypted result. This is what BR does if this parameter is omitted.&lt;br /&gt;
&lt;br /&gt;
As an example:&lt;br /&gt;
 ENCRYPT$(“test”,“key”) &lt;br /&gt;
Produces a string containing “random number initialization vector”&amp;amp;”encrypted result”.&lt;br /&gt;
&lt;br /&gt;
If the initialization vector is explicitly specified as in:&lt;br /&gt;
ENCRYPT$(“test”,“key”,“AES:256:CBC:128”,“RANDOM”) &lt;br /&gt;
the result would be simply “encrypted result”.&lt;br /&gt;
&lt;br /&gt;
DECRYPT$ has the same arguments as ENCRYPT$ with the exception of the first parameter which is the encrypted data. DECRYPT$ expects to be used with the same key$, encryption-type$, and initialization-vector$ as was used to encrypt the data.  As with ENCRYPT$, if key$ is not specified, the value from the OPTION statement will be used. If encryption-type$ is not specified, “AES:256:CBC:128” will be used. If the initialization vector is not specified, it will be assumed that the encrypted data starts with an initialization vector.&lt;br /&gt;
&lt;br /&gt;
==Hashing Routines==&lt;br /&gt;
Three common forms of hashing are allowed in BR. They are MD5, SHA, and SHA-1. These are also provided through the ENCRYPT$ function specifying a null key$ value:&lt;br /&gt;
&lt;br /&gt;
 ENCRYPT$(data$, “”, “MD5”) ENCRYPT$(data$, “”, “SHA”) ENCRYPT$(data$, “”, “SHA-1”)&lt;br /&gt;
&lt;br /&gt;
Hashing is also referred to as Message Digests or digests. This is what the MD in MD5 means. There is no way to restore data that has been hashed. Hashing is a one way function so DECRYPT$ will yield an error.&lt;br /&gt;
&lt;br /&gt;
==Asymmetric Encryption==&lt;br /&gt;
Asymmetric key encryption is also known as public/private key encryption.&lt;br /&gt;
&lt;br /&gt;
Public/private keys are created as a pair by a key generator.  They are a pair, and it is not possible to have two public keys for the same private key or vice versa. With regard to public/private key pairs, what one key encrypts the other key can decrypt, and neither key can decrypt what it has encrypted.  When a private key is used to encrypt data, the result is called a signature because everyone who has the public key can decrypt it.&lt;br /&gt;
&lt;br /&gt;
This technique is used for:&lt;br /&gt;
&lt;br /&gt;
Signing (using certificates) – A private key can be used to sign data. The result of such signing can be tested/validated with the corresponding public key.&lt;br /&gt;
&lt;br /&gt;
Data encryption – A public key can be used to encrypt data. This data can then only be decrypted by the corresponding private key.&lt;br /&gt;
&lt;br /&gt;
Hashes and signing are different but used together.  Rather than signing a large block of data which would create a large signature, only the hash is signed to create much smaller fixed length signature data.  When verifying a large block of signed data, the data is used to create a hash value and the hash value is compared to a decrypted signature.&lt;br /&gt;
&lt;br /&gt;
Asymmetric encryption is not accessible through the BR ENCRYPT$, DECRYPT$ functions. However, it is used by our SSL client server connections and HTTPS. Certificates are most commonly used by SSL and HTTPS and are less useful for other application processes. &lt;br /&gt;
&lt;br /&gt;
In the Client Server model the client knows the server’s public key and the server uses its private key to encrypt and decrypt.  BRclient.exe connects to BRListener.exe by opening an SSL socket on the server using DHE_RSA-AES256-SHA Encryption. Handshaking is performed using a private key stored on the server within BRListener. Once authenticated, the socket is then passed to BRServer.exe for actual data processing.&lt;br /&gt;
&lt;br /&gt;
Encryption is invoked by Business Rules HTTP support as follows:&lt;br /&gt;
&lt;br /&gt;
 CONFIG HTTPS PORT port-number   [ LOG file-pathname ]&lt;br /&gt;
 CONFIG OPTION  66   private-key-file-encryption-password&lt;br /&gt;
 OPEN #400: “HTTP=SERVER”, DISPLAY, OUTIN&lt;br /&gt;
&lt;br /&gt;
The BRSERVER executable directory must contain two files:&lt;br /&gt;
&lt;br /&gt;
 https-private.pem&lt;br /&gt;
 https-cert.pem&lt;br /&gt;
&lt;br /&gt;
These files are made by the following commands under Linux, MAC and cygwin for Windows: openssl req -new -x509 -out httpserver.pem -days 10000&lt;br /&gt;
&lt;br /&gt;
(this will prompt for the OPTION 66 password)&lt;br /&gt;
&lt;br /&gt;
 mv privkey.pem   https-private.pem&lt;br /&gt;
 mv httpserver.pem   https-cert.pem&lt;br /&gt;
&lt;br /&gt;
This port specific service can then be accessed with browsers. When the specified port is accessed through a browser, BR establishes an HTTPS connection rather than an HTTP connection.&lt;br /&gt;
&lt;br /&gt;
==Signing and Certificate Processing Industry Standards==&lt;br /&gt;
The purpose of certificates is to verify the authenticity of unencrypted data. &lt;br /&gt;
&lt;br /&gt;
Certain companies are authorized by the government to act as a Certificate Authority (CA). These companies (e.g. Verisign) issue electronic certificates which can be used to issue second level certificates. Certificates can have expiration dates and the line of authority extends from a CA to any number of levels (but a chain is only as strong as its weakest link). Certificates contain a list of signatures (described below) that trace back to a CA as follows: &lt;br /&gt;
&lt;br /&gt;
When a company needs to obtain a certificate from a CA, it prepares its own certificate and sends it to the CA for signature. Creating a certificate requires the pre-production of a private and public key pair. The certificate text properly identifies the signing authority, the owner of the certificate, and the owner’s public key. The signing authority externally verifies the identity of the owner before signing it.  The CA provides the signature and the CA’s own public key for validating it. &lt;br /&gt;
&lt;br /&gt;
Browsers know the CA identities and their public keys. A browser can verify a CA signed cert by hashing it, decrypting the signature with the known public key and matching the decrypted signature against the hash total. &lt;br /&gt;
 &lt;br /&gt;
Any company that is issued a (self-prepared authority signed) certificate by a CA can sign second level certificates issued to third parties. A second level cert contains the parent (CA issued) certificate, and includes the public keys of the issuer and the recipient. The signature is essentially the encrypted hash total of ‘itself plus all of its ancestors’. Additional levels each contain the chain of certificates leading from a CA issued cert to itself. By including public keys along with the identities of the owners, certificates become tools for validating the signatures of their owners. When signed data (with an encrypted hash total) is sent to clients the signatures insure that the data has not been altered along the way. &lt;br /&gt;
&lt;br /&gt;
Ostensibly, a certificate cannot be counterfeited because it requires the signature of its parent which can only be produced with its parent’s private key.  By providing both public keys ( signer and recipient ) in all certs along with signatures, a non-forgeable or alterable chain is established. &lt;br /&gt;
&lt;br /&gt;
====Example:====&lt;br /&gt;
CA public key – known to browser&lt;br /&gt;
certificate 1 (signed by CA – contains owner’s public key)&lt;br /&gt;
certificate 2 (signed by second level - includes certificate 1 - contains owner’s public key)&lt;br /&gt;
final certificate (signed by third level - includes certificate 2 - contains owner’s public key)&lt;br /&gt;
 &lt;br /&gt;
A browser would find the CA information in the certificate and check to see if it is in the browser’s internal list. If not, it fails. Then it verifies that certificate 1 (which ends up being part of the final certificate) has been signed by the CA. After that it checks certificate 2 and verifies that it has been signed by the owner of certificate 1. Finally it checks the final certificate and verifies that it has been signed by the owner of certificate 2.&lt;br /&gt;
&lt;br /&gt;
To assure the line authority of any certificate, the public keys are associated with signers, not with documents. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Definitions]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>GomezL</name></author>
	</entry>
</feed>