agentsclimarketplace

Sap hana tools

Skill efeumutaslan/SAP-SKILLS/skills/sap-hana-tools

23 SAP development skills for Claude Code — ABAP, RAP, CAP, Fiori, BTP, HANA, S/4HANA, Integration Suite and more. Agent Skills Specification compatible.

Install
npx -y skills add efeumutaslan/SAP-SKILLS --skill sap-hana-tools

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

SAP HANA developer tooling and CLI skill. Use when working with hdbsql CLI, managing HDI containers, using HANA Database Explorer, or automating HANA operations. If the user mentions hdbsql, HDI container management, HANA Cloud Central, or HANA client tools, use this skill. Extends sap-hana-cloud with operational tooling focus.

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

11.3 KB, as published. Nobody here has run it

SAP HANA Developer Tools & CLI

Related Skills

  • sap-hana-cloud — HANA Cloud database development (SQL, HDI, multi-model)
  • sap-devops-cicd — HANA artifact deployment in CI/CD pipelines
  • sap-cap-advanced — CAP projects with HANA Cloud persistence

Quick Start

Key tools:

ToolPurposeInstall
hdbsqlInteractive SQL clientSAP HANA Client package
hdbuserstoreSecure credential storeSAP HANA Client package
@sap/hdi-deployHDI container deployernpm install @sap/hdi-deploy
HANA Database ExplorerWeb-based SQL editorBTP cockpit → HANA Cloud
HANA Cloud CentralInstance managementBTP cockpit
@sap/hana-clientNode.js HANA drivernpm install @sap/hana-client

Connect with hdbsql:

# Store credentials securely
hdbuserstore SET HANACLOUD <host>:443 <user> <password>

# Connect and run query
hdbsql -U HANACLOUD "SELECT * FROM M_DATABASE"

# Connect directly
hdbsql -n <host>:443 -u <user> -p <password> -encrypt

Core Concepts

HDI Container Lifecycle (CLI)

# HDI deploy from command line (CI/CD)
npx @sap/hdi-deploy \
  --service-replacements '{"hdi-container":"my-hdi-service-key"}' \
  --deploy '["src/**"]' \
  --undeploy '["src/old_table.hdbtable"]'

# Environment variables for HDI deploy
export HDI_DEPLOY_OPTIONS='{"auto_undeploy":false,"treat_warnings_as_errors":true}'

Connection Methods

MethodUse CaseSecurity
hdbuserstorePersistent, scripted accessEncrypted local store
Direct paramsOne-off queriesPassword on command line (avoid in prod)
JWT tokenBTP app authShort-lived, OAuth 2.0
X.509 certificateService-to-serviceMutual TLS
Service key (JSON)BTP service bindingFrom BTP cockpit

hdbsql Output Formats

# CSV output (for data export)
hdbsql -U HANACLOUD -o output.csv -c "," -a "SELECT * FROM MY_TABLE"

# JSON output (pipe to jq)
hdbsql -U HANACLOUD -j "SELECT TOP 10 * FROM M_SQL_PLAN_CACHE ORDER BY total_execution_time DESC"

# Aligned column output (human-readable)
hdbsql -U HANACLOUD -A "SELECT * FROM M_SERVICE_MEMORY"

Common Patterns

Pattern 1: HANA Health Check Script

#!/bin/bash
# hana_health_check.sh — Daily HANA Cloud health report

STORE_KEY="HANACLOUD"

echo "=== HANA Cloud Health Check $(date) ==="

echo -e "\n--- Database Info ---"
hdbsql -U $STORE_KEY -j "SELECT DATABASE_NAME, VERSION, USAGE FROM M_DATABASE"

echo -e "\n--- Memory Usage ---"
hdbsql -U $STORE_KEY -A "
  SELECT HOST,
         ROUND(USED_PHYSICAL_MEMORY/1024/1024/1024, 2) AS USED_GB,
         ROUND(FREE_PHYSICAL_MEMORY/1024/1024/1024, 2) AS FREE_GB,
         ROUND(USED_PHYSICAL_MEMORY * 100.0 / (USED_PHYSICAL_MEMORY + FREE_PHYSICAL_MEMORY), 1) AS USED_PCT
  FROM M_HOST_RESOURCE_UTILIZATION"

echo -e "\n--- Top 5 Expensive Queries (Last 24h) ---"
hdbsql -U $STORE_KEY -A "
  SELECT TOP 5
    SUBSTRING(STATEMENT_STRING, 1, 80) AS QUERY,
    ROUND(DURATION_MICROSEC/1000000, 2) AS DURATION_SEC,
    RECORDS AS ROWS_AFFECTED
  FROM M_EXPENSIVE_STATEMENTS
  WHERE START_TIME > ADD_SECONDS(CURRENT_TIMESTAMP, -86400)
  ORDER BY DURATION_MICROSEC DESC"

