

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# ステップ 5: 台帳内のドキュメントを変更する
ステップ 5: ドキュメントを変更する

**重要**  
サポート終了通知: 既存のお客様は、07/31/2025 のサポート終了まで Amazon QLDB を使用できます。詳細については、[「Amazon QLDB 台帳を Amazon Aurora PostgreSQL に移行する](https://aws.amazon.com/blogs/database/migrate-an-amazon-qldb-ledger-to-amazon-aurora-postgresql/)」を参照してください。

操作するデータを用意できたところで、Amazon QLDB で `vehicle-registration` 台帳のドキュメントに変更を加えることができます。このステップでは、次のコード例により、データ操作言語 (DML) ステートメントを実行する方法を示します。これらのステートメントは、ある車両の主所有者を更新し、別の車両に第二所有者を追加します。

**ドキュメントに変更を加えるには**

1. 次のプログラム (`TransferVehicleOwnership.ts`) を使用して、台帳で VIN が `1N4AL11D75C109151` の車両の主所有者を更新します。

   ```
   /*
    * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
    * SPDX-License-Identifier: MIT-0
    *
    * Permission is hereby granted, free of charge, to any person obtaining a copy of this
    * software and associated documentation files (the "Software"), to deal in the Software
    * without restriction, including without limitation the rights to use, copy, modify,
    * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
    * permit persons to whom the Software is furnished to do so.
    *
    * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
    * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
    * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
    * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    */
   
   import { QldbDriver, Result, TransactionExecutor } from "amazon-qldb-driver-nodejs";
   import { dom } from "ion-js";
   
   import { getQldbDriver } from "./ConnectToLedger";
   import { PERSON, VEHICLE } from "./model/SampleData";
   import { PERSON_TABLE_NAME } from "./qldb/Constants";
   import { error, log } from "./qldb/LogUtil";
   import { getDocumentId } from "./qldb/Util";
   
   /**
    * Query a driver's information using the given ID.
    * @param txn The {@linkcode TransactionExecutor} for lambda execute.
    * @param documentId The unique ID of a document in the Person table.
    * @returns Promise which fulfills with an Ion value containing the person.
    */
   export async function findPersonFromDocumentId(txn: TransactionExecutor, documentId: string): Promise<dom.Value> {
       const query: string = "SELECT p.* FROM Person AS p BY pid WHERE pid = ?";
   
       let personId: dom.Value;
       await txn.execute(query, documentId).then((result: Result) => {
           const resultList: dom.Value[] = result.getResultList();
           if (resultList.length === 0) {
               throw new Error(`Unable to find person with ID: ${documentId}.`);
           }
           personId = resultList[0];
       });
       return personId;
   }
   
   /**
    * Find the primary owner for the given VIN.
    * @param txn The {@linkcode TransactionExecutor} for lambda execute.
    * @param vin The VIN to find primary owner for.
    * @returns Promise which fulfills with an Ion value containing the primary owner.
    */
   export async function findPrimaryOwnerForVehicle(txn: TransactionExecutor, vin: string): Promise<dom.Value> {
       log(`Finding primary owner for vehicle with VIN: ${vin}`);
       const query: string = "SELECT Owners.PrimaryOwner.PersonId FROM VehicleRegistration AS v WHERE v.VIN = ?";
   
       let documentId: string = undefined;
       await txn.execute(query, vin).then((result: Result) => {
           const resultList: dom.Value[] = result.getResultList();
           if (resultList.length === 0) {
               throw new Error(`Unable to retrieve document ID using ${vin}.`);
           }
           const PersonIdValue: dom.Value = resultList[0].get("PersonId");
           if (PersonIdValue === null) {
               throw new Error(`Expected field name PersonId not found.`);
           }
           documentId = PersonIdValue.stringValue();
       });
       return findPersonFromDocumentId(txn, documentId);
   }
   
   /**
    * Update the primary owner for a vehicle using the given VIN.
    * @param txn The {@linkcode TransactionExecutor} for lambda execute.
    * @param vin The VIN for the vehicle to operate on.
    * @param documentId New PersonId for the primary owner.
    * @returns Promise which fulfills with void.
    */
   async function updateVehicleRegistration(txn: TransactionExecutor, vin: string, documentId: string): Promise<void> {
       const statement: string = "UPDATE VehicleRegistration AS r SET r.Owners.PrimaryOwner.PersonId = ? WHERE r.VIN = ?";
   
       log(`Updating the primary owner for vehicle with VIN: ${vin}...`);
       await txn.execute(statement, documentId, vin).then((result: Result) => {
           const resultList: dom.Value[] = result.getResultList();
           if (resultList.length === 0) {
               throw new Error("Unable to transfer vehicle, could not find registration.");
           }
           log(`Successfully transferred vehicle with VIN ${vin} to new owner.`);
       });
   }
   
   /**
    * Validate the current owner of the given vehicle and transfer its ownership to a new owner in a single transaction.
    * @param txn The {@linkcode TransactionExecutor} for lambda execute.
    * @param vin The VIN of the vehicle to transfer ownership of.
    * @param currentOwner The GovId of the current owner of the vehicle.
    * @param newOwner The GovId of the new owner of the vehicle.
    */
   export async function validateAndUpdateRegistration(
       txn: TransactionExecutor,
       vin: string,
       currentOwner: string,
       newOwner: string
   ): Promise<void> {
       const primaryOwner: dom.Value = await findPrimaryOwnerForVehicle(txn, vin);
       const govIdValue: dom.Value = primaryOwner.get("GovId");
       if (govIdValue !== null && govIdValue.stringValue() !== currentOwner) {
           log("Incorrect primary owner identified for vehicle, unable to transfer.");
       }
       else {
           const documentId: string = await getDocumentId(txn, PERSON_TABLE_NAME, "GovId", newOwner);
           await updateVehicleRegistration(txn, vin, documentId);
           log("Successfully transferred vehicle ownership!");
       }
   }
   
   /**
    * Find primary owner for a particular vehicle's VIN.
    * Transfer to another primary owner for a particular vehicle's VIN.
    * @returns Promise which fulfills with void.
    */
   const main = async function(): Promise<void> {
       try {
           const qldbDriver: QldbDriver = getQldbDriver();
   
           const vin: string = VEHICLE[0].VIN;
           const previousOwnerGovId: string = PERSON[0].GovId;
           const newPrimaryOwnerGovId: string = PERSON[1].GovId;
   
           await qldbDriver.executeLambda(async (txn: TransactionExecutor) => {
               await validateAndUpdateRegistration(txn, vin, previousOwnerGovId,  newPrimaryOwnerGovId);
           });
       } catch (e) {
           error(`Unable to connect and run queries: ${e}`);
       }
   }
   
   if (require.main === module) {
       main();
   }
   ```

1. トランスパイルされたプログラムを実行するには、次のコマンドを入力します。

   ```
   node dist/TransferVehicleOwnership.js
   ```

1. 次のプログラム (`AddSecondaryOwner.ts`) を使用して、台帳で VIN が `KM8SRDHF6EU074761` の車両に第二所有者を追加します。

   ```
   /*
    * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
    * SPDX-License-Identifier: MIT-0
    *
    * Permission is hereby granted, free of charge, to any person obtaining a copy of this
    * software and associated documentation files (the "Software"), to deal in the Software
    * without restriction, including without limitation the rights to use, copy, modify,
    * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
    * permit persons to whom the Software is furnished to do so.
    *
    * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
    * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
    * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
    * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    */
   
   import { QldbDriver, Result, TransactionExecutor } from "amazon-qldb-driver-nodejs";
   import { dom } from "ion-js";
   
   import { getQldbDriver } from "./ConnectToLedger";
   import { PERSON, VEHICLE_REGISTRATION } from "./model/SampleData";
   import { PERSON_TABLE_NAME } from "./qldb/Constants";
   import { error, log } from "./qldb/LogUtil";
   import { getDocumentId } from "./qldb/Util";
   import { prettyPrintResultList } from "./ScanTable";
   
   /**
    * Add a secondary owner into 'VehicleRegistration' table for a particular VIN.
    * @param txn The {@linkcode TransactionExecutor} for lambda execute.
    * @param vin VIN of the vehicle to query.
    * @param secondaryOwnerId The secondary owner's person ID.
    * @returns Promise which fulfills with void.
    */
   export async function addSecondaryOwner(
       txn: TransactionExecutor, 
       vin: string, 
       secondaryOwnerId: string
   ): Promise<void> {
       log(`Inserting secondary owner for vehicle with VIN: ${vin}`);
       const query: string =
           `FROM VehicleRegistration AS v WHERE v.VIN = ? INSERT INTO v.Owners.SecondaryOwners VALUE ?`;
   
       const personToInsert = {PersonId: secondaryOwnerId};
       await txn.execute(query, vin, personToInsert).then(async (result: Result) => {
           const resultList: dom.Value[] = result.getResultList();
           log("VehicleRegistration Document IDs which had secondary owners added: ");
           prettyPrintResultList(resultList);
       });
   }
   
   /**
    * Query for a document ID with a government ID.
    * @param txn The {@linkcode TransactionExecutor} for lambda execute.
    * @param governmentId The government ID to query with.
    * @returns Promise which fulfills with the document ID as a string.
    */
   export async function getDocumentIdByGovId(txn: TransactionExecutor, governmentId: string): Promise<string> {
       const documentId: string = await getDocumentId(txn, PERSON_TABLE_NAME, "GovId", governmentId);
       return documentId;
   }
   
   /**
    * Check whether a driver has already been registered for the given VIN.
    * @param txn The {@linkcode TransactionExecutor} for lambda execute.
    * @param vin VIN of the vehicle to query.
    * @param secondaryOwnerId The secondary owner's person ID.
    * @returns Promise which fulfills with a boolean.
    */
   export async function isSecondaryOwnerForVehicle(
       txn: TransactionExecutor,
       vin: string,
       secondaryOwnerId: string
   ): Promise<boolean> {
       log(`Finding secondary owners for vehicle with VIN: ${vin}`);
       const query: string = "SELECT Owners.SecondaryOwners FROM VehicleRegistration AS v WHERE v.VIN = ?";
   
       let doesExist: boolean = false;
   
       await txn.execute(query, vin).then((result: Result) => {
           const resultList: dom.Value[] = result.getResultList();
   
           resultList.forEach((value: dom.Value) => {
               const secondaryOwnersList: dom.Value[] = value.get("SecondaryOwners").elements();
   
               secondaryOwnersList.forEach((secondaryOwner) => {
                   const personId: dom.Value = secondaryOwner.get("PersonId");
                   if (personId !== null &&  personId.stringValue() === secondaryOwnerId) {
                       doesExist = true;
                   }
               });
           });
       });
       return doesExist;
   }
   
   /**
    * Finds and adds secondary owners for a vehicle.
    * @returns Promise which fulfills with void.
    */
   const main = async function(): Promise<void> {
       try {
           const qldbDriver: QldbDriver = getQldbDriver();
           const vin: string = VEHICLE_REGISTRATION[1].VIN;
           const govId: string = PERSON[0].GovId;
   
           await qldbDriver.executeLambda(async (txn: TransactionExecutor) => {
               const documentId: string = await getDocumentIdByGovId(txn, govId);
   
               if (await isSecondaryOwnerForVehicle(txn, vin, documentId)) {
                   log(`Person with ID ${documentId} has already been added as a secondary owner of this vehicle.`);
               } else {
                   await addSecondaryOwner(txn, vin, documentId);
               }
           });
   
           log("Secondary owners successfully updated.");
       } catch (e) {
           error(`Unable to add secondary owner: ${e}`);
       } 
   }
   
   if (require.main === module) {
       main();
   }
   ```

1. トランスパイルされたプログラムを実行するには、次のコマンドを入力します。

   ```
   node dist/AddSecondaryOwner.js
   ```

これらの変更を `vehicle-registration` 台帳で確認するには、「[ステップ 6: ドキュメントのリビジョン履歴を表示する](getting-started.nodejs.step-6.md)」を参照してください。