
Sqldw Authoring Cli
- 122 installs
- 886 repo stars
- Updated July 23, 2026
- microsoft/skills-for-fabric
>.
About
>. > **Update Check — ONCE PER SESSION (mandatory)** > The first time this skill is used in a session, run the **check-updates** skill before proceeding. > - **GitHub Copilot CLI / VS Code**: invoke the `check-updates` skill. > - **Claude Code / Cowork / Cursor / Windsurf / Codex**: compare local vs remote package.json version. > - Skip if the check was already performed earlier in this session.
- > **Update Check — ONCE PER SESSION (mandatory)**
- > The first time this skill is used in a session, run the **check-updates** skill before proceeding.
- > - **GitHub Copilot CLI / VS Code**: invoke the `check-updates` skill.
- > - **Claude Code / Cowork / Cursor / Windsurf / Codex**: compare local vs remote package.json version.
- > - Skip if the check was already performed earlier in this session.
Sqldw Authoring Cli by the numbers
- 122 all-time installs (skills.sh)
- Ranked #1,090 of 1,881 Marketing & SEO skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Jul 28, 2026 (Skillselion catalog sync)
sqldw-authoring-cli capabilities & compatibility
- Capabilities
- > **update check — once per session (mandatory)* · > the first time this skill is used in a session · > **github copilot cli / vs code**: invoke the · > **claude code / cowork / cursor / windsurf /
- Use cases
- documentation
What sqldw-authoring-cli says it does
>
npx skills add https://github.com/microsoft/skills-for-fabric --skill sqldw-authoring-cliAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 122 |
|---|---|
| repo stars | ★ 886 |
| Security audit | 3 / 3 scanners passed |
| Last updated | July 23, 2026 |
| Repository | microsoft/skills-for-fabric ↗ |
How do I apply sqldw-authoring-cli using the workflow in its SKILL.md?
>
Who is it for?
Developers following the sqldw-authoring-cli skill for the tasks it documents.
Skip if: Tasks outside the sqldw-authoring-cli scope described in SKILL.md.
When should I use this skill?
User mentions sqldw-authoring-cli or related triggers from the skill description.
What you get
Working sqldw-authoring-cli setup aligned with the documented patterns and constraints.
Files
Update Check — ONCE PER SESSION (mandatory)
The first time this skill is used in a session, run the check-updates skill before proceeding.
- GitHub Copilot CLI / VS Code: invoke the check-updates skill.- Claude Code / Cowork / Cursor / Windsurf / Codex: compare local vs remote package.json version.
- Skip if the check was already performed earlier in this session.
CRITICAL NOTES
1. To find the workspace details (including its ID) from workspace name: list all workspaces and, then, use JMESPath filtering
2. To find the item details (including its ID) from workspace ID, item type, and item name: list all items of that type in that workspace and, then, use JMESPath filtering
SQL Endpoint Authoring — CLI Skill
Table of Contents
| Task | Reference | Notes |
|---|---|---|
| Finding Workspaces and Items in Fabric | COMMON-CLI.md § Finding Workspaces and Items in Fabric | Mandatory — READ link first [needed for finding workspace id by its name or item id by its name, item type, and workspace id] |
| Fabric Topology & Key Concepts | COMMON-CORE.md § Fabric Topology & Key Concepts | |
| Environment URLs | COMMON-CORE.md § Environment URLs | |
| Authentication & Token Acquisition | COMMON-CORE.md § Authentication & Token Acquisition | Wrong audience = 401; read before any auth issue |
| Core Control-Plane REST APIs | COMMON-CORE.md § Core Control-Plane REST APIs | Includes pagination, LRO polling, and rate-limiting patterns |
| OneLake Data Access | COMMON-CORE.md § OneLake Data Access | Requires storage.azure.com token, not Fabric token |
| Definition Envelope | ITEM-DEFINITIONS-CORE.md § Definition Envelope | Definition payload structure |
| Per-Item-Type Definitions | ITEM-DEFINITIONS-CORE.md § Per-Item-Type Definitions | Support matrix, decoded content, part paths — REST specs, CLI recipes |
| Job Execution | COMMON-CORE.md § Job Execution | |
| Capacity Management | COMMON-CORE.md § Capacity Management | |
| Gotchas, Best Practices & Troubleshooting (Platform) | COMMON-CORE.md § Gotchas, Best Practices & Troubleshooting | |
| Tool Selection Rationale | COMMON-CLI.md § Tool Selection Rationale | |
| Authentication Recipes | COMMON-CLI.md § Authentication Recipes | az login flows and token acquisition |
Fabric Control-Plane API via az rest | COMMON-CLI.md § Fabric Control-Plane API via az rest | Always pass `--resource`; includes pagination and LRO helpers |
OneLake Data Access via curl | COMMON-CLI.md § OneLake Data Access via curl | Use curl not az rest (different token audience) |
| SQL / TDS Data-Plane Access | COMMON-CLI.md § SQL / TDS Data-Plane Access | sqlcmd (Go) connect, query, CSV export |
| Job Execution (CLI) | COMMON-CLI.md § Job Execution | |
| OneLake Shortcuts | COMMON-CLI.md § OneLake Shortcuts | |
| Capacity Management (CLI) | COMMON-CLI.md § Capacity Management | |
| Composite Recipes | COMMON-CLI.md § Composite Recipes | |
| Gotchas & Troubleshooting (CLI-Specific) | COMMON-CLI.md § Gotchas & Troubleshooting (CLI-Specific) | az rest audience, shell escaping, token expiry |
| Quick Reference | COMMON-CLI.md § Quick Reference | az rest template + token audience/tool matrix |
| Item-Type Capability Matrix | SQLDW-CONSUMPTION-CORE.md § Item-Type Capability Matrix | Shows read-only (SQLEP) vs read-write (DW) |
| Connection Fundamentals | SQLDW-CONSUMPTION-CORE.md § Connection Fundamentals | TDS, port 1433, Entra-only, no MARS |
| Supported T-SQL Surface Area (Consumption Focus) | SQLDW-CONSUMPTION-CORE.md § Supported T-SQL Surface Area | Read before writing T-SQL — includes data types (no nvarchar/datetime/money) |
| Read-Side Objects You Can Create | SQLDW-CONSUMPTION-CORE.md § Read-Side Objects You Can Create | Views, TVFs, scalar UDFs, procedures |
| Temporary Tables | SQLDW-CONSUMPTION-CORE.md § Temporary Tables | |
| Cross-Database Queries | SQLDW-CONSUMPTION-CORE.md § Cross-Database Queries | 3-part naming, same workspace only |
| Security for Consumption | SQLDW-CONSUMPTION-CORE.md § Security for Consumption | GRANT/DENY, RLS, CLS, DDM |
| Monitoring and Diagnostics | SQLDW-CONSUMPTION-CORE.md § Monitoring and Diagnostics | Includes query labels; DMVs (live) + queryinsights.* (30-day history) |
| Performance: Best Practices and Troubleshooting | SQLDW-CONSUMPTION-CORE.md § Performance: Best Practices and Troubleshooting | Statistics, caching, clustering, query tips |
| REST API: Refresh SQL Endpoint Metadata | SQLDW-CONSUMPTION-CORE.md § REST API: Refresh SQL Endpoint Metadata | Force metadata sync when SQLEP is stale after ETL |
| System Catalog Queries (Metadata Exploration) | SQLDW-CONSUMPTION-CORE.md § System Catalog Queries | sys.tables, sys.columns, sys.views, sys.stats |
| Common Consumption Patterns | SQLDW-CONSUMPTION-CORE.md § Common Consumption Patterns | Reporting views, cross-DB analytics, temp table staging |
| Gotchas and Troubleshooting (Consumption) | SQLDW-CONSUMPTION-CORE.md § Gotchas and Troubleshooting Reference | 18 numbered issues with cause + resolution |
| Quick Reference: Consumption Capabilities | SQLDW-CONSUMPTION-CORE.md § Quick Reference: Consumption Capabilities | |
| Authoring Capability Matrix | SQLDW-AUTHORING-CORE.md § Authoring Capability Matrix | Read first — DW vs SQLEP authoring scope |
| Table DDL (DW Only) | SQLDW-AUTHORING-CORE.md § Table DDL (DW Only) | CREATE, CTAS, ALTER, sp_rename, DROP, constraints, schema evolution, IDENTITY |
| DML Operations (DW Only) | SQLDW-AUTHORING-CORE.md § DML Operations (DW Only) | INSERT...SELECT, UPDATE, DELETE, TRUNCATE, MERGE |
| Data Ingestion (DW Only) | SQLDW-AUTHORING-CORE.md § Data Ingestion (DW Only) | COPY INTO, OPENROWSET, method comparison |
| Transactions (DW Only) | SQLDW-AUTHORING-CORE.md § Transactions (DW Only) | Snapshot isolation only; write-write conflict rules |
| Stored Procedures (Authoring Patterns) | SQLDW-AUTHORING-CORE.md § Stored Procedures (Authoring Patterns) | ETL procs, upsert, CTAS swap, cursor replacement |
| Time Travel and Warehouse Snapshots | SQLDW-AUTHORING-CORE.md § Time Travel and Warehouse Snapshots (DW Only) | FOR TIMESTAMP AS OF; 30-day retention; snapshots GA |
| Source Control and CI/CD | SQLDW-AUTHORING-CORE.md § Source Control and CI/CD (DW Only — Preview) | Git integration, SQL DB projects, deployment pipelines |
| Authoring Permission Model | SQLDW-AUTHORING-CORE.md § Authoring Permission Model | Contributor minimum for DDL/DML; Admin for GRANT |
| Authoring Gotchas and Troubleshooting | SQLDW-AUTHORING-CORE.md § Authoring Gotchas and Troubleshooting | 17-row issue/cause/resolution table |
| Common Authoring Patterns | SQLDW-AUTHORING-CORE.md § Common Authoring Patterns | Incremental load, SCD Type 1, SQLEP view layer |
| Quick Reference: Authoring Decision Guide | SQLDW-AUTHORING-CORE.md § Quick Reference: Authoring Decision Guide | Scenario → recommended approach lookup |
| Core Authoring via CLI | authoring-cli-quickref.md § Core Authoring via CLI | Table DDL, DML, data ingestion sqlcmd one-liners |
| Advanced Authoring Patterns via CLI | authoring-cli-quickref.md § Advanced Authoring Patterns via CLI | Transactions, schema evolution, stored procedures, time travel |
| Bash Templates | authoring-script-templates.md § Bash Templates | COPY INTO, ELT pipeline, upsert with retry, schema migration, time travel recovery, stored procedure |
| PowerShell Templates | authoring-script-templates.md § PowerShell Templates | COPY INTO ingestion, incremental upsert with retry |
| Tool Stack | SKILL.md § Tool Stack | sqlcmd (Go) + az CLI + jq; verify before first op |
| Connection | SKILL.md § Connection | FQDN discovery, reusable vars, PowerShell |
| Script Generation | authoring-cli-quickref.md § Script Generation | sqlcmd output flags, piped input, parameterized queries |
| Agentic Workflows | SKILL.md § Agentic Workflows | Start here — discover schema before any write |
| Monitoring Authoring Operations | authoring-cli-quickref.md § Monitoring Authoring Operations | Active DML/DDL, recent ETL, failed writes |
| Gotchas, Rules, Troubleshooting | SKILL.md § Gotchas, Rules, Troubleshooting | MUST DO / AVOID / PREFER checklists |
| Agent Integration Notes | authoring-cli-quickref.md § Agent Integration Notes | Platform-specific tips (Copilot CLI, Claude Code) |
---
Tool Stack
| Tool | Role | Install |
|---|---|---|
sqlcmd (Go) | Primary: Execute DDL/DML T-SQL. Standalone binary, no ODBC, built-in Entra ID auth. | winget install sqlcmd / brew install sqlcmd / apt-get install sqlcmd |
az CLI | Auth (az login), token acquisition, Fabric REST for endpoint discovery, snapshot management. | Pre-installed in most dev environments |
jq | Parse JSON from az rest | Pre-installed or trivial |
Agent check — verify before first operation:
```bash
sqlcmd --version 2>/dev/null || echo "INSTALL: winget install sqlcmd OR brew install sqlcmd"
```
Authoring Scope by Item Type
| Capability | Warehouse (DW) | Lakehouse/Mirrored DB SQLEP |
|---|---|---|
| Table DDL (CREATE/ALTER/DROP) | ✅ | ❌ |
| DML (INSERT/UPDATE/DELETE/MERGE) | ✅ | ❌ |
| COPY INTO, OPENROWSET (ingest) | ✅ | OPENROWSET read-only |
| Transactions | ✅ | ❌ |
| Time travel, snapshots | ✅ | ❌ |
| CREATE VIEW/FUNCTION/PROCEDURE | ✅ | ✅ |
| CREATE SCHEMA | ✅ | ✅ |
---
Connection
Discover the SQL Endpoint FQDN
Per COMMON-CLI.md Discovering Connection Parameters via REST:
WS_ID="<workspaceId>"
ITEM_ID="<warehouseOrLakehouseId>"
# Warehouse
az rest --method get \
--resource "https://api.fabric.microsoft.com" \
--url "https://api.fabric.microsoft.com/v1/workspaces/$WS_ID/warehouses/$ITEM_ID" \
--query "properties.connectionString" --output tsv
# Lakehouse SQL endpoint
az rest --method get \
--resource "https://api.fabric.microsoft.com" \
--url "https://api.fabric.microsoft.com/v1/workspaces/$WS_ID/lakehouses/$ITEM_ID" \
--query "properties.sqlEndpointProperties.connectionString" --output tsvResult: <uniqueId>.datawarehouse.fabric.microsoft.com
Connect with sqlcmd (Go)
# Non-interactive one-shot query
sqlcmd -S "<endpoint>.datawarehouse.fabric.microsoft.com" -d "<DatabaseName>" -G \
-Q "SELECT TOP 10 * FROM dbo.FactSales"
# Service principal (CI/CD)
SQLCMDPASSWORD="<clientSecret>" \
sqlcmd -S "<endpoint>.datawarehouse.fabric.microsoft.com" -d "<DatabaseName>" \
--authentication-method ActiveDirectoryServicePrincipal \
-U "<appId>" \
-Q "SELECT COUNT(*) FROM dbo.FactSales"Reusable Connection Variables
# Set once at script top
FABRIC_SERVER="<endpoint>.datawarehouse.fabric.microsoft.com"
FABRIC_DB="<DatabaseName>"
SQLCMD="sqlcmd -S $FABRIC_SERVER -d $FABRIC_DB -G"
# Use throughout
$SQLCMD -Q "SELECT TOP 5 * FROM dbo.DimProduct"
$SQLCMD -i myscript.sqlPowerShell / Windows CMD
$s = "<endpoint>.datawarehouse.fabric.microsoft.com"; $db = "<DatabaseName>"
sqlcmd -S $s -d $db -G -Q "SELECT TOP 10 * FROM dbo.FactSales"
# CMD: use set S=... and %S% / %DB% instead of $variables---
Agentic Workflows
Schema Discovery Before Authoring
Before any write operation, discover the target schema:
# 1. List tables
$SQLCMD -Q "SELECT table_schema, table_name FROM information_schema.tables ORDER BY 1,2" -W
# 2. Check columns
$SQLCMD -Q "SELECT column_name, data_type, is_nullable FROM information_schema.columns WHERE table_name='FactSales' ORDER BY ordinal_position" -W
# 3. Sample data
$SQLCMD -Q "SELECT TOP 5 * FROM dbo.FactSales" -W
# 4. Check constraints
$SQLCMD -Q "SELECT constraint_name, constraint_type FROM information_schema.table_constraints WHERE table_name='FactSales'" -W
# 5. Row counts
$SQLCMD -Q "SELECT s.name AS [schema], t.name AS [table], SUM(p.rows) AS row_count FROM sys.tables t JOIN sys.schemas s ON t.schema_id=s.schema_id JOIN sys.partitions p ON t.object_id=p.object_id AND p.index_id IN (0,1) GROUP BY s.name, t.name ORDER BY row_count DESC" -W
# 6. Programmability objects
$SQLCMD -Q "SELECT name, type_desc FROM sys.objects WHERE type IN ('V','FN','IF','P','TF') ORDER BY type_desc, name" -WAgentic Workflow
1. Discover → Run steps 1–4 to understand available tables/columns. 2. Sample → SELECT TOP 5 on relevant tables. 3. Formulate → Select pattern from SQLDW-AUTHORING-CORE.md (Table DDL through Common Authoring Patterns). 4. Execute → $SQLCMD -Q "..." or $SQLCMD -i file.sql for multi-statement. 5. Verify → Query affected table (SELECT COUNT(*), SELECT TOP 5). 6. Optionally script → Generate reusable .sh or .ps1 using references/authoring-script-templates.md.
---
Gotchas, Rules, Troubleshooting
For full authoring gotchas: SQLDW-AUTHORING-CORE.md Authoring Gotchas and Troubleshooting. For CLI-specific issues: COMMON-CLI.md Gotchas & Troubleshooting (CLI-Specific).
MUST DO
- Verify workspace has capacity before creating warehouse — call
GET /v1/workspaces/{id}and checkcapacityId. - Always `-d <DatabaseName>` — FQDN alone is insufficient.
- Always `-G` or `--authentication-method` — SQL auth not supported on Fabric.
- `az login` first —
ActiveDirectoryDefaultuses az session. No session → cryptic failure. - `SET NOCOUNT ON;` in scripts — suppresses row-count messages that corrupt output.
- Use `-i file.sql` for multi-statement batches (CREATE PROCEDURE, transactions with GO separators).
- Label authoring queries with
OPTION (LABEL = 'ETL_description'). - Use explicit `CAST()` in CTAS to control output types.
- Keep transactions short — long transactions increase conflict window.
AVOID
- ODBC sqlcmd (
/opt/mssql-tools/bin/sqlcmd) — requires ODBC driver. Use Go version. - Omitting `-W` in scripts — trailing spaces corrupt CSV.
- Singleton `INSERT ... VALUES` at scale — creates tiny Parquet files. Use INSERT...SELECT, CTAS, or COPY INTO.
- `DROP TABLE IF EXISTS` + `CREATE TABLE` to refresh — loses time-travel history. Use
TRUNCATE TABLE+INSERT INTO. - MERGE in production — preview, table-level conflict detection. Use DELETE + INSERT.
- ALTER COLUMN — not supported. Use CTAS workaround (Schema Evolution).
- Variables in CTAS — not allowed. Wrap in dynamic SQL:
EXEC sp_executesql N'CREATE TABLE ...'. - DML on Lakehouse/Mirrored DB SQLEP — read-only for table data. Only views/funcs/procs can be authored.
- Concurrent UPDATE/DELETE on same table — snapshot isolation conflicts at table level. Serialize writes.
- Hardcoded FQDNs — discover via REST API (Connection section).
- MARS — not supported. Remove
MultipleActiveResultSetsfrom connection strings.
PREFER
- CTAS over
CREATE TABLE+INSERT— parallel, single-operation. - `INSERT ... SELECT` over singleton INSERTs.
- `COPY INTO` for external file ingestion — highest throughput.
- DELETE + INSERT over MERGE for upserts in production.
- `TRUNCATE TABLE` over
DELETE FROMwithout WHERE — faster, preserves history. - `-i file.sql` over
-Q "..."for anything beyond simple one-liners. - Piped here-doc for multi-statement batches without GO requirements.
- CTAS + sp_rename for large-scale transforms instead of UPDATE.
- `sqlcmd (Go) -G` over curl+token for SQL queries.
- `-Q` (non-interactive exit) for agentic use.
- `-F vertical` for exploration of wide tables.
- Env vars (
FABRIC_SERVER,FABRIC_DB) for script reuse.
TROUBLESHOOTING
| Symptom | Fix |
|---|---|
| Error 24556/24706 snapshot conflict | Serialize writes to same table; retry with backoff |
| COPY INTO auth error | Grant Storage Blob Data Reader on ADLS; or SAS in CREDENTIAL |
| COPY INTO from OneLake fails | Provision workspace identity; check firewall rules |
| CTAS unexpected types | Use explicit CAST() in SELECT |
| Singleton INSERT poor perf | Remediate: CTAS + drop + rename to consolidate Parquet |
Proc CREATE fails with -Q | Use -i file.sql (GO separators needed) |
| sp_rename on SQLEP fails | Only available on Warehouse, not Lakehouse/Mirrored DB |
| Deploy drops/recreates table | Avoid ALTER TABLE in DB project; apply manually |
Login failed for user | Verify -d matches item name exactly (case-sensitive) |
Cannot open server / Login timeout expired | Re-discover FQDN via REST API; check port 1433 / firewall |
ActiveDirectoryDefault failure | az login expired — az login --tenant <tenantId> |
Garbled CSV / (N rows affected) in file | Add -W -s"," -w 4000; prepend SET NOCOUNT ON; |
sqlcmd not found | Install Go version: winget install sqlcmd |
Authoring CLI Quick Reference
Concise sqlcmd invocation patterns, output formatting, monitoring queries, and agent tips. For full T-SQL patterns, see SQLDW-AUTHORING-CORE.md. For full reusable scripts, see authoring-script-templates.md.
All examples assume reusable connection variables are set:
FABRIC_SERVER="<endpoint>.datawarehouse.fabric.microsoft.com"
FABRIC_DB="<WarehouseName>"
SQLCMD="sqlcmd -S $FABRIC_SERVER -d $FABRIC_DB -G"Core Authoring via CLI
Table DDL via CLI
# CREATE TABLE
$SQLCMD -Q "
CREATE TABLE dbo.FactSales (
SaleID bigint NOT NULL,
ProductID int NOT NULL,
SaleDate date NOT NULL,
Amount decimal(19,4) NOT NULL
)"
# CTAS with explicit types (preferred for populated tables)
$SQLCMD -Q "
CREATE TABLE dbo.FactSales_2024 AS
SELECT SaleID, CAST(Amount AS decimal(19,2)) AS Amount
FROM dbo.FactSales WHERE SaleDate >= '2024-01-01'"
# ALTER TABLE — add column / DROP TABLE
$SQLCMD -Q "ALTER TABLE dbo.FactSales ADD Region varchar(50) NULL"
$SQLCMD -Q "DROP TABLE IF EXISTS dbo.StagingTable"DML via CLI
# INSERT...SELECT (preferred for bulk)
$SQLCMD -Q "
INSERT INTO dbo.FactSales (SaleID, ProductID, SaleDate, Amount)
SELECT SaleID, ProductID, SaleDate, Amount
FROM dbo.StagingTable WHERE IsValid = 1"
# Upsert (production-safe: DELETE + INSERT) — use -i for multi-statement
$SQLCMD -i upsert.sql
# TRUNCATE (fast, preserves history — use instead of DELETE FROM)
$SQLCMD -Q "TRUNCATE TABLE dbo.StagingTable"Data Ingestion via CLI
# Parquet from ADLS Gen2 (uses caller's Entra ID credentials)
$SQLCMD -Q "
COPY INTO dbo.FactSales
FROM 'https://storageacct.dfs.core.windows.net/container/sales/*.parquet'
WITH (FILE_TYPE = 'PARQUET')"
# CSV with options
$SQLCMD -Q "
COPY INTO dbo.FactSales
FROM 'https://storageacct.dfs.core.windows.net/container/sales/*.csv'
WITH (FILE_TYPE = 'CSV', FIRSTROW = 2, FIELDTERMINATOR = ',', ROWTERMINATOR = '\n')"
# OPENROWSET + CTAS (transform-on-ingest)
$SQLCMD -Q "
CREATE TABLE dbo.CleanData AS
SELECT id, UPPER(country) AS Country, CAST(amount AS decimal(19,4)) AS Amount
FROM OPENROWSET(BULK 'https://storageacct.dfs.core.windows.net/container/raw/*.parquet') AS raw
WHERE amount > 0"Advanced Authoring Patterns via CLI
Transactions via CLI
Multi-statement transactions require input files or piped here-docs (GO separators needed between batch-scoped statements).
# Simple transaction via piped input
cat <<'SQL' | sqlcmd -S "$FABRIC_SERVER" -d "$FABRIC_DB" -G
BEGIN TRANSACTION;
INSERT INTO dbo.FactSales SELECT * FROM dbo.StagingTable WHERE IsValid = 1;
DELETE FROM dbo.StagingTable WHERE IsValid = 1;
COMMIT TRANSACTION;
SQL
# Transaction with TRY/CATCH via input file
sqlcmd -S "$FABRIC_SERVER" -d "$FABRIC_DB" -G -i etl_load.sqlSchema Evolution via CLI
# Add nullable column (fast metadata op)
$SQLCMD -Q "ALTER TABLE dbo.FactSales ADD Region varchar(50) NULL"
# Drop column (April 2025+)
$SQLCMD -Q "ALTER TABLE dbo.FactSales DROP COLUMN Region"
# Change column type (CTAS workaround — ALTER COLUMN not supported)
$SQLCMD -i schema_migrate.sqlWarning: CTAS + rename loses time-travel history and security. Re-apply GRANT/DENY after swap.
Stored Procedures via CLI
# Create procedure (use -i for multi-statement with GO)
sqlcmd -S "$FABRIC_SERVER" -d "$FABRIC_DB" -G -i create_sp.sql
# Execute procedure
$SQLCMD -Q "EXEC dbo.sp_LoadFactSales @BatchDate = '2025-06-15'"
# Create view on Lakehouse SQLEP (read-only endpoint — views/funcs/procs allowed)
sqlcmd -S "$LAKEHOUSE_SERVER" -d "$LAKEHOUSE_DB" -G -i create_views.sqlTime Travel and Recovery via CLI
# Query data as it existed at a specific time (UTC)
$SQLCMD -Q "
SELECT * FROM dbo.FactSales
OPTION (FOR TIMESTAMP AS OF '2025-06-14T23:59:59.999')" -W
# Recover deleted data via CTAS + merge back
$SQLCMD -Q "
CREATE TABLE dbo.FactSales_Recovered AS
SELECT * FROM dbo.FactSales
OPTION (FOR TIMESTAMP AS OF '2025-06-14T23:59:59.999')"Script Generation
sqlcmd Output Formatting Flags
| Flag | Purpose | When |
|---|---|---|
-W | Trim trailing spaces | Always |
-s"," | Column separator | CSV export |
-s"\t" | Tab separator | TSV export |
-h-1 | No headers/dashes | Clean CSV body |
-h 1 | Headers, no dashes | CSV with headers |
-w 4000 | Line width | Wide tables |
-o file | Output to file | Export |
-i file.sql | Input from file | Complex queries, multi-statement |
-F vertical | One column per row | Exploration |
SET NOCOUNT ON; | Suppress row-affected messages | Always in scripts |
Piped Input
# Pipe SQL from stdin
echo "SELECT TOP 5 * FROM dbo.FactSales" | sqlcmd -S "$FABRIC_SERVER" -d "$FABRIC_DB" -G
# Here-doc for multi-statement
cat <<'SQL' | sqlcmd -S "$FABRIC_SERVER" -d "$FABRIC_DB" -G
SET NOCOUNT ON;
SELECT COUNT(*) AS TotalRows FROM dbo.FactSales;
SELECT TOP 3 ProductID, SUM(Amount) AS Total FROM dbo.FactSales GROUP BY ProductID ORDER BY Total DESC;
SQLParameterized Queries (sqlcmd Variables)
sqlcmd -S "$FABRIC_SERVER" -d "$FABRIC_DB" -G \
-v StartDate="2025-01-01" EndDate="2025-06-30" \
-Q "SET NOCOUNT ON; SELECT * FROM dbo.FactSales WHERE SaleDate BETWEEN '$(StartDate)' AND '$(EndDate)'" -WFor full reusable bash/PowerShell script templates, see authoring-script-templates.md.
Monitoring Authoring Operations
For full monitoring catalog see SQLDW-CONSUMPTION-CORE.md § Monitoring and Diagnostics.
# Active DML/DDL operations
$SQLCMD -Q "SELECT request_id, session_id, command, status, total_elapsed_time/1000 AS sec FROM sys.dm_exec_requests WHERE command IN ('INSERT','UPDATE','DELETE','MERGE','CREATE TABLE','COPY') ORDER BY total_elapsed_time DESC" -W
# Recent ETL queries (last 24h)
$SQLCMD -Q "SELECT TOP 20 distributed_statement_id, login_name, label, total_elapsed_time_ms FROM queryinsights.exec_requests_history WHERE start_time >= DATEADD(HOUR,-24,GETUTCDATE()) AND label LIKE 'ETL_%' ORDER BY total_elapsed_time_ms DESC" -W
# Failed writes (last 7d) — detect snapshot conflicts
$SQLCMD -Q "SELECT TOP 10 distributed_statement_id, command, start_time, status FROM queryinsights.exec_requests_history WHERE status='Failed' AND start_time >= DATEADD(DAY,-7,GETUTCDATE()) ORDER BY start_time DESC" -W
# Kill a stuck session (Admin role)
$SQLCMD -Q "KILL '<distributed_statement_id>'"Agent Integration Notes
- GitHub Copilot CLI: Generate
sqlcmdone-liners for DDL/DML or complete.sql+.shfile pairs. Ensure-Gand-din output. For COPY INTO, remind user about Storage Blob Data Reader role. - Claude Code / Cowork: Run
sqlcmd -Q "..."viabashtool directly. For multi-statement authoring (procedures, transactions): write.sqlfile first, then execute with-i. Always verifysqlcmdavailability andaz loginbefore first use. After writes: verify success by querying affected table. - Common agent pattern:
1. Discover schema (columns, types) 2. Formulate CTAS/DML with explicit CASTs 3. Execute via sqlcmd 4. Verify result (row count, sample) 5. Optionally generate reusable script
Authoring Script Templates
Self-contained templates for generating reusable authoring scripts.
Common prerequisites (validated in each template):
sqlcmd(Go) installed —winget install sqlcmd/brew install sqlcmdaz loginsession active- Env vars:
FABRIC_SERVER,FABRIC_DB
Bash Templates
Bash — COPY INTO Ingestion
#!/usr/bin/env bash
set -euo pipefail
FABRIC_SERVER="${FABRIC_SERVER:?Set FABRIC_SERVER env var}"
FABRIC_DB="${FABRIC_DB:?Set FABRIC_DB env var}"
STORAGE_PATH="${1:?Usage: $0 <storage_path> [table_name]}"
TABLE_NAME="${2:-dbo.StagingData}"
command -v sqlcmd >/dev/null 2>&1 || { echo "ERROR: sqlcmd (Go) not found. Install: winget install sqlcmd"; exit 1; }
az account show >/dev/null 2>&1 || { echo "Run 'az login' first."; exit 1; }
echo "Loading $STORAGE_PATH → $TABLE_NAME ..."
sqlcmd -S "$FABRIC_SERVER" -d "$FABRIC_DB" -G -Q "
COPY INTO $TABLE_NAME
FROM '$STORAGE_PATH'
WITH (FILE_TYPE = 'PARQUET')
OPTION (LABEL = 'ETL_COPY_INTO_$(date +%Y%m%d)')"
echo "Verifying..."
sqlcmd -S "$FABRIC_SERVER" -d "$FABRIC_DB" -G -Q "
SET NOCOUNT ON; SELECT COUNT(*) AS row_count FROM $TABLE_NAME" -W -h-1
echo "✓ Done"Bash — Full ELT Pipeline (Stage → Transform → Load)
#!/usr/bin/env bash
set -euo pipefail
FABRIC_SERVER="${FABRIC_SERVER:?}" ; FABRIC_DB="${FABRIC_DB:?}"
STORAGE_PATH="${1:?Usage: $0 <parquet_path>}"
BATCH_DATE=$(date +%Y-%m-%d)
command -v sqlcmd >/dev/null 2>&1 || { echo "ERROR: sqlcmd not found."; exit 1; }
az account show >/dev/null 2>&1 || { echo "Run 'az login' first."; exit 1; }
SQLCMD="sqlcmd -S $FABRIC_SERVER -d $FABRIC_DB -G"
echo "[1/3] Loading raw data from $STORAGE_PATH ..."
$SQLCMD -Q "
COPY INTO dbo.Staging_RawSales
FROM '$STORAGE_PATH'
WITH (FILE_TYPE = 'PARQUET')
OPTION (LABEL = 'ETL_Stage_$BATCH_DATE')"
echo "[2/3] Transforming and loading into FactSales ..."
$SQLCMD -Q "
INSERT INTO dbo.FactSales (SaleID, ProductID, CustomerID, SaleDate, Amount)
SELECT SaleID, ProductID, CustomerID,
CAST(SaleTimestamp AS date) AS SaleDate,
CAST(RawAmount AS decimal(19,4)) AS Amount
FROM dbo.Staging_RawSales
WHERE RawAmount > 0 AND SaleID IS NOT NULL
OPTION (LABEL = 'ETL_Transform_$BATCH_DATE')"
echo "[3/3] Cleaning staging ..."
$SQLCMD -Q "TRUNCATE TABLE dbo.Staging_RawSales"
echo "✓ ELT pipeline complete for $BATCH_DATE"
$SQLCMD -Q "SET NOCOUNT ON; SELECT COUNT(*) AS fact_rows FROM dbo.FactSales" -W -h-1Bash — Incremental Upsert (DELETE + INSERT with Retry)
#!/usr/bin/env bash
set -euo pipefail
FABRIC_SERVER="${FABRIC_SERVER:?}" ; FABRIC_DB="${FABRIC_DB:?}"
CUTOFF_DATE="${1:?Usage: $0 <cutoff_date YYYY-MM-DD>}"
MAX_RETRIES=3
command -v sqlcmd >/dev/null 2>&1 || { echo "ERROR: sqlcmd not found."; exit 1; }
az account show >/dev/null 2>&1 || { echo "Run 'az login' first."; exit 1; }
# Write the upsert SQL to a temp file
TMPFILE=$(mktemp /tmp/upsert_XXXXXX.sql)
cat > "$TMPFILE" <<SQL
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRANSACTION;
DELETE FROM dbo.FactSales WHERE SaleDate >= '$CUTOFF_DATE';
INSERT INTO dbo.FactSales
SELECT * FROM SalesLakehouse.dbo.ProcessedSales WHERE SaleDate >= '$CUTOFF_DATE';
COMMIT TRANSACTION;
PRINT 'SUCCESS';
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
PRINT 'ERROR: ' + CAST(ERROR_NUMBER() AS varchar) + ' - ' + ERROR_MESSAGE();
THROW;
END CATCH;
SQL
ATTEMPT=1
while [ "$ATTEMPT" -le "$MAX_RETRIES" ]; do
echo "Attempt $ATTEMPT/$MAX_RETRIES: Upserting data since $CUTOFF_DATE ..."
if sqlcmd -S "$FABRIC_SERVER" -d "$FABRIC_DB" -G -i "$TMPFILE" 2>&1 | tee /dev/stderr | grep -q "SUCCESS"; then
echo "✓ Upsert complete"
rm -f "$TMPFILE"
exit 0
fi
echo "Retrying in $((ATTEMPT * 5))s ..."
sleep $((ATTEMPT * 5))
ATTEMPT=$((ATTEMPT + 1))
done
rm -f "$TMPFILE"
echo "✗ Failed after $MAX_RETRIES attempts"
exit 1Bash — Schema Migration (CTAS Workaround)
#!/usr/bin/env bash
set -euo pipefail
FABRIC_SERVER="${FABRIC_SERVER:?}" ; FABRIC_DB="${FABRIC_DB:?}"
TABLE="dbo.FactSales"
command -v sqlcmd >/dev/null 2>&1 || { echo "ERROR: sqlcmd not found."; exit 1; }
az account show >/dev/null 2>&1 || { echo "Run 'az login' first."; exit 1; }
TMPFILE=$(mktemp /tmp/migrate_XXXXXX.sql)
cat > "$TMPFILE" <<'SQL'
-- Change Amount type from decimal(19,4) to decimal(19,2)
PRINT 'Creating new table with updated schema...';
CREATE TABLE dbo.FactSales_V2 AS
SELECT SaleID, ProductID, CustomerID, SaleDate,
CAST(Amount AS decimal(19,2)) AS Amount, Quantity
FROM dbo.FactSales;
GO
PRINT 'Dropping original...';
DROP TABLE dbo.FactSales;
GO
PRINT 'Renaming...';
EXEC sp_rename 'dbo.FactSales_V2', 'FactSales';
GO
PRINT 'Re-applying constraints...';
ALTER TABLE dbo.FactSales
ADD CONSTRAINT PK_FactSales PRIMARY KEY NONCLUSTERED (SaleID) NOT ENFORCED;
GO
PRINT 'Migration complete.';
-- WARNING: Re-apply GRANT/DENY security and verify time-travel history is reset.
SQL
echo "Migrating schema for $TABLE ..."
sqlcmd -S "$FABRIC_SERVER" -d "$FABRIC_DB" -G -i "$TMPFILE"
rm -f "$TMPFILE"
echo "✓ Schema migration complete. Re-apply any GRANT/DENY statements."Bash — Data Recovery via Time Travel
#!/usr/bin/env bash
set -euo pipefail
FABRIC_SERVER="${FABRIC_SERVER:?}" ; FABRIC_DB="${FABRIC_DB:?}"
TABLE="${1:?Usage: $0 <table> <utc_timestamp>}"
TIMESTAMP="${2:?Usage: $0 <table> <utc_timestamp>}"
command -v sqlcmd >/dev/null 2>&1 || { echo "ERROR: sqlcmd not found."; exit 1; }
az account show >/dev/null 2>&1 || { echo "Run 'az login' first."; exit 1; }
SQLCMD="sqlcmd -S $FABRIC_SERVER -d $FABRIC_DB -G"
echo "Recovering $TABLE as of $TIMESTAMP ..."
$SQLCMD -Q "
CREATE TABLE ${TABLE}_Recovered AS
SELECT * FROM $TABLE
OPTION (FOR TIMESTAMP AS OF '$TIMESTAMP')"
echo "Recovered rows:"
$SQLCMD -Q "SET NOCOUNT ON; SELECT COUNT(*) AS rows FROM ${TABLE}_Recovered" -W -h-1
echo "Merging back missing rows ..."
# Assumes SaleID as PK — adjust for your table
$SQLCMD -Q "
INSERT INTO $TABLE
SELECT r.* FROM ${TABLE}_Recovered r
WHERE NOT EXISTS (SELECT 1 FROM $TABLE t WHERE t.SaleID = r.SaleID)"
$SQLCMD -Q "DROP TABLE ${TABLE}_Recovered"
echo "✓ Recovery complete"Bash — Create Stored Procedure
#!/usr/bin/env bash
set -euo pipefail
FABRIC_SERVER="${FABRIC_SERVER:?}" ; FABRIC_DB="${FABRIC_DB:?}"
# Write procedure to file (GO separators required)
cat > /tmp/create_sp.sql <<'SQL'
CREATE OR ALTER PROCEDURE dbo.sp_IncrementalLoad
@CutoffDate date
AS
BEGIN
BEGIN TRY
BEGIN TRANSACTION;
DELETE FROM dbo.FactSales WHERE SaleDate >= @CutoffDate;
INSERT INTO dbo.FactSales
SELECT * FROM SalesLakehouse.dbo.ProcessedSales WHERE SaleDate >= @CutoffDate;
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
THROW;
END CATCH;
END;
GO
SQL
sqlcmd -S "$FABRIC_SERVER" -d "$FABRIC_DB" -G -i /tmp/create_sp.sql
echo "✓ Procedure created. Execute: EXEC dbo.sp_IncrementalLoad @CutoffDate = '2025-01-01'"PowerShell Templates
PowerShell — COPY INTO Ingestion
#Requires -Version 5.1
param(
[Parameter(Mandatory)][string]$Server,
[Parameter(Mandatory)][string]$Database,
[Parameter(Mandatory)][string]$StoragePath,
[string]$TableName = "dbo.StagingData"
)
if (-not (Get-Command sqlcmd -ErrorAction SilentlyContinue)) {
Write-Error "sqlcmd (Go) not found. Install: winget install sqlcmd"; exit 1
}
$null = az account show 2>$null
if ($LASTEXITCODE -ne 0) { Write-Error "Not logged in. Run: az login"; exit 1 }
$query = @"
COPY INTO $TableName
FROM '$StoragePath'
WITH (FILE_TYPE = 'PARQUET')
OPTION (LABEL = 'ETL_COPY_$(Get-Date -Format yyyyMMdd)')
"@
Write-Host "Loading $StoragePath → $TableName ..."
sqlcmd -S $Server -d $Database -G -Q $query
Write-Host "Verifying..."
sqlcmd -S $Server -d $Database -G -Q "SET NOCOUNT ON; SELECT COUNT(*) AS rows FROM $TableName" -W -h-1
Write-Host "Done"PowerShell — Incremental Upsert with Retry
#Requires -Version 5.1
param(
[Parameter(Mandatory)][string]$Server,
[Parameter(Mandatory)][string]$Database,
[Parameter(Mandatory)][string]$CutoffDate,
[int]$MaxRetries = 3
)
if (-not (Get-Command sqlcmd -ErrorAction SilentlyContinue)) {
Write-Error "sqlcmd not found."; exit 1
}
$sql = @"
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRANSACTION;
DELETE FROM dbo.FactSales WHERE SaleDate >= '$CutoffDate';
INSERT INTO dbo.FactSales SELECT * FROM SalesLakehouse.dbo.ProcessedSales WHERE SaleDate >= '$CutoffDate';
COMMIT TRANSACTION;
PRINT 'SUCCESS';
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
THROW;
END CATCH;
"@
$tmpFile = [System.IO.Path]::GetTempFileName() + ".sql"
$sql | Out-File -FilePath $tmpFile -Encoding UTF8
for ($i = 1; $i -le $MaxRetries; $i++) {
Write-Host "Attempt $i/$MaxRetries ..."
$output = sqlcmd -S $Server -d $Database -G -i $tmpFile 2>&1
if ($output -match "SUCCESS") {
Remove-Item $tmpFile -Force
Write-Host "Upsert complete"; exit 0
}
Write-Host "Retrying in $($i * 5)s ..."
Start-Sleep -Seconds ($i * 5)
}
Remove-Item $tmpFile -Force
Write-Error "Failed after $MaxRetries attempts"; exit 1Related skills
FAQ
What does sqldw-authoring-cli do?
>
When should I use sqldw-authoring-cli?
Invoke when >.
Is sqldw-authoring-cli safe to install?
Review the Security Audits panel on this page before installing in production.