How to retrieve SObject using Schema.SObjectType class?

734    Asked by Aalapprabhakaran in Salesforce , Asked on May 4, 2023

I am trying to create a dynamic class to retrieve a record for update. I struggle with the following part of the code:

targetSObject = new sor.getSObjectType()(ID = sObjectID);
For example, if this were an account record, I would want the result to be:
targetSobject = new Account(ID = '0016A000003tqQfQAI')
Essentially what I am asking is how do I recreate the above example using the Schema class.
Also, I am curious what the community thinks about retrieving records using the new Sobject(ID = '...')
public with sharing class UpdateAccountGoalsFromOpp {
    Map> sorToUpdate = new Map>();
    public SObject getSObject(ID sObjectID)
    {
        Schema.DescribeSObjectResult sor = sObjectID.getSobjectType().getDescribe();
        String recObject = String.valueOf(sor.getName());
        if(!sorToUpdate.containsKey(recObject))
        {
            sorToUpdate.put(recObject, new Map());
        }
        SObject targetSObject = sorToUpdate.get(recObject).get(sObjectID);
        if(targetSObject == null)
        {
            targetSObject = new sor.getSObjectType()(ID = sObjectID);
            sorToUpdate.get(recObject).put(sObjectID, targetSObject);
        }
        return targetSObject;
    }
}
After doing research:
targetSObject = Schema.getGlobalDescribe().get(recObject).newSObject(sObjectID);
^ I think the above code may be the equivalent to:
targetSobject = new Account(ID = '0016A000003tqQfQAI')
Answered by Buffy Heaton

To retrieve SObject using Schema.SObjectType class-


From the sObjectType object, use the newSobject method to create a new record in memory. It accepts a single optional parameter for the record Id:
targetSObject = new sor.getSObjectType().newSobject(sObjectID);
As an aside, if you already know the Id, you don't need the describe:
targetSObject = sObjectID.getSobjectType().newSobject(sObjectID);
Also, you can use an sObjectType token instead of a string to avoid a describe call entirely:
Map> sorToUpdate = new Map>();
...
sObjectType sot = sObjectID.getSobjectType();
if(!sorToUpdate.containsKey(sot)) {
  sorToUpdate.put(sot, new Map());
}




Your Answer

Answer (1)

In PostgreSQL, you can convert a timestamp (without time zone) to a timestamptz (timestamp with time zone) using the AT TIME ZONE syntax. The AT TIME ZONE construct is used to interpret a timestamp without time zone as a timestamp with time zone.

Here's how you can do it:

Basic Conversion

Assuming you have a timestamp column and you want to convert it to timestamptz by interpreting it in a specific time zone:

  SELECT timestamp_column AT TIME ZONE 'UTC' AS timestamptz_columnFROM your_table;

This example interprets the timestamp_column as being in UTC time zone.

Example Usage

Let's say you have the following table:

  CREATE TABLE example_table (    id SERIAL PRIMARY KEY,    timestamp_column TIMESTAMP);INSERT INTO example_table (timestamp_column)VALUES ('2024-07-10 12:00:00'),       ('2024-07-10 15:30:00');To convert the timestamp_column to timestamptz, interpreting it in UTC:
  SELECT timestamp_column,       timestamp_column AT TIME ZONE 'UTC' AS timestamptz_columnFROM example_table;

Adjusting to Your Local Time Zone

If you want to convert the timestamp to timestamptz in your local time zone, you need to specify your local time zone:

  SELECT timestamp_column,       timestamp_column AT TIME ZONE 'America/New_York' AS timestamptz_columnFROM example_table;Changing the Data Type of a Column

If you want to permanently change the data type of a column from timestamp to timestamptz, you can use the ALTER TABLE statement with the USING clause:

  ALTER TABLE example_tableALTER COLUMN timestamp_columnSET DATA TYPE TIMESTAMPTZUSING timestamp_column AT TIME ZONE 'UTC';

This will convert all existing timestamp values to timestamptz using the specified time zone.

Detailed Example

Here's a complete example, including table creation, insertion, conversion, and alteration of the column data type:

  -- Create tableCREATE TABLE example_table (    id SERIAL PRIMARY KEY,    timestamp_column TIMESTAMP);-- Insert sample dataINSERT INTO example_table (timestamp_column)VALUES ('2024-07-10 12:00:00'),       ('2024-07-10 15:30:00');-- Select with conversion to timestamptzSELECT timestamp_column,       timestamp_column AT TIME ZONE 'UTC' AS timestamptz_columnFROM example_table;-- Alter the column to permanently change its type to timestamptzALTER TABLE example_tableALTER COLUMN timestamp_columnSET DATA TYPE TIMESTAMPTZUSING timestamp_column AT TIME ZONE 'UTC';-- Verify the changeSELECT * FROM example_table;

