SQL API Reference
v1.1.19+
The SQL API lets you execute custom SQL queries configured on the Lovrabet platform.
ℹ️ Version requirement This feature requires SDK v1.1.19 or later.
💡 New to custom SQL? If this is your first time using custom SQL, start with the Custom SQL tutorial — this document is a pure API reference.
When to Use the SQL API
| Scenario | Recommended API |
|---|---|
| Simple CRUD operations | Dataset API |
| Cross-table joins | SQL API ✅ |
| Complex aggregate statistics | SQL API ✅ |
| Custom reports | SQL API ✅ |
API Methods
execute() - recommended v1.2.0+
Use the client.sql namespace to execute SQL queries.
Method Signature
client.sql.execute<T>({ sqlCode, params }: SqlExecuteParams): Promise<SqlExecuteResult<T>>
client.sql.execute<T>(sqlCode: string | number, params?: Record<string, any>): Promise<SqlExecuteResult<T>>Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
sqlCode | string | number | ✅ | SQL code, in the format "xxxxx-xxxxx" or a numeric ID |
params | Record<string, any> | ❌ | SQL parameter object for parameterized queries |
Return Value
interface SqlExecuteResult<T> {
execSuccess: boolean; // SQL 执行是否成功
execResult?: T[]; // 查询结果数组(仅成功时存在)
}⚠️ Important The SDK returns an object containing
execSuccessandexecResult— not a plain array.
Your application must check execSuccess before using execResult.
executeSql() - legacy style
Uses the client.api namespace (kept for backward compatibility; not recommended).
client.api.executeSql<T>(sqlCode: string | number, params?: Record<string, any>): Promise<SqlExecuteResult<T>>Quick Start
Basic Usage (recommended)
import { createClient, sqlSafe } from "@lovrabet/sdk";
// 1. 创建客户端
const client = createClient({
accessKey process.env.LOVRABET_ACCESS_KEY,
appCode: "your-app-code",
});
// 2. 执行 SQL - 使用 sqlSafe 语法糖(推荐)
const { data, error } = await sqlSafe(() =>
client.sql.execute({ sqlCode: "xxxxx-xxxxx" })
);
// 3. 处理结果(一次检查)
if (error) {
console.error("查询失败:", error.message);
return;
}
// data 直接是查询结果数组
console.log(`查询成功,返回 ${data.length} 条数据`);
data.forEach((row) => console.log(row));Legacy Style (not recommended)
// 不使用 sqlSafe:需要手动检查 execSuccess
const result = await client.sql.execute({ sqlCode: "xxxxx-xxxxx" });
if (result.execSuccess && result.execResult) {
console.log(`查询成功,返回 ${result.execResult.length} 条数据`);
result.execResult.forEach((row) => console.log(row));
} else {
console.error("SQL 执行失败");
}Parameterized Queries
// SQL 中使用 #{paramName} 定义参数
// 例如:SELECT * FROM users WHERE id = #{userId} AND status = #{status}
// 推荐方式:对象参数
const result = await client.sql.execute({
sqlCode: "xxxxx-xxxxx",
params: {
userId: 123,
status: "active",
}
});
// 或直接传参
const result = await client.sql.execute("xxxxx-xxxxx", {
userId: 123,
status: "active",
});
if (result.execSuccess && result.execResult) {
console.log("查询结果:", result.execResult);
}TypeScript Support
// 定义结果类型
interface UserStat {
id: number;
name: string;
login_count: number;
}
// 使用 sqlSafe + 泛型
const { data, error } = await sqlSafe<UserStat>(() =>
client.sql.execute({ sqlCode: "xxxxx-xxxxx" })
);
if (error) {
console.error("查询失败:", error.message);
return;
}
// data 是 UserStat[],类型安全
data.forEach((user) => {
console.log(`${user.name}: ${user.login_count} 次登录`);
});Error Handling
With sqlSafe (recommended)
import { sqlSafe } from "@lovrabet/sdk";
// 一次检查处理所有错误
const { data, error } = await sqlSafe(() =>
client.sql.execute({ sqlCode: "xxxxx-xxxxx" })
);
if (error) {
// 区分错误类型
if (error.code === 'SQL_ERROR') {
// 业务逻辑失败(execSuccess = false)
console.error('SQL 执行失败:', error.cause);
} else {
// HTTP 错误(404、500 等)
console.error('请求失败:', error.message, error.status);
}
return;
}
// data 直接是查询结果数组
console.log(`查询到 ${data.length} 条记录`);Distinguishing Error Types
const { data, error } = await sqlSafe(() =>
client.sql.execute({ sqlCode: 'user-stats' })
);
if (error) {
// 业务错误:execSuccess = false
if (error.code === 'SQL_ERROR') {
const originalResult = error.cause; // 原始 SqlExecuteResult
console.error('业务失败:', originalResult);
}
// HTTP 错误:404、500 等
else if (error.status) {
console.error('HTTP 错误:', error.status, error.message);
}
// 其他错误
else {
console.error('未知错误:', error.message);
}
return;
}
// 使用数据
data.forEach(row => console.log(row));Common Error Codes
| Code | Description | Fix |
|---|---|---|
| 401 | Authentication failed | Check your AccessKey or log in again |
| 404 | SQL not found | Check that the SQL code is correct |
| 500 | Server error | Retry later or contact support |
FAQ
Why is execSuccess false?
execSuccess: false means the SQL failed to execute on the platform. Common causes:
- SQL syntax errors
- A referenced table or column doesn't exist
- Wrong SQL parameters or mismatched types
- Database connection issues
Fix: Test the SQL on the platform's custom SQL management page first to confirm it runs.
How do I debug SQL queries?
Enable SDK debug mode:
const client = createClient({
appCode: "your-app",
accessKey: process.env.ACCESS_KEY,
options: {
debug: true, // 启用调试日志
},
});How do I handle large datasets?
- Use LIMIT in the SQL
- Use pagination parameters
- Use background jobs: for heavy data processing, prefer a scheduled task over a real-time query
Which SQL operations are supported?
- ✅ SELECT queries: fully supported
- ⚠️ UPDATE/DELETE: partially supported (requires admin permission configuration)
- ❌ INSERT: not recommended (use the Dataset API)
- ❌ DDL operations: not supported (CREATE/DROP TABLE, etc.)
Differences in Backend Functions
If you run SQL inside a Backend Function (BFF) on the Lovrabet platform, the return structure differs from the frontend SDK:
Return Value Comparison
| Environment | Call | Return value | How to get the data |
|---|---|---|---|
| Frontend SDK | client.sql.execute() | { execSuccess, execResult } | Check execSuccess, read from execResult |
| Backend Function | context.client.sql.execute() | A plain array [{ col: val }, ...] | Use the result directly; no execResult field |
Backend Function Example
// BFF 环境中
export default async function myEndpoint(params, context) {
// 直接返回数组,无需检查 execSuccess
const rows = await context.client.sql.execute({
sqlCode: "user-stats",
params: { userId: params.userId }
});
// rows 就是查询结果数组
return { data: rows };
}⚠️ Mind the difference There is no
execResultfield in BFF — the following pattern is wrong:
Error Handling
Frontend SDK: check execSuccess or use sqlSafe
const result = await client.sql.execute({ sqlCode: 'xxx' });
if (!result.execSuccess) {
throw new Error('查询失败');
}Backend Function: failures throw directly — catch them with try-catch
try {
const rows = await context.client.sql.execute({ sqlCode: 'xxx' });
return { data: rows };
} catch (error) {
throw new Error(`查询失败: ${error.message}`);
}Related Documentation
- Custom SQL tutorial - a complete step-by-step tutorial
- Quick start - SDK installation and configuration
- Authentication - the three auth modes in depth
- API guide - Dataset API reference
- Troubleshooting - fixes for common issues
Last updated: 2025-11-12