diff --git a/docs/cn/sql-reference/30-stored-procedure-scripting/index.md b/docs/cn/sql-reference/30-stored-procedure-scripting/index.md
index 84738c8a1e..c8e1658e44 100644
--- a/docs/cn/sql-reference/30-stored-procedure-scripting/index.md
+++ b/docs/cn/sql-reference/30-stored-procedure-scripting/index.md
@@ -3,6 +3,10 @@ title: 存储过程(Stored Procedure)与 SQL 脚本
slug: /stored-procedure-scripting/
---
+import FunctionDescription from '@site/src/components/FunctionDescription';
+
+
+
Databend 中的存储过程(Stored Procedure)允许您将 SQL 逻辑打包在服务器上运行,并支持控制流(Control Flow)、变量(Variable)、游标(Cursor)和动态语句(Dynamic Statement)。本页面介绍如何创建存储过程以及编写驱动它们的内联脚本。
## 定义存储过程
@@ -52,7 +56,7 @@ CALL PROCEDURE convert_kg_to_lb(10);
### 声明部分
-存储过程可以以可选的 `DECLARE` 块开始,在可执行部分之前初始化变量(Variable)。
+存储过程可以以可选的 `DECLARE` 块开始,在可执行部分之前初始化变量(Variable)。每个条目遵循与 `LET` 相同的语法:`name [] [:= | DEFAULT ]`。如果省略初始化器,变量必须在读取之前被赋值;过早引用会触发错误 3129。
```sql
CREATE OR REPLACE PROCEDURE sp_with_declare()
@@ -60,7 +64,7 @@ RETURNS INT
LANGUAGE SQL
AS $$
DECLARE
- counter := 0;
+ counter INT DEFAULT 0;
BEGIN
counter := counter + 5;
RETURN counter;
@@ -70,11 +74,11 @@ $$;
CALL PROCEDURE sp_with_declare();
```
-`DECLARE` 部分接受与 `LET` 相同的定义,包括 `RESULTSET` 和 `CURSOR` 声明。每项后使用分号。
+`DECLARE` 部分接受与 `LET` 相同的定义,包括可选的数据类型、`RESULTSET` 和 `CURSOR` 声明。每项后使用分号。
### 变量与赋值
-使用 `LET` 声明变量(Variable)或常量(Constant),通过省略 `LET` 进行重新赋值。
+使用 `LET` 声明变量(Variable)或常量(Constant)。可以选择添加类型标注,并使用 `:=` 或 `DEFAULT` 关键字指定初始值。如果省略初始化器,变量必须在读取之前被赋值;提前引用会触发错误 3129。通过省略 `LET` 进行重新赋值。
```sql
CREATE OR REPLACE PROCEDURE sp_demo_variables()
@@ -82,11 +86,14 @@ RETURNS FLOAT
LANGUAGE SQL
AS $$
BEGIN
- LET total := 100;
- LET rate := 0.07;
+ LET total DECIMAL(10, 2) DEFAULT 100;
+ LET rate FLOAT := 0.07;
+ LET surcharge FLOAT := NULL; -- 使用前显式初始化
+ LET tax FLOAT DEFAULT rate; -- DEFAULT 可以引用已经初始化的变量
total := total * rate; -- 乘以比率
- total := total + 5; -- 不使用 LET 重新赋值
+ total := total + COALESCE(surcharge, 5); -- 不使用 LET 重新赋值
+ total := total + tax;
RETURN total;
END;
@@ -95,6 +102,8 @@ $$;
CALL PROCEDURE sp_demo_variables();
```
+在存储过程的任何位置引用未初始化的变量都会触发错误 3129。
+
### 变量作用域
变量(Variable)的作用域限定在封闭块内。内部块可以遮蔽外部绑定,当块退出时恢复外部值。
diff --git a/docs/en/sql-reference/30-stored-procedure-scripting/index.md b/docs/en/sql-reference/30-stored-procedure-scripting/index.md
index 9fb38dca63..88a929b294 100644
--- a/docs/en/sql-reference/30-stored-procedure-scripting/index.md
+++ b/docs/en/sql-reference/30-stored-procedure-scripting/index.md
@@ -3,6 +3,10 @@ title: Stored Procedure & SQL Scripting
slug: /stored-procedure-scripting/
---
+import FunctionDescription from '@site/src/components/FunctionDescription';
+
+
+
Stored procedures in Databend let you package SQL logic that runs on the server with access to control flow, variables, cursors, and dynamic statements. This page explains how to create procedures and write the inline scripting that powers them.
## Defining a Procedure
@@ -52,7 +56,7 @@ CALL PROCEDURE convert_kg_to_lb(10);
### Declare Section
-Stored procedures can start with an optional `DECLARE` block to initialize variables before the executable section.
+Stored procedures can start with an optional `DECLARE` block to initialize variables before the executable section. Each entry in the block follows the same syntax as `LET`: `name [] [:= | DEFAULT ]`. When you omit the initializer, the variable must be assigned before it is read; referencing it too early raises error 3129.
```sql
CREATE OR REPLACE PROCEDURE sp_with_declare()
@@ -60,7 +64,7 @@ RETURNS INT
LANGUAGE SQL
AS $$
DECLARE
- counter := 0;
+ counter INT DEFAULT 0;
BEGIN
counter := counter + 5;
RETURN counter;
@@ -70,11 +74,11 @@ $$;
CALL PROCEDURE sp_with_declare();
```
-The `DECLARE` section accepts the same definitions as `LET`, including `RESULTSET` and `CURSOR` declarations. Use a semicolon after each item.
+The `DECLARE` section accepts the same definitions as `LET`, including optional data types, `RESULTSET`, and `CURSOR` declarations. Use a semicolon after each item.
### Variables and Assignment
-Use `LET` to declare variables or constants, and reassign by omitting `LET`.
+Use `LET` to declare variables or constants. You can optionally provide a type annotation and an initializer with either `:=` or the `DEFAULT` keyword. Without an initializer, the variable must be assigned before it is read; referencing it beforehand raises error 3129. Reassign by omitting `LET`.
```sql
CREATE OR REPLACE PROCEDURE sp_demo_variables()
@@ -82,11 +86,14 @@ RETURNS FLOAT
LANGUAGE SQL
AS $$
BEGIN
- LET total := 100;
- LET rate := 0.07;
+ LET total DECIMAL(10, 2) DEFAULT 100;
+ LET rate FLOAT := 0.07;
+ LET surcharge FLOAT := NULL; -- Explicitly initialize before use
+ LET tax FLOAT DEFAULT rate; -- DEFAULT can reference initialized variables
total := total * rate; -- Multiply by the rate
- total := total + 5; -- Reassign without LET
+ total := total + COALESCE(surcharge, 5); -- Reassign without LET
+ total := total + tax;
RETURN total;
END;
@@ -95,6 +102,8 @@ $$;
CALL PROCEDURE sp_demo_variables();
```
+Referencing an uninitialized variable anywhere in a procedure raises error 3129.
+
### Variable Scope
Variables are scoped to the enclosing block. Inner blocks can shadow outer bindings, and the outer value is restored when the block exits.