echo -e "\n--- Active Connections ---"
hdbsql -U $STORE_KEY -A "
  SELECT CONNECTION_STATUS, COUNT(*) AS CNT
  FROM M_CONNECTIONS
  GROUP BY CONNECTION_STATUS"

echo -e "\n--- Table Growth (Top 10 by size) ---"
hdbsql -U $STORE_KEY -A "
  SELECT TOP 10
    SCHEMA_NAME, TABLE_NAME,
    ROUND(TABLE_SIZE/1024/1024, 2) AS SIZE_MB,
    RECORD_COUNT
  FROM M_CS_TABLES
  ORDER BY TABLE_SIZE DESC"

Pattern 2: Node.js HANA Client

const hana = require('@sap/hana-client');

class HANAConnection {
  constructor(serviceKey) {
    this.connParams = {
      host: serviceKey.host,
      port: serviceKey.port,
      uid: serviceKey.user,
      pwd: serviceKey.password,
      encrypt: true,
      sslValidateCertificate: true
    };
  }

  async query(sql, params = []) {
    const conn = hana.createConnection();
    try {
      await new Promise((resolve, reject) =>
        conn.connect(this.connParams, (err) => err ? reject(err) : resolve())
      );
      return await new Promise((resolve, reject) =>
        conn.exec(sql, params, (err, result) => err ? reject(err) : resolve(result))
      );
    } finally {
      conn.disconnect();
    }
  }

  async streamLargeResult(sql, params, onRow) {
    const conn = hana.createConnection();
    await new Promise((resolve, reject) =>
      conn.connect(this.connParams, (err) => err ? reject(err) : resolve())
    );
    const stmt = conn.prepare(sql);
    const rs = stmt.execQuery(params);
    while (rs.next()) {
      await onRow(rs.getValues());
    }
    rs.close();
    stmt.drop();
    conn.disconnect();
  }
}

// Usage
const db = new HANAConnection(JSON.parse(process.env.HANA_SERVICE_KEY));
const results = await db.query(
  'SELECT * FROM ORDERS WHERE CUSTOMER_ID = ? AND ORDER_DATE > ?',
  ['CUST001', '2026-01-01']
);

Pattern 3: HDI Container Management Script

#!/bin/bash
# Manage HDI containers for multi-tenant scenario

SERVICE_INSTANCE="my-hdi-shared"

# List all HDI containers
cf service-keys $SERVICE_INSTANCE | grep -E "^name"

# Create tenant-specific container
create_tenant_container() {
  local TENANT_ID=$1
  local CONTAINER_NAME="hdi-${TENANT_ID}"

  cf create-service-key $SERVICE_INSTANCE $CONTAINER_NAME \
    -c "{\"permissions\":\"development\"}"

  # Get connection details
  cf service-key $SERVICE_INSTANCE $CONTAINER_NAME | tail -n +2 > /tmp/${CONTAINER_NAME}.json

  # Deploy schema to new container
  HDI_SERVICE_KEY=$(cat /tmp/${CONTAINER_NAME}.json)
  npx @sap/hdi-deploy --service-replacements "[{\"key\":\"hdi-container\",\"service\":\"$HDI_SERVICE_KEY\"}]"
}

# Delete tenant container
delete_tenant_container() {
  local TENANT_ID=$1
  cf delete-service-key $SERVICE_INSTANCE "hdi-${TENANT_ID}" -f
}

Pattern 4: Performance Analysis Queries

-- Find slow queries in plan cache
SELECT TOP 20
  STATEMENT_HASH,
  EXECUTION_COUNT,
  ROUND(TOTAL_EXECUTION_TIME/1000000, 2) AS TOTAL_SEC,
  ROUND(AVG_EXECUTION_TIME/1000000, 2) AS AVG_SEC,
  ROUND(MAX_EXECUTION_TIME/1000000, 2) AS MAX_SEC,
  TOTAL_LOCK_WAIT_COUNT,
  SUBSTR(STATEMENT_STRING, 1, 100) AS QUERY_PREVIEW
FROM M_SQL_PLAN_CACHE
WHERE EXECUTION_COUNT > 10
ORDER BY AVG_EXECUTION_TIME DESC;

-- Table column memory consumption
SELECT SCHEMA_NAME, TABLE_NAME, COLUMN_NAME,
       ROUND(MEMORY_SIZE_IN_TOTAL/1024/1024, 2) AS TOTAL_MB,
       ROUND(PERSISTENT_MEMORY_SIZE_IN_TOTAL/1024/1024, 2) AS DISK_MB,
       LOADED AS IS_LOADED
FROM M_CS_COLUMNS
WHERE SCHEMA_NAME = 'MY_SCHEMA'
ORDER BY MEMORY_SIZE_IN_TOTAL DESC;

