Execute DDL (Data Definition Language) statements — CREATE, ALTER, DROP tables, indexes, and views on 30+ databases using DbCli. CRITICAL: mandatory backup is required before any DROP or ALTER operations. Use when a user needs to create schema, modify structure, or remove database objects.
All examples use the plain command name dbcli (no directory prefix).
Ensure dbcli is on PATH instead of hardcoding paths like .\.claude\skills\dbcli\dbcli.exe.
Execute Data Definition Language (DDL) operations - CREATE, ALTER, DROP tables, indexes, and views.
MANDATORY BACKUPS BEFORE DROP/ALTER OPERATIONS
DBCLI_CONNECTION="CONNECTION_STRING" DBCLI_DBTYPE="DATABASE_TYPE" dbcli ddl "DDL_STATEMENT"
DBCLI_CONNECTION: Database connection string (required)DBCLI_DBTYPE: Database type (default: sqlite)--config <path>: Config file path (e.g. appsettings.json) (optional)-F, --file: Execute DDL from fileNotes:
GO batch separators in DDL scripts (use -F and keep GO on its own line).# SQLite - Basic table
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "CREATE TABLE Users (Id INTEGER PRIMARY KEY AUTOINCREMENT, Name TEXT NOT NULL, Email TEXT UNIQUE, CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP)"
# SQL Server
DBCLI_CONNECTION="Server=localhost;Database=mydb;Trusted_Connection=True" DBCLI_DBTYPE="sqlserver" dbcli ddl "CREATE TABLE Users (Id INT PRIMARY KEY IDENTITY(1,1), Name NVARCHAR(100) NOT NULL, Email NVARCHAR(255) UNIQUE, CreatedAt DATETIME DEFAULT GETDATE())"
# MySQL
DBCLI_CONNECTION="Server=localhost;Database=mydb;Uid=root;Pwd=xxxxxxxxxx" DBCLI_DBTYPE="mysql" dbcli ddl "CREATE TABLE Users (Id INT PRIMARY KEY AUTO_INCREMENT, Name VARCHAR(100) NOT NULL, Email VARCHAR(255) UNIQUE, CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP)"
# PostgreSQL
DBCLI_CONNECTION="Host=localhost;Database=mydb;Username=postgres;Password=xxxxxxxxxx" DBCLI_DBTYPE="postgresql" dbcli ddl "CREATE TABLE Users (Id SERIAL PRIMARY KEY, Name VARCHAR(100) NOT NULL, Email VARCHAR(255) UNIQUE, CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP)"
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "CREATE TABLE Orders (Id INTEGER PRIMARY KEY AUTOINCREMENT, UserId INTEGER NOT NULL, Total REAL NOT NULL, OrderDate TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (UserId) REFERENCES Users(Id))"
# Create backup table
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "CREATE TABLE Users_backup AS SELECT * FROM Users"
# Create filtered copy
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "CREATE TABLE ActiveUsers AS SELECT * FROM Users WHERE active = 1"
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "CREATE TABLE IF NOT EXISTS Settings (Key TEXT PRIMARY KEY, Value TEXT)"
# Single column index
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "CREATE INDEX idx_users_email ON Users(Email)"
# Multi-column index
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "CREATE INDEX idx_orders_user_date ON Orders(UserId, OrderDate)"
# Unique index
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "CREATE UNIQUE INDEX idx_users_username ON Users(Username)"
# Simple view
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "CREATE VIEW ActiveUsers AS SELECT Id, Name, Email FROM Users WHERE active = 1"
# Complex view with JOIN
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "CREATE VIEW UserOrders AS SELECT u.Name, o.Id as OrderId, o.Total, o.OrderDate FROM Users u JOIN Orders o ON u.Id = o.UserId"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# STEP 1: Export table schema (for reference)
DBCLI_CONNECTION="Data Source=app.db" dbcli -f table columns OldTable > OldTable_schema_${TIMESTAMP}.txt
# STEP 2: Export table data (SQL format)
DBCLI_CONNECTION="Data Source=app.db" dbcli export OldTable > OldTable_backup_${TIMESTAMP}.sql
# STEP 3: Create table copy (fastest recovery)
DBCLI_CONNECTION="Data Source=app.db" dbcli query "CREATE TABLE OldTable_copy_${TIMESTAMP} AS SELECT * FROM OldTable"
# STEP 4: Verify backup
DBCLI_CONNECTION="Data Source=app.db" dbcli query "SELECT COUNT(*) FROM OldTable"
DBCLI_CONNECTION="Data Source=app.db" dbcli query "SELECT COUNT(*) FROM OldTable_copy_${TIMESTAMP}"
# STEP 5: Drop table
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "DROP TABLE IF EXISTS OldTable"
echo "Table dropped. Backups: OldTable_backup_${TIMESTAMP}.sql, OldTable_copy_${TIMESTAMP}"
# Document index before dropping
DBCLI_CONNECTION="Data Source=app.db" dbcli query "SELECT sql FROM sqlite_master WHERE type='index' AND name='idx_old_index'" > idx_old_index_definition.sql
# Drop index
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "DROP INDEX IF EXISTS idx_old_index"
# Export view definition
DBCLI_CONNECTION="Data Source=app.db" dbcli query "SELECT sql FROM sqlite_master WHERE type='view' AND name='OldView'" > OldView_definition.sql
# Drop view
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "DROP VIEW IF EXISTS OldView"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# STEP 1: Full table backup (data + schema)
DBCLI_CONNECTION="Data Source=app.db" dbcli export Users > Users_backup_${TIMESTAMP}.sql
DBCLI_CONNECTION="Data Source=app.db" dbcli query "CREATE TABLE Users_copy_${TIMESTAMP} AS SELECT * FROM Users"
# STEP 2: Verify backup
DBCLI_CONNECTION="Data Source=app.db" dbcli query "SELECT COUNT(*) FROM Users"
DBCLI_CONNECTION="Data Source=app.db" dbcli query "SELECT COUNT(*) FROM Users_copy_${TIMESTAMP}"
# STEP 3: Execute ALTER
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "ALTER TABLE Users ADD COLUMN PhoneNumber TEXT"
# STEP 4: Verify structure
DBCLI_CONNECTION="Data Source=app.db" dbcli -f table columns Users
# Backup first
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
DBCLI_CONNECTION="Data Source=app.db" dbcli export Users > Users_backup_${TIMESTAMP}.sql
# Add column
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "ALTER TABLE Users ADD COLUMN Age INTEGER"
# Add column with default
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "ALTER TABLE Users ADD COLUMN Status TEXT DEFAULT 'active'"
# CRITICAL: Full backup required
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
DBCLI_CONNECTION="Data Source=app.db" dbcli export Users > Users_backup_${TIMESTAMP}.sql
DBCLI_CONNECTION="Data Source=app.db" dbcli query "CREATE TABLE Users_copy_${TIMESTAMP} AS SELECT * FROM Users"
# Drop column (SQL Server syntax)
DBCLI_CONNECTION="Server=localhost;Database=mydb;Trusted_Connection=True" DBCLI_DBTYPE="sqlserver" dbcli ddl "ALTER TABLE Users DROP COLUMN TempColumn"
# Backup first
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
DBCLI_CONNECTION="Data Source=app.db" dbcli export OldName > OldName_backup_${TIMESTAMP}.sql
# Rename (SQLite syntax)
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "ALTER TABLE OldName RENAME TO NewName"
# Rename (SQL Server syntax)
DBCLI_CONNECTION="Server=localhost;Database=mydb;Trusted_Connection=True" DBCLI_DBTYPE="sqlserver" dbcli ddl "EXEC sp_rename 'OldName', 'NewName'"
# Backup first
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
DBCLI_CONNECTION="Data Source=app.db" dbcli export Users > Users_backup_${TIMESTAMP}.sql
# Rename column (SQLite 3.25+)
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "ALTER TABLE Users RENAME COLUMN OldColumnName TO NewColumnName"
# SQL Server
DBCLI_CONNECTION="Server=localhost;Database=mydb;Trusted_Connection=True" DBCLI_DBTYPE="sqlserver" dbcli ddl "EXEC sp_rename 'Users.OldColumnName', 'NewColumnName', 'COLUMN'"
# Create schema.sql
cat > schema.sql <<EOF
CREATE TABLE Users (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
Name TEXT NOT NULL,
Email TEXT UNIQUE,
CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE Orders (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
UserId INTEGER NOT NULL,
Total REAL NOT NULL,
OrderDate TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (UserId) REFERENCES Users(Id)
);
CREATE INDEX idx_users_email ON Users(Email);
CREATE INDEX idx_orders_user ON Orders(UserId);
EOF
# Execute schema
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl -F schema.sql
# migrations/001_create_users.sql
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl -F migrations/001_create_users.sql
# migrations/002_add_orders.sql
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl -F migrations/002_add_orders.sql
# migrations/003_add_indexes.sql
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl -F migrations/003_add_indexes.sql
# Create table
DBCLI_CONNECTION="Server=localhost;User Id=SYSDBA;PWD=xxxxxxxxxx;DATABASE=mydb" DBCLI_DBTYPE="dm" dbcli ddl "CREATE TABLE dm_test (id INT PRIMARY KEY, name VARCHAR(100), create_time TIMESTAMP)"
# Create index
DBCLI_CONNECTION="Server=localhost;User Id=SYSDBA;PWD=xxxxxxxxxx;DATABASE=mydb" DBCLI_DBTYPE="dm" dbcli ddl "CREATE INDEX idx_dm_test_name ON dm_test(name)"
# Create view
DBCLI_CONNECTION="Server=localhost;User Id=SYSDBA;PWD=xxxxxxxxxx;DATABASE=mydb" DBCLI_DBTYPE="dm" dbcli ddl "CREATE VIEW v_dm_test AS SELECT id, name FROM dm_test WHERE id > 0"
# Create table with sequence
DBCLI_CONNECTION="Host=localhost;Port=8000;Database=mydb;Username=gaussdb;Password=xxxxxxxxxx" DBCLI_DBTYPE="gaussdb" dbcli ddl "CREATE TABLE gauss_test (id SERIAL PRIMARY KEY, name VARCHAR(100), amount DECIMAL(10,2))"
# Create index
DBCLI_CONNECTION="Host=localhost;Port=8000;Database=mydb;Username=gaussdb;Password=xxxxxxxxxx" DBCLI_DBTYPE="gaussdb" dbcli ddl "CREATE INDEX idx_gauss_test_name ON gauss_test(name)"
# Create function (PL/pgSQL)
DBCLI_CONNECTION="Host=localhost;Port=8000;Database=mydb;Username=gaussdb;Password=xxxxxxxxxx" DBCLI_DBTYPE="gaussdb" dbcli ddl "CREATE OR REPLACE FUNCTION get_total() RETURNS DECIMAL AS \$\$ BEGIN RETURN (SELECT SUM(amount) FROM gauss_test); END; \$\$ LANGUAGE plpgsql"
# Create table
DBCLI_CONNECTION="Server=localhost;Port=54321;UID=system;PWD=xxxxxxxxxx;database=mydb" DBCLI_DBTYPE="kdbndp" dbcli ddl "CREATE TABLE kingbase_test (id SERIAL PRIMARY KEY, name VARCHAR(100), price NUMERIC(10,2))"
# Create view
DBCLI_CONNECTION="Server=localhost;Port=54321;UID=system;PWD=xxxxxxxxxx;database=mydb" DBCLI_DBTYPE="kdbndp" dbcli ddl "CREATE VIEW v_kingbase_active AS SELECT * FROM kingbase_test WHERE status = 1"
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "CREATE TABLE UserRoles (UserId INTEGER NOT NULL, RoleId INTEGER NOT NULL, AssignedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (UserId, RoleId))"
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "CREATE TABLE Products (Id INTEGER PRIMARY KEY, Name TEXT NOT NULL, Price REAL CHECK(Price > 0), Stock INTEGER CHECK(Stock >= 0))"
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "CREATE TRIGGER update_timestamp AFTER UPDATE ON Users BEGIN UPDATE Users SET UpdatedAt = datetime('now') WHERE Id = NEW.Id; END"
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "CREATE INDEX idx_active_users ON Users(Email) WHERE active = 1"
# From table copy
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "CREATE TABLE Users AS SELECT * FROM Users_copy_20250127_143022"
# From SQL export
DBCLI_CONNECTION="Data Source=app.db" dbcli exec -F Users_backup_20250127_143022.sql
# Re-create from saved definition
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl -F idx_users_email_definition.sql
# Drop altered table
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "DROP TABLE Users"
# Restore from backup
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "CREATE TABLE Users AS SELECT * FROM Users_copy_20250127_143022"
# SQLite
DBCLI_CONNECTION="Data Source=app.db" dbcli query "SELECT name FROM sqlite_master WHERE type='table' AND name='Users'"
# SQL Server
DBCLI_CONNECTION="Server=localhost;Database=mydb;Trusted_Connection=True" DBCLI_DBTYPE="sqlserver" dbcli query "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Users'"
# SQLite
DBCLI_CONNECTION="Data Source=app.db" dbcli query "PRAGMA table_info(Users)"
# SQL Server
DBCLI_CONNECTION="Server=localhost;Database=mydb;Trusted_Connection=True" DBCLI_DBTYPE="sqlserver" dbcli query "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'Users' AND COLUMN_NAME = 'Email'"
# SQLite
DBCLI_CONNECTION="Data Source=app.db" dbcli query "SELECT name FROM sqlite_master WHERE type='index' AND tbl_name='Users' AND name='idx_users_email'"
# Drop if exists, then create
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "DROP TABLE IF EXISTS TempTable"
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "CREATE TABLE TempTable (Id INTEGER PRIMARY KEY, Data TEXT)"
# Create if not exists
DBCLI_CONNECTION="Data Source=app.db" dbcli ddl "CREATE TABLE IF NOT EXISTS Settings (Key TEXT PRIMARY KEY, Value TEXT)"
#!/bin/bash
# init_db.sh
CONNECTION="Data Source=app.db"
# Create tables
DBCLI_CONNECTION="$CONNECTION" dbcli ddl -F schema/001_users.sql
DBCLI_CONNECTION="$CONNECTION" dbcli ddl -F schema/002_orders.sql
DBCLI_CONNECTION="$CONNECTION" dbcli ddl -F schema/003_products.sql
# Create indexes
DBCLI_CONNECTION="$CONNECTION" dbcli ddl -F schema/004_indexes.sql
# Create views
DBCLI_CONNECTION="$CONNECTION" dbcli ddl -F schema/005_views.sql
echo "Database initialized"
#!/bin/bash
# migrate.sh
CONNECTION="Data Source=app.db"
BACKUP_DIR="backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# Backup entire database
cp app.db "${BACKUP_DIR}/app_${TIMESTAMP}.db"
# Run migrations
for migration in migrations/*.sql; do
echo "Running $migration..."
DBCLI_CONNECTION="$CONNECTION" dbcli ddl -F "$migration"
if [ $? -ne 0 ]; then
echo "Migration failed: $migration"
echo "Restoring from backup..."
cp "${BACKUP_DIR}/app_${TIMESTAMP}.db" app.db
exit 1
fi
done
echo "All migrations completed successfully"
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer