Manipular datos
Para recuperar datos de la base de datos, puede usar las funciones de acceso a datos.
Puede usar las siguientes funciones de acceso a datos para obtener registros:
- Get
- Find, FindFirst, FindLast
- Next
- IsEmpty
Función Get
Sección titulada «Función Get»La función Get recupera un registro basado en la clave principal. Si la tabla tiene una clave principal de un campo, debe proporcionarle un parámetro a la función Get.
var customer: Record Customer;begin customer.Get('30000');
if customer.Get('10000') then Message('%1', customer) else Error('Not found');
end;Función Find
Sección titulada «Función Find»La función Find tiene dos funciones derivadas: FindFirst y FindLast. En algún código estándar, se siguen utilizando las funciones Find('-') y Find('+'). Estas funciones se utilizaron en versiones anteriores de Business Central.
La función Find('-') le solicita SELECT a SQL Server y recupera el primer registro de Business Central. Por tanto, este proceso genera un rendimiento deficiente. Es mejor utilizar las funciones FindFirst y FindLast.
var customer: Record Customer;begin customer.Find('-'); // SELECT * FROM Customer Message('%1', customer.Name);
customer.Find('+'); // SELECT * FROM Customer Order By No. Desc Message('%1', customer.Name);
customer.FindFirst(); // SELECT TOP 1 * FROM Customer Message('%1', customer.Name);
customer.FindLast(); // SELECT TOP 1 * FROM Customer Order By No. Desc Message('%1', customer.Name);Para recuperar todos los registros (o un conjunto filtrado de registros), puede usar la función FindSet.
customer.FindSet();// SELECT * FROM CustomerInstrucción Next
Sección titulada «Instrucción Next»La instrucción Next se utiliza para obtener el siguiente registro de un conjunto de registros. Por lo general, la instrucción Next se usaría en una instrucción repeat until
customer.FindSet();// SELECT * FROM Customerrepeat // process record Message(customer.Name);until customer.Next() = 0;Función IsEmpty
Sección titulada «Función IsEmpty»Si desea comprobar si existe un registro, pero no desea recuperarlo, la mejor opción es usar la función IsEmpty.
Función SetCurrentKey
Sección titulada «Función SetCurrentKey»Para ordenar registros, use la función SetCurrentKey, donde puede especificar los campos por los que desea ordenar.
var customer: Record Customer;begin customer.SetCurrentKey(City);
customer.FindFirst(); Message('%1', customer);Funciones SetRange
Sección titulada «Funciones SetRange»puede especificar un valor inicial y final para un campo específico. Sin embargo, no puede usar la función SetRange para buscar registros donde el valor del campo sea mayor o menor que un valor específico.
SetRange(Field, [FromValue], [ToValue])customer.SetRange("No.", '10000', '40000');customer.FindSet();repeat Message('%1', customer);until customer.Next() = 0;Funciones SetFilter
Sección titulada «Funciones SetFilter»La función SetFilter acepta un valor de cadena donde puede especificar las condiciones de filtrado; por ejemplo:
><< ><=>='*'..(intervalo)&(y)|(o) y más en esta condición de filtro
SetFilter(Field, String, [Value1], [Value2], …)customer.SetFilter("No.", '> 10000 & <> 20000');value1 := '10000';value2 := '20000';customer.SetFilter("No.", '>%1&<>%2', value1, value2);customer.SetRange("No.", '10000', '90000');customer.SetFilter(City, '@B*');customer.SetFilter("Country/Region Code", 'B*');customer.FindSet();repeat Message('%1', customer);until customer.Next() = 0;customer.SetFilter("No.", '10000|20000|30000');Agregar, modificar o eliminar datos con AL
Sección titulada «Agregar, modificar o eliminar datos con AL»Con frecuencia, se les pedirá a los desarrolladores que modifiquen los datos en la base de datos mediante el código AL.
Las siguientes instrucciones permiten la modificación de datos:
- Insert
- Modify y ModifyAll
- Delete y DeleteAll
Instrucción Insert
Sección titulada «Instrucción Insert»La instrucción Insert se utiliza para agregar nuevos registros a la base de datos. Antes de poder insertar datos, debe establecer los valores para cada campo que desea almacenar.
var customer: Record Customer;begin customer.Init(); customer."No." := '4711'; customer.Name := 'John Doe'; customer.Insert(true);Aunque el desencadenador OnInsert no se ejecuta de forma predeterminada, los eventos OnBeforeInsert u OnAfterInsert siempre se ejecutan.
Instrucciones Modify y ModifyAll
Sección titulada «Instrucciones Modify y ModifyAll»customer.Get('4711');customer.Name := 'Richard Roe';customer.Modify();Si desea actualizar varios registros simultáneamente, puede usar la función ModifyAll. La función ModifyAll acepta el parámetro RunTrigger como el tercer parámetro de la función.
customer.SetRange("Salesperson Code", 'PS');customer.ModifyAll("Salesperson Code", 'JR');Las funciones Modify y ModifyAll no le piden confirmación; la modificación se ejecuta sin previo aviso.
Sección titulada «Las funciones Modify y ModifyAll no le piden confirmación; la modificación se ejecuta sin previo aviso.»Instrucciones Delete y DeleteAll
Al igual que con la función Modify, necesita recuperar un registro de la base de datos antes de poder eliminar un registro. Las funciones Delete y DeleteAll aceptan el parámetro RunTrigger.
customer.Get('4711');customer.Delete(true);customer.SetRange("Salesperson Code", 'PS');customer.DeleteAll();Las funciones Delete y DeleteAll no le piden confirmación; la eliminación ocurre sin previo aviso.
Instrucciones CalcFields y SetAutoCalcfields
Sección titulada «Instrucciones CalcFields y SetAutoCalcfields»Instrucciones CalcFields y SetAutoCalcfields
customer.SetRange("Date Filter", 0D, Today());
// Using CALCFIELDSif customer.FindSet() then repeat customer.CalcFields(Balance, "Net Change"); // Do some additional processing until customer.Next() = 0;Si siempre quiere calcular determinados FlowFields (dentro del ámbito de la función), puede usar la función SetAutoCalcFields.
customer.SetAutoCalcFields(Balance, "Net Change");if customer.FindSet() then repeat // Do some additional processing until customer.Next() = 0;Instrucción CalcSums
Sección titulada «Instrucción CalcSums»La función CalcSums se usa para calcular un total para un campo específico, en función de los filtros del conjunto de datos.
salesInvoiceHeader.SetCurrentKey("Bill-to Customer No.");salesInvoiceHeader.SetRange("Bill-to Customer No.", '10000', '50000');salesInvoiceHeader.SetRange("Document Date", 0D, Today());salesInvoiceHeader.CalcSums(Amount);
Message('The total is %1', salesInvoiceHeader.Amount);Instrucción FieldError
Sección titulada «Instrucción FieldError»La función FieldError detiene la implementación del código, lo que causa un error en tiempo de ejecución y crea un mensaje de error para un campo específico. El campo muestra un borde rojo, lo que indica que se ha producido un error con el valor de este campo.
if item."Unit Price" < 10 then item.FieldError("Unit Price", 'must be greater than 10');Instrucción init
Sección titulada «Instrucción init»La mejor estrategia es comenzar usando el comando Init en el registro. Esta acción inicializa todos los campos en el registro.
customer.Init();customer.Name := 'John Doe';customer."E-Mail" := 'john.doe@contoso.com';customer.Insert(true);Instrucción TestField
Sección titulada «Instrucción TestField»Con la función TestField, puede comprobar si un campo tiene un valor o está en blanco. Si el campo está vacío, la función TestField genera un error en tiempo de ejecución.
customer.TestField("Salesperson Code");customer."Salesperson Code" := 'DK';customer.TestField("Salesperson Code", 'ZX');Instrucción validate
Sección titulada «Instrucción validate»Al asignar un valor a un campo, el desencadenador OnValidate de ese campo no se ejecuta. Si quiere ejecutar el desencadenador OnValidate, use la función Validate.
Customer."Phone No." := '1234567891234'customer.Validate("Phone No.");Nivel de Aislamiento (Investigar sobre este tema)
Sección titulada «Nivel de Aislamiento (Investigar sobre este tema)»local procedure CurrentBehavior()var cust: Record Customer; otherCust: Record Customer; curr: Record Currency;begin cust.FindFirst(); // READUNCOMMITTED
// Heighten isolation level for Customer table. cust.LockTable(); cust.FindLast(); // UPDLOCK
// Also impacts other instances of same table. otherCust.FindSet(); // UPDLOCK
// But does not impact other tables. curr.Find(); // READUNCOMMITTEDend;La siguiente lista describe los diferentes niveles de aislamiento del tipo de opción IsolationLevel que puede aplicar:
- Predeterminado
- Sigue el estado de la transacción. Equivale a no usar el aislamiento de lectura.
- ReadUncommitted
- Permite lecturas sucias, lo que significa que puede leer filas que han sido modificadas por otras transacciones, pero que aún no han sido confirmadas. No acepta bloqueos e ignora los bloqueos de otras transacciones.
- ReadCommitted
- Solo permite lecturas en datos confirmados; es decir, no puede leer datos que hayan sido modificados por otras transacciones, pero que aún no hayan sido confirmadas. Sin embargo, no garantiza que las filas leídas se mantengan uniformes durante toda la transacción.
- RepeatableRead
- Garantiza que todas las lecturas sean estables manteniendo los bloqueos compartidos durante toda la transacción. La transacción no puede leer datos que hayan sido modificados, pero que aún no hayan sido confirmados por otras transacciones, y ninguna otra transacción puede modificar datos que hayan sido leídos por la transacción actual hasta que esta finalice.
- UpdLock
- Lee para actualizar e impide que otros lean con la misma intención.