[英]T-SQL stored procedure from SQL server to PostgreSQL
对于一些上下文:我编写了一个使用两个表的存储过程, products
( product_id 、product_name、description、price、category_id)和supplies
(shipping_id、suppliers_id、product_id(FK 到products
)、 supply_date 、数量)。
该过程采用product_id
并在给定时间范围内(从 date1 到 date2)打印有关产品供应的描述和某些信息。
这是 T-SQL 代码:
CREATE OR ALTER PROCEDURE productInfo
(@product_id INT,
@date1 DATE,
@date2 DATE)
AS
BEGIN
DECLARE @description VARCHAR(100),
@shipment_id INT,
@supply_date DATE,
@quantity INT;
DECLARE product_cursor CURSOR LOCAL FOR
SELECT description
FROM products
WHERE product_id = @product_id
OPEN product_cursor;
FETCH NEXT FROM product_cursor INTO @description
CLOSE product_cursor
DECLARE product_supply_cursor CURSOR LOCAL FOR
SELECT shipment_id, supply_date, quantity
FROM supplies
WHERE product_id = @product_id
OPEN product_supply_cursor;
FETCH NEXT FROM product_supply_cursor INTO @shipment_id, @supply_date, @quantity;
WHILE @@FETCH_STATUS = 0
BEGIN
IF @supply_date >= @date1 AND @supply_date <= @date2
BEGIN
PRINT 'DESCRIPTION: ' + @description
PRINT 'SHIPMENT_ID: ' + STR(@shipment_id)
PRINT 'SUPPLY_DATE: ' + convert(varchar, @supply_date, 23)
PRINT 'QUANTITY: ' + STR(@quantity)
PRINT ' '
END;
FETCH NEXT FROM product_supply_cursor INTO @shipment_id, @supply_date, @quantity;
END;
CLOSE product_supply_cursor;
END;
显然,这个过程不能在 pgSQL 中运行,而且我在这件事上没有经验,所以我想要这段代码的翻译,或者(如果我问得太多)关于需要改变什么的提示(语法或逻辑明智)以适应 pgSQL 语言。
SQL 服务器代码一开始就非常复杂。 游标的使用以及缓慢且低效的(嵌套)逐行处理可以简化为连接两个表的单个 SELECT 语句。 对 cursor 循环中的两个日期进行范围检查非常有效,最好直接在 SELECT 语句的 WHERE 子句中应用它,这样您就不必迭代超过 1000 万行。 只是为了显示 5。
一个天真的迁移会做这样的事情:
create procedure print_product_info(p_product_id int, p_date1 date, p_date2 date)
as
$$
declare
l_row record;
begin
for l_row in SELECT p.description, s.shipment_id, s.supply_date, s.quantity
FROM supplies s
JOIN products p ON p.product_id = s.product_id
WHERE p.product_id = p_product_id
AND s.supply_date >= p_date1
AND s.supply_date <= p_date2
loop
raise notice 'DESCRIPTION: %', l_row.description;
raise notice 'SHIPMENT_ID: %', l_row.shipment_id;
raise notice 'SUPPLY_DATE: %', to_char(l_row.supply_date, 'yyyy-mm-dd');
raise notice 'QUANTITY: %', l_row.quantity;
end loop;
end;
$$
language plpgsql;
但是,这不是在 Postgres 中这样做的方式。 结果不应“打印”,而应由 function 简单地“返回”(程序并非旨在返回内容)。
在 Postgres 中实现这一点的正确方法是返回集合 function:
create function get_product_info(p_product_id int, p_date1 date, p_date2 date)
returns table(description text, shipment_id int, supply_date date, quantity int)
as
$$
SELECT p.description, s.shipment_id, s.supply_date, s.quantity
FROM supplies s
JOIN products p ON p.product_id = s.product_id
WHERE p.product_id = p_product_id
AND s.supply_date >= p_date1
AND s.supply_date <= p_date2
$$
language sql;
要显示数据,请使用:
select *
from get_product_info(42, date '2020-01-07', '2020-01-12');
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.