afv-library/skills/platform-soql-query/references/cli-commands.md

359 lines
7.2 KiB
Markdown
Raw Permalink Normal View History

<!-- Parent: platform-soql-query/SKILL.md -->
# 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
```bash
sf data query \
--query "SELECT Id, Name, Industry FROM Account LIMIT 10" \
--target-org my-sandbox
```
### Query with Filters
```bash
sf data query \
--query "SELECT Id, Name FROM Account WHERE Industry = 'Technology'" \
--target-org my-sandbox
```
### Query Relationships
```bash
# 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)
```bash
sf data query \
--query "SELECT Id, Name FROM Account LIMIT 5" \
--target-org my-sandbox
```
### JSON
```bash
sf data query \
--query "SELECT Id, Name FROM Account LIMIT 5" \
--target-org my-sandbox \
--json
```
### CSV
```bash
sf data query \
--query "SELECT Id, Name, Industry FROM Account" \
--target-org my-sandbox \
--result-format csv > accounts.csv
```
### Direct to File
```bash
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:
```bash
# 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**: `--bulk` and `--wait` flags on `sf data query` were removed in v2.87.7. Use `sf data export bulk` instead.
---
## Query Plan Analysis
Analyze query performance before running:
```bash
sf data query \
--query "SELECT Id FROM Account WHERE Name = 'Acme'" \
--target-org my-sandbox \
--use-tooling-api \
--plan
```
### Understanding Query Plan Output
```json
{
"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 query
- `cardinality` = Expected number of results
---
## Tooling API Queries
Query metadata objects:
```bash
# 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:
```bash
# 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
```bash
sf data query \
--query "SELECT COUNT() FROM Account" \
--target-org my-sandbox
```
### Export to File
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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:
```bash
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:
```bash
# 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:
```bash
# 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:
```bash
# Query accessible fields only
sf data query \
--query "SELECT Id, Name FROM Account" \
--target-org my-sandbox
```
---
## Integration with Other Tools
### Pipe to File
```bash
sf data query \
--query "SELECT Id, Name FROM Account" \
--target-org my-sandbox \
--result-format csv | tee accounts.csv
```
### Use in Scripts
```bash
#!/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
```bash
#!/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))"
```