From 915950949d9d89d0987cccf8f2460b2d795f8d41 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 21 Oct 2025 08:14:12 +0000 Subject: [PATCH 1/3] [INIT] Start translation to Simplified-Chinese --- .translation-init | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.translation-init b/.translation-init index 12cb9eb887..4b2a0a4619 100644 --- a/.translation-init +++ b/.translation-init @@ -1 +1 @@ -Translation initialization: 2025-10-20T12:06:14.189361 +Translation initialization: 2025-10-21T08:14:11.718396 From fbaa613c33cdf5d8e0e49e205653b58ccd2a54eb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 21 Oct 2025 08:16:37 +0000 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=8C=90=20Translate=2098-sql-scripting?= =?UTF-8?q?.md=20to=20Simplified-Chinese?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../00-sql-reference/98-sql-scripting.md | 456 +++++++++++++++--- 1 file changed, 395 insertions(+), 61 deletions(-) diff --git a/docs/cn/sql-reference/00-sql-reference/98-sql-scripting.md b/docs/cn/sql-reference/00-sql-reference/98-sql-scripting.md index 12130bf334..39090f4818 100644 --- a/docs/cn/sql-reference/00-sql-reference/98-sql-scripting.md +++ b/docs/cn/sql-reference/00-sql-reference/98-sql-scripting.md @@ -4,105 +4,439 @@ title: SQL 脚本 本页面概述了 Databend 中可用的 SQL 脚本选项。你可以通过以下任一查询方法使用 SQL 脚本: -- [存储过程 (Stored Procedure)](/sql/sql-commands/ddl/procedure/create-procedure) +- [存储过程(Stored Procedure)](/sql/sql-commands/ddl/procedure/create-procedure) - [EXECUTE IMMEDIATE](/sql/sql-commands/administration-cmds/execute-immediate) -### 变量声明 +:::note +要使用存储过程,你需要启用实验性功能: +```sql +SET global enable_experimental_procedure=1; +``` +::: + +## 变量声明 -可以使用 `LET` 关键字声明变量,后跟变量名、可选的类型和初始值。 +变量可以使用 `LET` 关键字声明,后跟变量名、可选的类型和初始值。 -```sql title='示例:' +```sql title='基本变量声明:' LET x := 100; +LET name := 'Alice'; +``` + +## 结果集变量 + +SQL 查询可以在脚本中执行,结果可以存储在变量或结果集(Result Set)中。 + +```sql title='结果集示例:' +-- 将查询结果存储在 RESULTSET 变量中 +LET employees RESULTSET := SELECT * FROM employee_table; + +-- 遍历结果集 +FOR emp IN employees DO + -- 处理每一行 + LET salary := emp.salary * 1.1; +END FOR; ``` -### 查询执行 +## 游标(Cursor) -SQL 查询可以在脚本中执行,结果可以存储在变量或结果集 (Result Set) 中。 +从 SQL 查询声明游标(Cursor) +```sql + LET c1 CURSOR FOR SELECT price FROM invoices; +``` + +从结果集声明游标(Cursor) +```sql + LET r1 RESULTSET := SELECT price FROM invoices; + LET c1 CURSOR for r1; +``` -```sql title='示例:' -LET result RESULTSET := SELECT * FROM t1; +打开游标(Cursor)并将数据提取到变量中 +```sql +LET c1 CURSOR FOR SELECT number from numbers(10); +OPEN c1; +LET price := 0; +FETCH c1 INTO price; +CLOSE c1; ``` -### 控制流结构 +遍历游标(Cursor) +```sql +LET c1 CURSOR FOR SELECT number from numbers(10); + +for price in c1 do + -- 处理每个数字 + select :price; +END FOR; +``` + +## 控制流结构 + +### FOR 循环 -- **FOR 循环**:遍历一个范围或结果集。 +遍历一个范围、结果集(Result Set)或游标(Cursor)。 - ```sql title='示例:' - FOR i IN 1..10 DO ... END FOR; - ``` +```sql title='FOR 循环示例:' +-- 基于范围的 FOR 循环 +FOR i IN 1 TO 10 DO + -- 处理每个数字 + INSERT INTO temp_table VALUES (:i, :i * 2); +END FOR; -- **WHILE 循环**:在指定条件为真时执行代码块。 +-- 结果集迭代 +LET data RESULTSET := SELECT number FROM numbers(5); +FOR r IN data DO + -- 访问 r.number + LET squared := r.number * r.number; +END FOR; +``` + +### WHILE 循环 - ```sql title='示例:' - WHILE condition DO ... END WHILE; - ``` +只要指定条件为真,就执行一个代码块。 + +```sql title='WHILE 循环示例:' +CREATE PROCEDURE fibonacci_sum(n INT) +RETURNS INT +LANGUAGE SQL +AS $$ +BEGIN + LET a := 0; + LET b := 1; + LET sum := 0; + LET i := 0; -- **REPEAT 循环**:执行代码块直到满足条件。 + WHILE i < n DO + sum := sum + a; + LET temp := a + b; + a := b; + b := temp; + i := i + 1; + END WHILE; + + RETURN sum; +END; +$$; +``` - ```sql title='示例:' - REPEAT ... UNTIL condition END REPEAT; - ``` +### REPEAT 循环 -- **LOOP**:无限期执行代码块,直到遇到 `BREAK` 语句。 +执行一个代码块,直到满足某个条件。 - ```sql title='示例:' - LOOP ... END LOOP; - ``` +```sql title='REPEAT 循环示例:' +LET counter := 0; +LET sum := 0; -- **CASE 语句**:允许根据不同条件有条件地执行代码块。 +REPEAT + counter := counter + 1; + sum := sum + counter; +UNTIL counter >= 5 END REPEAT; +``` - ```sql title='示例:' - CASE [operand] - WHEN condition1 THEN ... - WHEN condition2 THEN ... - ELSE ... - END; - ``` +### LOOP 与 BREAK -- **IF 语句**:根据条件执行代码块。 +无限期地执行一个代码块,直到遇到 `BREAK` 语句。 - ```sql title='示例:' - IF condition THEN ... - ELSEIF condition THEN ... - ELSE ... +```sql title='LOOP 示例:' +LET i := 0; +LOOP + i := i + 1; + IF i > 10 THEN + BREAK; END IF; - ``` + -- 在此处处理逻辑 +END LOOP; +``` -### RETURN +### IF 语句 + +根据条件执行一个代码块。 + +```sql title='IF 语句示例:' +-- 简单的 IF-ELSE +IF x > 100 THEN + LET result := 'High'; +ELSEIF x > 50 THEN + LET result := 'Medium'; +ELSE + LET result := 'Low'; +END IF; + +### CASE 语句 + +允许根据不同条件有条件地执行代码块。 + +```sql title='CASE 语句示例:' +CREATE PROCEDURE process_grade(score INT) +RETURNS STRING +LANGUAGE SQL +AS $$ +BEGIN + LET grade:= ''; + + CASE + WHEN score >= 90 THEN grade := 'A'; + WHEN score >= 80 THEN grade := 'B'; + WHEN score >= 70 THEN grade := 'C'; + WHEN score >= 60 THEN grade := 'D'; + ELSE grade := 'F'; + END CASE; + + RETURN grade; +END; +$$; +``` + + +## 存储过程示例 + +### 基本数学计算 + +```sql title='单位转换存储过程:' +CREATE PROCEDURE convert_kg_to_lb(kg INT) +RETURNS INT +LANGUAGE SQL +COMMENT = '将千克转换为磅' +AS $$ +BEGIN + RETURN kg * 2.20462; +END; +$$; + +-- 用法 +CALL PROCEDURE convert_kg_to_lb(70::Int); +``` + + +### 使用循环进行批处理 + +```sql title='批量数据处理:' +CREATE OR REPLACE PROCEDURE process_daily_sales() +RETURNS STRING NOT NULL +LANGUAGE SQL +AS $$ +BEGIN + LET sales_data RESULTSET := + SELECT product_id, SUM(quantity) as total_quantity, SUM(amount) as total_amount + FROM daily_sales + WHERE sale_date = today() + GROUP BY product_id; + + LET processed_count := 0; + + FOR sale IN sales_data DO + -- 更新产品统计信息 + LET total_quantity := sale.total_quantity; + LET total_amount := sale.total_amount; + LET product_id := sale.product_id; + UPDATE product_stats + SET + total_sold = total_sold + :total_quantity, + total_revenue = total_revenue + :total_amount, + last_updated = NOW() + WHERE product_id = :product_id; + + processed_count := processed_count + 1; + END FOR; + + -- 清理每日销售数据 + DELETE FROM daily_sales WHERE sale_date = today(); + + RETURN 'Processed ' || processed_count || ' products'; +END; +$$; +``` + +## EXECUTE IMMEDIATE -从脚本返回,并可选择性地附带一个值。 +`EXECUTE IMMEDIATE` 允许你运行 SQL 脚本块,而无需创建存储过程。 + +```sql title='基本的 EXECUTE IMMEDIATE:' +EXECUTE IMMEDIATE $$ +BEGIN + LET sum := 0; + FOR x IN SELECT number FROM numbers(10) DO + sum := sum + x.number; + END FOR; + RETURN sum; +END; +$$; +``` -```sql title='示例:' -RETURN [expr]; +如果脚本是单个语句,则结果与该语句的结果相同。 +```sql +EXECUTE IMMEDIATE 'select 1'; ``` +## 返回语句 + +### RETURN + +从脚本或存储过程中返回,可以带一个可选值。如果未指定值,则默认返回。 + +```sql title='RETURN 示例:' +-- 返回一个简单值 +RETURN 42; + +-- 返回一个计算值 +RETURN x * 2 + 10; + +-- 返回一个字符串 +RETURN 'Processing completed successfully'; + + ### RETURN TABLE -从脚本返回,并将表结果作为字符串列返回。 +从脚本返回一个表结果。这在 `EXECUTE IMMEDIATE` 块中特别有用。 -```sql title='示例:' +```sql title='RETURN TABLE 示例:' +-- 基本的表返回 EXECUTE IMMEDIATE $$ BEGIN CREATE OR REPLACE TABLE t1 (a INT, b FLOAT, c STRING); - INSERT INTO t1 VALUES (1, 2.0, '3'); - RETURN TABLE(select * from t1); + INSERT INTO t1 VALUES (1, 2.0, '3'), (4, 5.0, '6'); + RETURN TABLE(SELECT * FROM t1); +END; +$$; + +-- 动态创建表并返回 +EXECUTE IMMEDIATE $$ +BEGIN + -- 创建摘要表 + CREATE OR REPLACE TABLE monthly_summary ( + month STRING, + total_sales DECIMAL(15,2), + order_count INT + ); + + -- 使用聚合数据填充 + INSERT INTO monthly_summary + SELECT + DATE_FORMAT(order_date, '%Y-%m') as month, + SUM(total_amount) as total_sales, + COUNT(*) as order_count + FROM orders + WHERE order_date >= '2024-01-01' + GROUP BY DATE_FORMAT(order_date, '%Y-%m') + ORDER BY month; + + RETURN TABLE(SELECT * FROM monthly_summary); +END; +$$; +``` + +结果将显示为格式化的表格: + +``` +╭────────────────────────────────────────────────────────╮ +│ a │ b │ c │ +│ Nullable(Int32) │ Nullable(Float32) │ Nullable(String) │ +├─────────────────┼───────────────────┼──────────────────┤ +│ 1 │ 2 │ 3 │ +│ 4 │ 5 │ 6 │ +╰────────────────────────────────────────────────────────╯ +``` + +## 注释 + +SQL 脚本支持单行和多行注释: + +```sql title='注释示例:' +-- 单行注释 +LET x := 10; -- 这也是一个单行注释 + +/* +多行注释 +可以跨越多行 +*/ +LET y := /* 内联注释 */ 20; + +/* +支持嵌套注释: +/* 这是一个嵌套注释 */ +*/ +``` + +## 高级功能 + +### 变量作用域 + +变量具有块级作用域,并且可以在嵌套块中被遮蔽(shadowed): + +```sql title='变量作用域示例:' +CREATE PROCEDURE scope_demo() +RETURNS STRING +LANGUAGE SQL +AS $$ +BEGIN + LET x := 'outer'; + + IF TRUE THEN + LET x := 'inner'; -- 遮蔽外部的 x + -- 此处 x 是 'inner' + END IF; + + -- 此处 x 再次变为 'outer' + RETURN x; END; $$; +``` + +### 事务行为 + +存储过程在事务(Transaction)中运行,并支持出错时自动回滚: + +```sql title='事务示例:' +CREATE PROCEDURE transfer_with_log(from_id INT, to_id INT, amount DECIMAL(10,2)) +RETURNS STRING +LANGUAGE SQL +AS $$ +BEGIN + -- 所有操作都在同一个事务(Transaction)中 + UPDATE accounts SET balance = balance - amount WHERE id = from_id; + UPDATE accounts SET balance = balance + amount WHERE id = to_id; -┌─────────────────────────────────────────────┐ -│ 结果 │ -│ String │ -├─────────────────────────────────────────────┤ -│ ┌─────────────────────────────────────────┐ │ -│ │ a │ b │ c │ │ -│ │ Int32 NULL │ Float32 NULL │ String NULL │ │ -│ ├────────────┼──────────────┼─────────────┤ │ -│ │ 1 │ 2 │ '3' │ │ -│ └─────────────────────────────────────────┘ │ -└─────────────────────────────────────────────┘ + -- 记录事务 + INSERT INTO transaction_log (from_account, to_account, amount, timestamp) + VALUES (from_id, to_id, amount, NOW()); + + -- 如果任何操作失败,所有操作都会自动回滚 + RETURN 'Transfer completed'; +END; +$$; ``` -### 注释 +## 最佳实践 + +1. **使用有意义的变量名**:使用 `LET total_amount := 0;` 而不是 `LET x := 0;` + +2. **为复杂逻辑添加注释**: + ```sql + -- 按月计算复利 + FOR month IN 1 TO months DO + balance := balance * (1 + annual_rate / 12); + END FOR; + ``` + +3. **处理边界情况**: + ```sql + IF input_value IS NULL THEN + RETURN 'Invalid input: NULL value not allowed'; + END IF; + ``` + +4. **使用适当的返回类型**: + ```sql + CREATE PROCEDURE calculate_discount(amount DECIMAL(10,2)) + RETURNS DECIMAL(10,2) NOT NULL -- 在适当时指定 NOT NULL + ``` -- **单行注释**:`-- comment` -- **多行注释**:`/* comment */` \ No newline at end of file +5. **用清晰的段落组织复杂的存储过程**: + ```sql + BEGIN + -- 输入验证 + -- 业务逻辑 + -- 数据持久化 + -- 返回结果 + END; + ``` \ No newline at end of file From 9ee13cb15199584ae24dbaaa7b5ae83376320842 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 21 Oct 2025 08:19:07 +0000 Subject: [PATCH 3/3] =?UTF-8?q?=F0=9F=8C=90=20Translate=2098-sql-scripting?= =?UTF-8?q?.md=20to=20Simplified-Chinese?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../connect/connect-to-databend-bendsql.md | 39 +++++++++++-------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/docs/cn/tutorials/connect/connect-to-databend-bendsql.md b/docs/cn/tutorials/connect/connect-to-databend-bendsql.md index 1f72a0a2f6..10af51dc53 100644 --- a/docs/cn/tutorials/connect/connect-to-databend-bendsql.md +++ b/docs/cn/tutorials/connect/connect-to-databend-bendsql.md @@ -1,28 +1,28 @@ --- -title: "使用 BendSQL 连接到私有化部署 Databend" -sidebar_label: "连接到私有化部署 Databend (BendSQL)" +title: "使用 BendSQL 连接到自托管 Databend" +sidebar_label: "连接到自托管 Databend (BendSQL)" slug: / --- import StepsWrap from '@site/src/components/StepsWrap'; import StepContent from '@site/src/components/Steps/step-content'; -在本教程中,我们将指导您完成使用 BendSQL 连接到私有化部署 Databend 实例的过程。 +在本教程中,我们将指导你如何使用 BendSQL 连接到自托管的 Databend 实例。 ### 开始之前 -- 确保您的本地机器上安装了 [Docker](https://www.docker.com/),因为它将用于启动 Databend。 -- 确保您的机器上安装了 BendSQL。有关如何使用各种包管理器安装 BendSQL 的说明,请参阅 [安装 BendSQL](/guides/sql-clients/bendsql/#installing-bendsql)。 +- 确保本地已安装 [Docker](https://www.docker.com/),我们将用它启动 Databend。 +- 确保本地已安装 BendSQL。安装方法请参考 [安装 BendSQL](/guides/sql-clients/bendsql/#installing-bendsql)。 ### 启动 Databend -在您的终端中运行以下命令以启动 Databend 实例: +在终端运行以下命令启动 Databend 实例: ```bash docker run -d --name databend \ @@ -32,25 +32,25 @@ docker run -d --name databend \ datafuselabs/databend:nightly ``` -此命令在 Docker 容器中本地启动一个 Databend 实例,连接信息如下: +该命令会在本地 Docker 容器中启动 Databend,连接信息如下: -- Host: `127.0.0.1` -- Port: `8000` -- User: `eric` -- Password: `abc123` +- 主机:`127.0.0.1` +- 端口:`8000` +- 用户:`eric` +- 密码:`abc123` ### 启动 BendSQL -一旦 Databend 实例正在运行,您可以使用 BendSQL 连接到它。打开一个终端并使用以下命令进行连接: +Databend 实例运行后,即可用 BendSQL 连接。打开终端并执行: ```bash bendsql --host 127.0.0.1 --port 8000 --user eric --password abc123 ``` -这将使用 HTTP API 通过用户 `eric` 和密码 `abc123` 连接到 `127.0.0.1:8000` 上的 Databend。运行此命令后,您应该会看到一个成功的连接消息,如下所示: +该命令通过 `127.0.0.1:8000` 的 HTTP API,以用户 `eric` 和密码 `abc123` 连接 Databend。成功后可见如下提示: ```bash Welcome to BendSQL 0.24.7-ff9563a(2024-12-27T03:23:17.723492000Z). @@ -65,7 +65,7 @@ Started web server at 127.0.0.1:8080 ### 执行查询 -连接后,您可以在 BendSQL shell 中执行 SQL 查询。例如,键入 `SELECT NOW();` 以返回当前时间: +连接成功后,可在 BendSQL Shell 中执行 SQL。例如输入 `SELECT NOW();` 查看当前时间: ```bash eric@127.0.0.1:8000/default> SELECT NOW(); @@ -74,7 +74,7 @@ SELECT NOW() ┌────────────────────────────┐ │ now() │ -│ Timestamp │ +│ Timestamp │ ├────────────────────────────┤ │ 2025-04-24 13:24:06.640616 │ └────────────────────────────┘ @@ -86,7 +86,7 @@ SELECT NOW() ### 退出 BendSQL -要退出 BendSQL,请键入 `quit`。 +输入 `quit` 即可退出 BendSQL。 ```bash eric@127.0.0.1:8000/default> quit @@ -94,5 +94,12 @@ Bye~ ➜ ~ ``` +### BendSQL UI +使用 `--ui` 选项,BendSQL 会启动 Web 服务器并自动打开浏览器展示图形界面。你可以在浏览器中执行 SQL、分析查询性能,还可通过复制 URL 与他人共享结果。 + +```bash +❯ bendsql -h 127.0.0.1 --port 8000 --ui +``` + \ No newline at end of file