Skip to Content
# SQL 查询 API 技术文档 ## 概述 本文档描述了 BI 工具中 SQL 查询 API 的设计与实现方案。该 API 允许用户通过自定义 SQL 查询数据库并将结果用于图表渲染。 ## API 规格 ### 端点信息 - **方法**: POST - **路径**: `/api/sql-query` - **功能**: 执行 SQL 查询并返回结果 ### 请求格式 ```typescript interface SqlQueryRequest { sql: string; // SQL查询语句 } ``` ### 响应格式 遵循项目标准响应结构: ```typescript interface ApiResponse<T> { success: boolean; data?: T; error?: { code: string; message: string; }; } ``` 查询结果将以 TableData 数组形式返回: ```typescript interface TableData { [key: string]: string | number | boolean | null; } // 成功响应示例 { "success": true, "data": [ { "id": 1, "name": "产品A", "sales": 1200 }, { "id": 2, "name": "产品B", "sales": 1500 } ] } ``` ## 实现方案 ### 1. 数据库配置 使用 Prisma 作为 ORM 工具连接 PostgreSQL 数据库: 1. 环境变量配置(.env 文件): ``` DATABASE_URL="postgresql://username:password@localhost:5432/database_name" ``` 2. Prisma 配置(prisma/schema.prisma): ```prisma datasource db { provider = "postgresql" url = env("DATABASE_URL") } generator client { provider = "prisma-client-js" } // 后续根据实际需求定义数据模型 ``` ### 2. API 路由实现 按照项目标准,实现 API 路由: ```typescript // app/api/sql-query/route.ts import { NextRequest } from "next/server"; import { PrismaClient } from "@prisma/client"; import { createSuccessResponse, withErrorHandling } from "@/lib/error-wrapper"; const prisma = new PrismaClient(); async function handlePost(req: NextRequest) { const body = await req.json(); const { sql } = body; // 执行原始SQL查询 const results = await prisma.$queryRawUnsafe(sql); // 返回标准响应 return createSuccessResponse({ message: "查询成功", data: results, }); } export const POST = withErrorHandling(handlePost); ``` ### 3. API 客户端实现 在前端创建 API 客户端模块: ```typescript // api-clients/sql-client.ts import { api, ApiResponse } from "@/lib/api-client"; import { TableData } from "@/components/charts/types"; /** * SQL查询客户端 */ export const sqlClient = { /** * 执行SQL查询 * @param sql SQL查询语句 * @returns 查询结果 */ executeQuery: async (sql: string): Promise<ApiResponse<TableData[]>> => { return api.post<TableData[]>("/api/sql-query", { sql }); }, }; ``` ### 4. 前端组件集成示例 ```typescript "use client"; import { useState } from "react"; import { sqlClient } from "@/api-clients/sql-client"; import { TableData } from "@/components/charts/types"; import { toast } from "sonner"; export function SqlQueryComponent() { const [query, setQuery] = useState(""); const [results, setResults] = useState<TableData[]>([]); const [loading, setLoading] = useState(false); const handleExecuteQuery = async () => { setLoading(true); try { const response = await sqlClient.executeQuery(query); if (response.success && response.data) { setResults(response.data); toast.success("查询成功"); } else { toast.error("查询失败", { description: response.error?.message || "未知错误", }); } } finally { setLoading(false); } }; // 组件渲染... } ```
Last updated on