mirror of
https://github.com/forcedotcom/afv-library.git
synced 2026-07-30 03:09:50 +08:00
7.2 KiB
7.2 KiB
Salesforce CLI SOQL Commands
Quick Reference
| Task | Command |
|---|---|
| Run query | sf data query --query "SELECT..." |
| JSON output | sf data query --query "..." --json |
| CSV output | sf data query --query "..." --result-format csv |
| Bulk export | sf data export bulk --query "SELECT..." --target-org alias |
| Query plan | sf api request rest '/query/?explain=<SOQL>' --target-org alias |
Basic Queries
Run a Query
sf data query \
--query "SELECT Id, Name, Industry FROM Account LIMIT 10" \
--target-org my-sandbox
Query with Filters
sf data query \
--query "SELECT Id, Name FROM Account WHERE Industry = 'Technology'" \
--target-org my-sandbox
Query Relationships
# Child-to-parent
sf data query \
--query "SELECT Id, Name, Account.Name FROM Contact LIMIT 10" \
--target-org my-sandbox
# Parent-to-child
sf data query \
--query "SELECT Id, Name, (SELECT Id, Name FROM Contacts) FROM Account LIMIT 5" \
--target-org my-sandbox
Output Formats
Human-Readable (Default)
sf data query \
--query "SELECT Id, Name FROM Account LIMIT 5" \
--target-org my-sandbox
JSON
sf data query \
--query "SELECT Id, Name FROM Account LIMIT 5" \
--target-org my-sandbox \
--json
CSV
sf data query \
--query "SELECT Id, Name, Industry FROM Account" \
--target-org my-sandbox \
--result-format csv > accounts.csv
Direct to File
sf data query \
--query "SELECT Id, Name, Industry FROM Account" \
--target-org my-sandbox \
--result-format csv \
--output-file accounts.csv
Bulk Data Export
For large result sets (> 2,000 records), use the dedicated bulk export command:
# Export to CSV (default)
sf data export bulk \
--query "SELECT Id, Name FROM Account" \
--target-org my-sandbox \
--output-file accounts.csv
# Export as JSON
sf data export bulk \
--query "SELECT Id, Name FROM Account" \
--target-org my-sandbox \
--output-file accounts.json \
--result-format json
Note
:
--bulkand--waitflags onsf data querywere removed in v2.87.7. Usesf data export bulkinstead.
Query Plan Analysis
Analyze query performance before running:
sf data query \
--query "SELECT Id FROM Account WHERE Name = 'Acme'" \
--target-org my-sandbox \
--use-tooling-api \
--plan
Understanding Query Plan Output
{
"plans": [{
"cardinality": 50, // Estimated rows returned
"fields": ["Name"], // Fields used for filtering
"leadingOperationType": "Index", // Index = good, TableScan = bad
"relativeCost": 0.1, // Lower is better
"sobjectCardinality": 10000, // Total records in object
"sobjectType": "Account"
}]
}
Key Indicators:
leadingOperationType: "Index"= Query uses index (good)leadingOperationType: "TableScan"= Full table scan (bad for large tables)relativeCost < 1= Efficient querycardinality= Expected number of results
Tooling API Queries
Query metadata objects:
# Query ApexClass
sf data query \
--query "SELECT Id, Name, Body FROM ApexClass WHERE Name = 'MyController'" \
--target-org my-sandbox \
--use-tooling-api
# Query CustomField
sf data query \
--query "SELECT Id, DeveloperName, TableEnumOrId FROM CustomField WHERE TableEnumOrId = 'Account'" \
--target-org my-sandbox \
--use-tooling-api
Query from File
Store query in file and execute:
# Create query file
echo "SELECT Id, Name FROM Account WHERE Industry = 'Technology'" > query.soql
# Execute from file
sf data query \
--file query.soql \
--target-org my-sandbox
Useful Patterns
Get Record Count
sf data query \
--query "SELECT COUNT() FROM Account" \
--target-org my-sandbox
Export to File
# CSV export
sf data query \
--query "SELECT Id, Name, Industry, Phone FROM Account" \
--target-org my-sandbox \
--result-format csv > accounts.csv
# JSON export
sf data query \
--query "SELECT Id, Name, Industry FROM Account" \
--target-org my-sandbox \
--json > accounts.json
Query with jq Processing
# Get just the names
sf data query \
--query "SELECT Name FROM Account LIMIT 10" \
--target-org my-sandbox \
--json | jq -r '.result.records[].Name'
# Count records
sf data query \
--query "SELECT Id FROM Account" \
--target-org my-sandbox \
--json | jq '.result.totalSize'
# Filter in shell
sf data query \
--query "SELECT Id, Name, Industry FROM Account" \
--target-org my-sandbox \
--json | jq '.result.records[] | select(.Industry == "Technology")'
Query with Dates
# Records created today
sf data query \
--query "SELECT Id, Name FROM Account WHERE CreatedDate = TODAY" \
--target-org my-sandbox
# Records from last 30 days
sf data query \
--query "SELECT Id, Name FROM Account WHERE CreatedDate = LAST_N_DAYS:30" \
--target-org my-sandbox
Aggregate Queries
# Count by industry
sf data query \
--query "SELECT Industry, COUNT(Id) FROM Account GROUP BY Industry" \
--target-org my-sandbox
# Sum of amounts
sf data query \
--query "SELECT SUM(Amount) FROM Opportunity WHERE StageName = 'Closed Won'" \
--target-org my-sandbox
Troubleshooting
Query Timeout
For long-running queries, export via bulk API:
sf data export bulk \
--query "SELECT Id, Name FROM Account" \
--target-org my-sandbox \
--output-file results.csv
Too Many Results
Add LIMIT or filter:
# With limit
sf data query \
--query "SELECT Id, Name FROM Account LIMIT 1000" \
--target-org my-sandbox
# With filter
sf data query \
--query "SELECT Id, Name FROM Account WHERE CreatedDate = THIS_YEAR" \
--target-org my-sandbox
Non-Selective Query Error
Add indexed field to WHERE:
# Add CreatedDate filter (indexed)
sf data query \
--query "SELECT Id FROM Lead WHERE Status = 'Open' AND CreatedDate = LAST_N_DAYS:90" \
--target-org my-sandbox
Permission Errors
Check field-level security:
# Query accessible fields only
sf data query \
--query "SELECT Id, Name FROM Account" \
--target-org my-sandbox
Integration with Other Tools
Pipe to File
sf data query \
--query "SELECT Id, Name FROM Account" \
--target-org my-sandbox \
--result-format csv | tee accounts.csv
Use in Scripts
#!/bin/bash
ORG=${1:-"my-sandbox"}
# Get count
COUNT=$(sf data query \
--query "SELECT COUNT() FROM Account" \
--target-org $ORG \
--json | jq -r '.result.totalSize')
echo "Total accounts: $COUNT"
# Get top accounts
sf data query \
--query "SELECT Name, AnnualRevenue FROM Account ORDER BY AnnualRevenue DESC LIMIT 10" \
--target-org $ORG
Compare Orgs
#!/bin/bash
PROD_COUNT=$(sf data query --query "SELECT COUNT() FROM Account" --target-org prod --json | jq '.result.totalSize')
SANDBOX_COUNT=$(sf data query --query "SELECT COUNT() FROM Account" --target-org sandbox --json | jq '.result.totalSize')
echo "Production accounts: $PROD_COUNT"
echo "Sandbox accounts: $SANDBOX_COUNT"
echo "Difference: $((PROD_COUNT - SANDBOX_COUNT))"