通过一个简单的例子学习在 Firebird 中使用执行块
Learning to use execute block in Firebird with a simple example
我还没有在 Firebird 中使用过执行块,但我正在努力学习如何使用它。
我试图从一个简单的例子中学习,然后扩展到更复杂的情况。
假设我有 2 个 table,如下所示:
+------------+------+
| Clientcode | name |
+------------+------+
| 123 | A |
| 234 | B |
+------------+------+
+----------+------------+---------+
| order_id | clientcode | value |
+----------+------------+---------+
| 12 | 234 | 10,00 |
| 13 | 123 | 20,00 |
| 14 | 123 | 10,00 |
+----------+------------+---------+
我有以下代码。
execute block returns (client integer,amount double)
as
declare variable client_code integer;
begin
for
select clientcode from clients
into : client_code
do
begin
select :client_code,sum(value) from orders group by 1
into :client, :order_id;
end
end
基本上,我想为客户端table中的每个客户端计算订单table中的订单总和。我知道在这种情况下不需要执行块,但是通过一个简单的例子我可能会更好地理解它。
+-------------+--------+
| client_code | amount |
+-------------+--------+
| 123 | 30 |
| 234 | 10 |
+-------------+--------+
正确的语法是什么?
您的代码中缺少一些东西:
- 从
orders
中选择时需要一个 where
子句以将其限制为仅当前客户端的行
- 您需要将总和输出到
amount
,而不是 non-existent 变量 order_id
- 您需要添加
suspend
以输出一行(否则执行块只能产生一行,并分配最后一个值)。
- (可选)当
client
达到相同目的时,您不需要变量 client_code
生成的代码类似于(请注意,我使用 decimal(18,2)
而不是 double precision
,使用 decimal
等精确数字类型是货币值的更好选择):
execute block returns (client_code integer,amount decimal(18,2))
as
begin
for select clientcode from clients
into client_code
do
begin
select sum(amount) from orders where clientcode = :client_code
into amount;
suspend;
end
end
这相当于以下查询:
select clients.clientcode as client_code, sum(orders.amount) as amount
from clients
left join orders on clients.clientcode = orders.clientcode
group by clients.clientcode
另请参阅此 dbfiddle。
请记住,execute block
is essentially a Firebird stored procedure that isn't stored. An execute block
with a suspend
behaves as a selectable procedure which can produce zero or more rows, and one without suspend
behaves as an executable procedure 只能生成一行。
我还没有在 Firebird 中使用过执行块,但我正在努力学习如何使用它。
我试图从一个简单的例子中学习,然后扩展到更复杂的情况。
假设我有 2 个 table,如下所示:
+------------+------+
| Clientcode | name |
+------------+------+
| 123 | A |
| 234 | B |
+------------+------+
+----------+------------+---------+
| order_id | clientcode | value |
+----------+------------+---------+
| 12 | 234 | 10,00 |
| 13 | 123 | 20,00 |
| 14 | 123 | 10,00 |
+----------+------------+---------+
我有以下代码。
execute block returns (client integer,amount double)
as
declare variable client_code integer;
begin
for
select clientcode from clients
into : client_code
do
begin
select :client_code,sum(value) from orders group by 1
into :client, :order_id;
end
end
基本上,我想为客户端table中的每个客户端计算订单table中的订单总和。我知道在这种情况下不需要执行块,但是通过一个简单的例子我可能会更好地理解它。
+-------------+--------+
| client_code | amount |
+-------------+--------+
| 123 | 30 |
| 234 | 10 |
+-------------+--------+
正确的语法是什么?
您的代码中缺少一些东西:
- 从
orders
中选择时需要一个where
子句以将其限制为仅当前客户端的行 - 您需要将总和输出到
amount
,而不是 non-existent 变量order_id
- 您需要添加
suspend
以输出一行(否则执行块只能产生一行,并分配最后一个值)。 - (可选)当
client
达到相同目的时,您不需要变量client_code
生成的代码类似于(请注意,我使用 decimal(18,2)
而不是 double precision
,使用 decimal
等精确数字类型是货币值的更好选择):
execute block returns (client_code integer,amount decimal(18,2))
as
begin
for select clientcode from clients
into client_code
do
begin
select sum(amount) from orders where clientcode = :client_code
into amount;
suspend;
end
end
这相当于以下查询:
select clients.clientcode as client_code, sum(orders.amount) as amount
from clients
left join orders on clients.clientcode = orders.clientcode
group by clients.clientcode
另请参阅此 dbfiddle。
请记住,execute block
is essentially a Firebird stored procedure that isn't stored. An execute block
with a suspend
behaves as a selectable procedure which can produce zero or more rows, and one without suspend
behaves as an executable procedure 只能生成一行。