![](/img/trans.png)
[英]How can I get multiple output parameters from a stored procedure in a web service in C#?
[英]How can I get output values into output parameters?
我在VS 2008中使用C#从具有两个输入参数和两个输出参数的PostgreSQL存储过程中检索数据。 创建该过程时,PostgreSQL告诉我必须指定它返回一条记录。
在VS2008中,我首次尝试使用该过程涉及创建类型为CommandType.StoredProcedure
的OdbcCommand
对象,并为其提供四个参数,两个参数为Input方向,两个参数为Output方向。 执行该命令没有错误,首先使用ExecuteNonQuery()
,然后使用ExecuteReader()
,但是输出参数的值为null。 我调用了读者的GetValues()
函数,发现结果是一个包含字符串"{3,4}"
的单个对象。
然后,根据StackOverflow的建议,我将命令文本更改为:{call hidden_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;
您正在使用OUT
参数,但同时使用RETURNS record
子句,而在函数主体中没有显式的RETURN
语句。 这种组合不起作用。 比使用OUT
参数更优雅的解决方案是定义输出表格式-发生的情况更加明显:
CREATE OR REPLACE FUNCTION plant_genie.closest_idle_cover(current_x int, current_y int)
RETURNS TABLE (target_x int, target_y int) AS $BODY$
DECLARE
coverLocations ic_storage_locations%rowtype;
BEGIN
SELECT INTO coverLocations *
FROM ic_storage_locations
WHERE inner_cover IS NOT NULL
ORDER BY 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.');
RETURN QUERY SELECT coverLocations.x_coordinate, coverLocations.y_coordinate;
ELSE
INSERT INTO op_messages (message) VALUES ('Could not find a cover location record.');
END IF;
END; $BODY$ LANGUAGE 'plpgsql' STRICT;
因此,如果调用此函数,并且至少有1个ic_storage_location不为null,则会返回一条记录:
SELECT * FROM plant_genie.closest_idle_cover(1, 2);
您可以像使用其他任何从数据库中提取的数据一样,在C#代码中进行处理。
一些观察:
SQRT()
函数调用,这在计算上是昂贵的。 仅仅使用平方和具有与从当前位置的距离对记录进行排序的相同属性。 STRICT
因为它需要两个参数的值才能正常工作。 COST
值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.