我已查看www.npgsql.org中的资料,但找不到如何解决我的问题......
表,PostgreSQL
[City], [State]
"Austin", "TX"
"Houston", "TX"
"Los Angeles", "CA"
"San Diego", "CA"
"San Fransisco";"CA"
"St.Louis", "MO"
功能(存储过程),PostgreSQL
-- Procedure that returns a single result set (cursor)
CREATE OR REPLACE FUNCTION show_cities() RETURNS refcursor AS $$
DECLARE
ref refcursor;
BEGIN
OPEN ref FOR SELECT city, state FROM cities;
RETURN ref;
END;
$$ LANGUAGE plpgsql;
代码,C#
using (NpgsqlConnection conn = new NpgsqlConnection(ConfigurationManager.ConnectionStrings["dbConnection"].ConnectionString))
{
conn.Open();
using (NpgsqlTransaction tran = conn.BeginTransaction())
{
using (var command = new NpgsqlCommand("show_cities", conn))
{
command.Transaction = tran;
command.CommandType = CommandType.StoredProcedure;
NpgsqlDataReader dr = command.ExecuteReader();
while (dr.Read())
str += dr.GetValue(0);
dr.Close();
}
tran.Commit();
}
}
这将返回“未命名的门户1”并且它是一个要获取的光标而不是数据, 有没有办法将其转换为奥斯汀,休斯顿,洛杉矶等数据??
互联网上有一些关于此的帖子,但我不确定我做错了什么。
(添加) 我发现这是在npgsql ver3.x上发生的,而在ver2.x中它可以正常使用我的代码。获取光标的用法是否有任何变化?
(参考) http://www.sqlines.com/postgresql/npgsql_cs_result_sets
答案 0 :(得分:10)
在Shay的帮助下,我弄清楚在删除“dereferenced”功能后我们如何在v3.x中获取光标。 我认为这方面没有太多好的例子,我希望这可以帮助人们节省搜索范例的时间。
您可以在npgsql ver3.x中执行此操作
<强> 1。 CommandType.StoredProcedure (未定义游标名称)
conn.Open();
NpgsqlTransaction tran = conn.BeginTransaction();
NpgsqlCommand command = new NpgsqlCommand("show_cities", conn);
command.CommandType = CommandType.StoredProcedure;
command.ExecuteNonQuery();
command.CommandText = "fetch all in \"<unnamed portal 1>\"";
command.CommandType = CommandType.Text;
NpgsqlDataReader dr = command.ExecuteReader();
while (dr.Read())
{
// do what you want with data, convert this to json or...
Console.WriteLine(dr[0]);
}
dr.Close();
tran.Commit();
conn.Close();
<强> 2。 CommandType.StoredProcedure (已定义游标名称)
conn.Open();
NpgsqlTransaction tran = conn.BeginTransaction();
NpgsqlCommand command = new NpgsqlCommand("select show_cities(@ref)", conn);
command.CommandType = CommandType.Text;
NpgsqlParameter p = new NpgsqlParameter();
p.ParameterName = "@ref";
p.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Refcursor;
p.Direction = ParameterDirection.InputOutput;
p.Value = "ref";
command.Parameters.Add(p);
command.ExecuteNonQuery();
command.CommandText = "fetch all in \"ref\"";
command.CommandType = CommandType.Text;
NpgsqlDataReader dr = command.ExecuteReader();
while (dr.Read())
{
// do what you want with data, convert this to json or...
Console.WriteLine(dr[0]);
}
dr.Close();
tran.Commit();
conn.Close();
第3。 CommandType.Text (已定义游标名称)
conn.Open();
NpgsqlTransaction tran = conn.BeginTransaction();
NpgsqlCommand command = new NpgsqlCommand("select show_cities(@ref)", conn);
command.CommandType = CommandType.Text;
NpgsqlParameter p = new NpgsqlParameter();
p.ParameterName = "@ref";
p.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Refcursor;
p.Direction = ParameterDirection.InputOutput;
p.Value = "ref";
command.Parameters.Add(p);
command.ExecuteNonQuery();
command.CommandText = "fetch all in \"ref\"";
command.CommandType = CommandType.Text;
NpgsqlDataReader dr = command.ExecuteReader();
while (dr.Read())
{
// do what you want with data, convert this to json or...
Console.WriteLine(dr[0]);
}
dr.Close();
tran.Commit();
conn.Close();
(参考v2.x)http://www.sqlines.com/postgresql/npgsql_cs_result_sets
这是一个易于理解的示例,因此如果您希望函数返回单个结果集,那么请考虑将其返回cursor
作为@Shay建议或创建一个table
。 {1}}不是@CeOnSql建议的view
。
谢谢!
答案 1 :(得分:6)
Npgsql 2.x有一个功能,可以自动&#34;取消引用&#34;游标从函数返回。此功能已从Npgsql 3.0中删除;这在我们的3.0迁移节点中提到,讨论在this issue。由于光标只是被返回而且没有被解除引用,所以Npgsql返回游标名称本身(未命名的门户1);您现在可以通过发送FETCH
等
然而,如前所述,在函数中包装单个SELECT并没有多大意义。如果确实需要编写一个返回单个结果集的函数,请使其返回SETOF或TABLE而不是游标:CREATE FUNCTION ... RETURNS TABLE (column_name column_type [, ...])
。除了更简单和更干净之外,这也更有效,因为查询结果是直接返回的(取消引用游标涉及另一个数据库往返)。
有关如何定义返回表格的函数的详细信息,请参阅PostgreSQL docs。