-- Index advisor suggestions
SELECT * FROM M_CS_INDEXES_ADVISOR
WHERE SCHEMA_NAME = 'MY_SCHEMA'
ORDER BY ESTIMATED_BENEFIT DESC;

-- Check delta merge status
SELECT SCHEMA_NAME, TABLE_NAME, PART_ID,
       RAW_RECORD_COUNT_IN_DELTA AS DELTA_ROWS,
       RAW_RECORD_COUNT_IN_MAIN AS MAIN_ROWS,
       ROUND(RAW_RECORD_COUNT_IN_DELTA * 100.0 /
         NULLIF(RAW_RECORD_COUNT_IN_MAIN + RAW_RECORD_COUNT_IN_DELTA, 0), 1) AS DELTA_PCT
FROM M_CS_TABLES
WHERE RAW_RECORD_COUNT_IN_DELTA > 100000
ORDER BY RAW_RECORD_COUNT_IN_DELTA DESC;

Pattern 5: Python HANA Client (hdbcli)

from hdbcli import dbapi
import json

def connect_from_service_key(key_path):
    """Connect using BTP service key JSON."""
    with open(key_path) as f:
        key = json.load(f)
    return dbapi.connect(
        address=key["host"],
        port=key["port"],
        user=key["user"],
        password=key["password"],
        encrypt=True
    )

def export_to_csv(conn, sql, output_path):
    """Export query results to CSV."""
    import csv
    cursor = conn.cursor()
    cursor.execute(sql)
    columns = [desc[0] for desc in cursor.description]
    with open(output_path, 'w', newline='') as f:
        writer = csv.writer(f)
        writer.writerow(columns)
        while True:
            rows = cursor.fetchmany(10000)
            if not rows:
                break
            writer.writerows(rows)
    cursor.close()

def bulk_insert(conn, table_name, data, batch_size=5000):
    """Efficient bulk insert with parameterized batches."""
    if not data:
        return
    columns = list(data[0].keys())
    placeholders = ','.join(['?' for _ in columns])
    sql = f"INSERT INTO {table_name} ({','.join(columns)}) VALUES ({placeholders})"

    cursor = conn.cursor()
    for i in range(0, len(data), batch_size):
        batch = data[i:i+batch_size]
        params = [tuple(row[c] for c in columns) for row in batch]
        cursor.executemany(sql, params)
    conn.commit()
    cursor.close()

Error Catalog

ErrorMessageRoot CauseFix
hdbsql: -10709Connection failedWrong host/port or network issueCheck host:443 (HANA Cloud always uses 443)
hdbsql: -10104Invalid credentialsWrong user/passwordReset password; check hdbuserstore entry
hdbsql: -10Encryption requiredMissing -encrypt flagAdd -encrypt or encrypt=true
hdi-deploy: 403Insufficient privilegeMissing HDI admin roleGrant HDI container admin to technical user
hdi-deploy: Build failedArtifact compilation errorInvalid HDB artifact syntaxCheck .hdbcds/.hdbprocedure syntax
npm: @sap/hana-clientInstall failed (native module)Missing C++ build toolsInstall node-gyp prereqs; use prebuild binary
SQLCODE -131Transaction rolled backLock timeout during bulk insertReduce batch size; check for concurrent access
SQLCODE -10001SQL syntax errorHANA SQL ≠ ANSI SQLCheck HANA-specific syntax (e.g., TOP N not LIMIT N)

Performance Tips

  1. Use hdbuserstore — Avoid passwords in scripts; hdbuserstore is encrypted and reusable
  2. Batch size for hdbsql — Use -B (batch mode) for non-interactive execution in CI/CD
  3. Parameterized queries — Always use ? placeholders; prevents SQL injection and enables plan reuse
  4. Connection pooling — In Node.js/Python apps, reuse connections; don't connect per query
  5. hdbsql -j for JSON — JSON output is parse-friendly for automation scripts
  6. HDI deploy incremental — Only deploy changed files; use --deploy with specific file paths
  7. Export large datasets — Use hdbsql -o with CSV format for data export instead of SELECT in app code

Gotchas

  • HANA Cloud port: Always 443 (not 30015/30013 like on-premise)
  • hdbsql LIMIT: HANA uses SELECT TOP N not LIMIT N (though recent versions support both)
  • Node.js driver versions: @sap/hana-client (native, faster) vs hdb (pure JS, slower but no native deps)
  • hdbuserstore scope: Keys are per-OS-user; CI/CD needs its own userstore setup
  • SSL certificates: HANA Cloud uses DigiCert root CA; ensure it's in your trust store
  • Time zone: HANA Cloud always runs in UTC; convert in queries with UTCTOLOCAL()

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.