如何将输出值输出到输出参数中?

时间:2013-09-12 12:28:01

标签: c# postgresql parameters

我在VS 2008中使用C#从具有两个输入参数和两个输出参数的PostgreSQL存储过程中检索数据。当我创建程序时,PostgreSQL告诉我,我必须指定它返回一条记录。

在VS2008中,我第一次尝试使用该过程涉及创建类型为OdbcCommand的{​​{1}}对象,并为其提供四个参数,两个参数为Input,两个为方向Output。执行该命令时没有错误,首先使用CommandType.StoredProcedure然后使用ExecuteNonQuery(),但输出参数的值为null。我调用了读者的ExecuteReader()函数,发现结果是包含字符串GetValues()的单个对象。

然后,根据StackOverflow的建议,我将命令文本更改为:     {call nearest_idle_cover(?,?,?,?)}

这也有效,"{3,4}"给了我一个两个int类型对象的数组,一个用3个,另一个用4个。这个好一点,因为我不需要解析一个字符串。但是输出参数仍然具有空值,实际上,如果我只传入两个输入参数,该命令也可以正常工作。

所以,虽然我有一个有效的解决方案,但我仍然很好奇:如何将值输入到我的输出参数中?

这是PostgreSQL存储过程:

GetValues()

1 个答案:

答案 0 :(得分:1)

您正在使用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#代码中处理它,就像从数据库中提取的任何其他数据一样。

一些观察结果:

  • 由于您正在寻找最近的ic_storage_location,因此您可以省去SQRT()函数调用,这在计算上非常昂贵。仅使用平方和就具有与当前位置距离排序记录的相同属性。
  • 该函数定义为STRICT,因为它要求两个参数的值都能正常工作。
  • 请勿自行分配COST个值,除非 真的 知道您在做什么。