Using wildcards for column names in dynamic soql in apex - salesforce

I have a scenario where my columns names can be of type genesis__prod__c/docgen__prod__c/lnd__prod__c,etc depending upon which package is using my solution package. Here genesis,docgen and are different product packages using my solution.
My solution needs to fetch any of these(genesis__prod__c/docgen__prod__c/lnd__prod__c) fields from there respective sObjects in there products.
I want to construct a generic query which will omit the namespace using a wildcard and only look for prod__c in specified sObject. With this, I don't have to hardcode any namespace in my query.
for eg., I don't want to form my query like this
String query = 'select Id,Name,docgen__CL_Product__c from '+ sObjectType + ' where id= \'' + appId + '\'';
List<sObject> runtimeDeterminedObject = Database.query(query+' LIMIT 1');
Here I have specifically mentioned docgen__CL_Product__c name to be fetched from a runtime resolved sObject name sObjectType w.r.t an appId
How can I form a query where I do not have to provide namespace docgen,genesis before prod__c. I do not want to write if-else for each product which can utilize my package.

Why don't you make the namespace a variable that gets appended to the query based on some condition? Not exactly what you're looking for, but I'm assuming there's some way to determine the environment and then based on that you can adjust the query dynamically:
String env = someCondition ? 'genesis__' : 'docgen__';
String query = 'select Id, Name, ' + env + 'CL_Product__c from '+ sObjectType + ' where id= \'' + appId + '\'';
List<sObject> runtimeDeterminedObject = Database.query(query+' LIMIT 1');

Related

Get the specified input parameter from stored procedure

I want to get all the related information from database. For example I have a summary column which contains data like "A01.1 | Foodland Inbound QIP Details and Pre Unloading" and I want to pass only "A01" in input parameter and get all the data related to "A01"
select * from TableName where summary_column like 'A01%';
Based on the code in your comment, the where clause will only find a summary that is the equal to A01.2 e.g:
TaskMaster.Summary =#summary
You want to use LIKE and a wild card:
WHERE TaskMaster.Summary LIKE '''' + #summary + '%' + ''''
The above will find everything that starts with A01.2, so if you want to find all with A01, pass #summary as A01

Can i create a sql table populated with Salesforce objects?

does Salesforce offer a way to obtain all Objects like Account, Contact etc and populate them in a SQL table with certain columns like
ObjectEntity, FieldName , FieldType ?
I'm pretty sure the only way to achieve this would be by using the Schema.sObjectType and Schema.sObjectField. Here is a link to the documentation for getting all sObjects. You will basically call the Schema.getGlobalDescribe() method which will return you a map of sObjectTypes with their sObject name as the key. Then you'll need to call getDesribe() on each sObjectType get the fields of the object from that Describe result. You'll again need to call getDescribe() on each sObjectField in order to have access to the columns you wanted (eg. FieldType). Here is the documentation on that You could save each DescribeFieldResult into a list that goes into a Map of > with the sObject name as the key, then you could do what you want with them... Put them in a table if you like. Keep in mind this is all going to be very expensive when it comes to CPU time. You may even run into some governor limits.
Here is a little example you can run using Execute Anonymous in the developer console where the sObject Name and all its field names and types are printed to the debug logs
Map<String, sObjectType> objects = Schema.getGlobalDescribe();
for(String objName : objects.keySet()){
system.debug('=======' + objName + '=========\n Fields: ');
sObjectType o = objects.get(objName);
DescribeSobjectResult oDRes = o.getDescribe();
Map<String, Schema.SObjectField> fields = dResult.fields.getMap();
for(Schema.SObjectField f : fields.values()){
DescribeFieldResult fDRes = f.getDescribe();
system.debug('name: ' + fDRes.getName() + ' | type: ' + fDRes.getType());
}
}
Hope this helps

How to ignore null or empty values while using find() in Spring MongoRepository

