VS 2008 で C# を使用して、2 つの入力パラメーターと 2 つの出力パラメーターを持つ PostgreSQL ストアド プロシージャからデータを取得しています。プロシージャを作成したとき、PostgreSQL から、レコードを返すように指定する必要があると言われました。
VS2008 では、この手順を使用する最初の試みとして、OdbcCommand
型のオブジェクトを作成し、CommandType.StoredProcedure
それに 4 つのパラメーター (入力の方向を持つ 2 つと出力の方向を持つ 2 つ) を与える必要がありました。ExecuteNonQuery()
最初に を使用し、次に を使用して、コマンドはエラーなしで実行されましExecuteReader()
たが、出力パラメータの値は null でした。リーダーのGetValues()
関数を呼び出したところ、結果は string を含む単一のオブジェクトであることがわかりました"{3,4}"
。
次に、StackOverflow からの提案に従って、コマンド テキストを次のように変更しました: {call closest_idle_cover(?, ?, ?, ?)}
これも機能し、GetValues()
int 型の 2 つのオブジェクト (1 つは 3、もう 1 つは 4) の配列が得られました。これは、文字列を解析する必要がないため、かなり改善されました。しかし、出力パラメーターにはまだ NULL 値が含まれており、実際、2 つの入力パラメーターのみを渡した場合でも、コマンドは同様に機能します。
それで、うまくいく解決策がありますが、私はまだ興味があります: 出力パラメーターに値を取得するにはどうすればよいですか?
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;