This example demonstrates how to handle the conversion both temporarily (for queries) and permanently (for altering table structure). Adjust the time zone as needed to fit your requirements.

How To Retrieve SObject Using Schema.SObjectType Class?

In Salesforce, the Schema.SObjectType class is used to interact with metadata about objects dynamically. You can retrieve SObjects dynamically by using the Schema.SObjectType class, which is particularly useful when you need to work with objects without hardcoding their API names.

Here's how you can use Schema.SObjectType to retrieve an SObject:

Step-by-Step Guide

Get SObject Type: Use the Schema.getGlobalDescribe() method to get a map of all SObject types available in your Salesforce org.

Retrieve SObject Type: Use the map to retrieve the Schema.SObjectType instance for a specific object.

Query the SObject: Use the retrieved Schema.SObjectType to query the SObject.

Example

Suppose you want to retrieve a record from the Account object dynamically.

// Step 1: Get the global describe map

Map globalDescribeMap = Schema.getGlobalDescribe();


// Step 2: Retrieve the Schema.SObjectType for the Account object

Schema.SObjectType accountSObjectType = globalDescribeMap.get('Account');


// Step 3: Retrieve the DescribeSObjectResult

Schema.DescribeSObjectResult describeResult = accountSObjectType.getDescribe();

// Step 4: Get the API name of the SObject

String sObjectApiName = describeResult.getName(); // Should return 'Account'

// Step 5: Use the SObjectType to perform a SOQL query

  String soqlQuery = 'SELECT Id, Name FROM ' + sObjectApiName + ' LIMIT 1';List records = Database.query(soqlQuery);// Step 6: Process the resultif (records.size() > 0) {    SObject accountRecord = records[0];    System.debug('Account Name: ' + accountRecord.get('Name'));} else {    System.debug('No records found.');}

Explanation

Global Describe Map: Schema.getGlobalDescribe() returns a map of all SObject types in your org, where the key is the API name of the SObject.

Retrieve SObjectType: The map is used to get the Schema.SObjectType for the Account object.

Describe SObject: The getDescribe() method on the Schema.SObjectType instance returns metadata about the Account object.

Get API Name: The getName() method on the DescribeSObjectResult instance returns the API name of the object.

Dynamic SOQL Query: Constructs a SOQL query string using the API name and executes it with Database.query().

Process Result: Processes the result of the query and accesses the fields dynamically using the get() method on the SObject.

Handling Other SObjects

You can use the same pattern to work with other SObjects dynamically. Simply replace 'Account' with the desired SObject API name.

Error Handling

It's good practice to add error handling, especially when working with dynamic queries. You might want to add checks to ensure that the SObject type exists in the globalDescribeMap and handle QueryException for the SOQL query.

Full Example with Error Handling

      // Step 1: Get the global describe map    Map globalDescribeMap = Schema.getGlobalDescribe();    // Step 2: Retrieve the Schema.SObjectType for the Account object    Schema.SObjectType sObjectType = globalDescribeMap.get('Account');    if (sObjectType != null) {        // Step 3: Retrieve the DescribeSObjectResult        Schema.DescribeSObjectResult describeResult = sObjectType.getDescribe();        // Step 4: Get the API name of the SObject        String sObjectApiName = describeResult.getName(); // Should return 'Account'        // Step 5: Use the SObjectType to perform a SOQL query        String soqlQuery = 'SELECT Id, Name FROM ' + sObjectApiName + ' LIMIT 1';        List records = Database.query(soqlQuery);        // Step 6: Process the result        if (records.size() > 0) {            SObject accountRecord = records[0];            System.debug('Account Name: ' + accountRecord.get('Name'));        } else {            System.debug('No records found.');        }    } else {        System.debug('SObject type not found.');    }} catch (QueryException e) {
      System.debug('Query Exception: ' + e.getMessage());} catch (Exception e) {    System.debug('Exception: ' + e.getMessage());}

By following this pattern, you can dynamically retrieve and work with SObjects in Salesforce without hardcoding their names, making your Apex code more flexible and maintainable.

4 Months

Interviews

Parent Categories