I have a search functionality where there are different parameters and user can choose one or multiple parameters and ignore other parameters.
I want to use findByFirstNameAndLastNameAndAddressAndCountry() for this so that if any parameter is null or empty it can be ignored and the And condition get applied to other parameters
This can be a duplicate issue. You can do it using #Query annotation and your custom Query.
Ref: How to skip #Param in #Query if is null or empty in Spring Data JPA
#Query("select foo from Foo foo where foo.bar = :bar and "
+ "(:goo is null or foo.goo = :goo)")
public List<Foo> findByBarAndOptionalGoo(
#Param("bar") Bar bar,
#Param("goo") Optional<Goo> goo);
Use 'Query' and 'Criteria' option provided by Spring for MongoDB.
Query query = new Query();
if(!obj.getFirstName.isEmpty()){
Criteria criteria1 = Criteria.where('first_name').is(obj.getFirstName);
query.add(criteria1);
}

SQL - WHERE statement with text added to value from table

I need to copy data from an old database to a newer one.
Both of these databases have a user setup table with the primary key of "USER ID".
The problem is, in the old database the users didn't have the domain in the name, but in the new one they have.
Example:
Primary Key old DB: USER1
Primary Key new DB: DOMAIN\USER1
This prevents a standard WHERE clause to update the correct user because it can't find it due to the domain being added.
My code:
'FROM [' + #src_DB + '].dbo.[' + #src_table + '] as src '
'WHERE [' + #dest_DB + '].dbo.[' + #dest_table + '].[User ID] = ' + #domain_name + 'src.[User ID]'
printing the result:
WHERE [Destination_DB].dbo.[Destination_Table].[User ID] = DOMAIN\src.[User ID]
The problem is it doesn't add the DOMAIN to the value but rather to the statement...
How can I add the Domain to the actual value of src.[User ID]?
I think there's a dot missing, and you should use QUOTENAME
'WHERE ' + QUOTENAME(destination_table) + '.[User ID] = ' + QUOTENAME(#domain) + '.' + QUOTENAME(source_table) + '.[User ID]'
Whenever you create a SQL statement dynamically it's a good idea to print it out, copy it into a new query window and check for syntax errors...
UPDATE You: Yes, both databases are in the same server
An object can be (fully) specified with
ServerName.DatabaseName.Schema.ObjectName
A table's column would add one more .ColumnName
When both objects live on the same server you can let the first part away.
Objects of the same database let this part away.
Objects of the default schema might be called with the ObjectName alone.
But if you state a DatabaseName you must also state a SchemaName!
Use QUOTENAME() to add the brackets and add just the dots via string concatenation (or use CONCAT()-function).
UPDATE 2 Did I get this wrong completely?
After you comment I think I understand it now: You want to compare the values of both [USER ID] columns, but the new is DOMAIN\MyUserId while the older was just MyUserId.
You have two approaches
Add the Domain\ as string to the value of [User ID]
Use SUBSTRING([User ID],CHARINDEX('\',[UserID])+1,1000) to cut the newer value down to the naked value of [User ID]
For the first something like this
'WHERE [' + #dest_DB + '].dbo.[' + #dest_table + '].[User ID] = ''' + #domain_name + ''' + src.[User ID]'
The second is quite clumsy with dynamically created SQL...

Salesforce SOQL describe table

Is there a way to fetch a list of all fields in a table in Salesforce? DESCRIBE myTable doesn't work, and SELECT * FROM myTable doesn't work.
From within Apex, you can get this by running the following Apex code snippet. If your table/object is named MyObject__c, then this will give you a Set of the API names of all fields on that object that you have access to (this is important --- even as a System Administrator, if certain fields on your table/object are not visible through Field Level Security to you, they will not show up here):
// Get a map of all fields available to you on the MyObject__c table/object
// keyed by the API name of each field
Map<String,Schema.SObjectField> myObjectFields
= MyObject__c.SObjectType.getDescribe().fields.getMap();
// Get a Set of the field names
Set<String> myObjectFieldAPINames = myObjectFields.keyset();
// Print out the names to the debug log
String allFields = 'ALL ACCESSIBLE FIELDS on MyObject__c:\n\n';
for (String s : myObjectFieldAPINames) {
allFields += s + '\n';
}
System.debug(allFields);
To finish this off, and achieve SELECT * FROM MYTABLE functionality, you would need to construct a dynamic SOQL query using these fields:
List<String> fieldsList = new List<String>(myObjectFieldAPINames);
String query = 'SELECT ';
// Add in all but the last field, comma-separated
for (Integer i = 0; i < fieldsList.size()-1; i++) {
query += fieldsList + ',';
}
// Add in the final field
query += fieldsList[fieldsList.size()-1];
// Complete the query
query += ' FROM MyCustomObject__c';
// Perform the query (perform the SELECT *)
List<SObject> results = Database.query(query);
the describeSObject API call returns all the metadata about a given object/table including its fields. Its available in the SOAP, REST & Apex APIs.
Try using Schema.FieldSet
Schema.DescribeSObjectResult d = Account.sObjectType.getDescribe();
Map<String, Schema.FieldSet> FsMap = d.fieldSets.getMap();
complete documentation
Have you tried DESC myTable?
For me it works fine, it's also in the underlying tips in italic. Look:

Resources