我在 VS 2008 中使用 C# 从具有两个输入参数和两个输出参数的 PostgreSQL 存储过程中检索数据。当我创建过程时,PostgreSQL 告诉我必须指定它返回一条记录。
在 VS2008 中,我第一次尝试使用该过程涉及创建一个OdbcCommand
类型的对象CommandType.StoredProcedure
并为其提供四个参数,两个带有输入方向,两个带有方向输出。该命令执行没有错误,首先使用ExecuteNonQuery()
然后使用ExecuteReader()
,但输出参数的值为空。我调用了 reader 的GetValues()
函数,发现结果是一个包含字符串的单个对象"{3,4}"
。
然后,根据 StackOverflow 的建议,我将命令文本更改为:{call most_idle_cover(?, ?, ?, ?)}
这也有效,并GetValues()
给了我一个包含两个 int 类型对象的数组,一个为 3,另一个为 4。这要好得多,因为我不必解析字符串。但是输出参数仍然有空值,事实上,如果我只传入两个输入参数,该命令也同样有效。
所以,虽然我有一个可行的解决方案,但我仍然很好奇:如何将这些值放入我的输出参数中?
这是 PostgreSQL 存储过程:
CREATE OR REPLACE FUNCTION plant_genie.closest_idle_cover(IN int, IN int, OUT int, OUT int)
RETURNS record AS
$BODY$
DECLARE
current_x ALIAS FOR $1;
current_y ALIAS FOR $2;
target_x ALIAS FOR $3;
target_y ALIAS FOR $4;
coverLocations ic_storage_locations%rowtype;
BEGIN
target_x := 3;
target_y := 4;
SELECT INTO coverLocations *
FROM ic_storage_locations
WHERE inner_cover IS NOT NULL
ORDER BY sqrt(pow(current_x - ic_storage_locations.x_coordinate, 2) +
pow(current_y - ic_storage_locations.y_coordinate, 2))
LIMIT 1;
IF FOUND THEN
INSERT INTO op_messages (message) VALUES ('Found a cover location record.');
target_x := coverLocations.x_coordinate;
target_y := coverLocations.y_coordinate;
ELSE
INSERT INTO op_messages (message) VALUES ('Could not find a cover location record.');
END IF;
END;
$BODY$ LANGUAGE 'plpgsql' VOLATILE COST 100;