簡體   English   中英

如何將輸出值轉換為輸出參數?

[英]How can I get output values into output parameters?

我在VS 2008中使用C#從具有兩個輸入參數和兩個輸出參數的PostgreSQL存儲過程中檢索數據。 創建該過程時,PostgreSQL告訴我必須指定它返回一條記錄。

在VS2008中,我首次嘗試使用該過程涉及創建類型為CommandType.StoredProcedureOdbcCommand對象,並為其提供四個參數,兩個參數為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#代碼中進行處理。

一些觀察:

  • 由於您正在尋找最接近的ic_storage_location,因此可以省去SQRT()函數調用,這在計算上是昂貴的。 僅僅使用平方和具有與從當前位置的距離對記錄進行排序的相同屬性。
  • 該函數定義為STRICT因為它需要兩個參數的值才能正常工作。
  • 除非您真的知道自己在做什么,否則不要自己分配COST值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM