如何通过在 npgsql 中调用存储过程来获取游标数据
how can I get cursor data with calling stored procedure in npgsql
我查看了 www.npgsql.org 中的资料,但找不到解决问题的方法...
Table, 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();
}
}
这个 returns "unnamed portal 1" 是要获取的游标而不是数据,
有什么方法可以将其转换为 Austin, Houston, Los Angeles... 这样的数据?
互联网上有一些关于此的帖子,但我不确定我做错了什么。
- npgsql : ver3.0.3
- c#:vs2012
(已添加)
我发现这发生在 npgsql ver3.x 中,而在 ver2.x 中它与我的代码一起工作正常。获取游标的用法有任何变化吗?
(参考)
http://www.sqlines.com/postgresql/npgsql_cs_result_sets
Npgsql 2.x 有一个特性,它可以自动 "dereferenced" 从函数中 return 游标。此功能已从 Npgsql 3.0 中删除;我们在 3.0 的迁移节点中提到了这一点,讨论在 this issue 中。由于游标只是 returned 而不是取消引用,Npgsql returns 游标名称本身(未命名的门户 1);您现在可以通过发送 FETCH
等
从此查询中获取结果
然而,如前所述,将单个 SELECT 包装在函数中没有多大意义。如果您确实需要编写一个 return 是 单个 结果集的函数,请将其设为 return SETOF 或 TABLE 而不是游标:CREATE FUNCTION ... RETURNS TABLE (column_name column_type [, ...])
。除了更简单和更清晰之外,这也更有效,因为查询结果是直接 returned(取消引用游标涉及另一个数据库往返)。
请参阅 PostgreSQL docs 了解有关如何定义函数的更多信息 returning table。
在 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
这是为了便于理解的示例,所以如果您希望您的函数 return 单个结果集,那么请考虑 return 而不是 returning cursor
=] table
正如@Shay 建议的那样,或者创建一个 view
而不是 @CeOnSql 建议的 function
。
谢谢!
我有以下 Npgsql 2.2.7 版本的工作代码:
private static DataSet ExecuteFunction(string functionName)
{
DataSet ds = new DataSet();
var conn = new NpgsqlConnection("replace with connection string");
conn.Open();
var tran = conn.BeginTransaction();
var cmd = new NpgsqlCommand(functionName, conn);
cmd.CommandType = CommandType.StoredProcedure;
NpgsqlDataAdapter da = new NpgsqlDataAdapter(cmd);
da.Fill(ds);
//foreach (DataRow r in ds.Tables[0].Rows)
//{
// Console.WriteLine("{0}", r[0]);
//}
tran.Commit();
conn.Close();
return ds;
}
我查看了 www.npgsql.org 中的资料,但找不到解决问题的方法...
Table, 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();
}
}
这个 returns "unnamed portal 1" 是要获取的游标而不是数据, 有什么方法可以将其转换为 Austin, Houston, Los Angeles... 这样的数据?
互联网上有一些关于此的帖子,但我不确定我做错了什么。
- npgsql : ver3.0.3
- c#:vs2012
(已添加) 我发现这发生在 npgsql ver3.x 中,而在 ver2.x 中它与我的代码一起工作正常。获取游标的用法有任何变化吗?
(参考) http://www.sqlines.com/postgresql/npgsql_cs_result_sets
Npgsql 2.x 有一个特性,它可以自动 "dereferenced" 从函数中 return 游标。此功能已从 Npgsql 3.0 中删除;我们在 3.0 的迁移节点中提到了这一点,讨论在 this issue 中。由于游标只是 returned 而不是取消引用,Npgsql returns 游标名称本身(未命名的门户 1);您现在可以通过发送 FETCH
等
然而,如前所述,将单个 SELECT 包装在函数中没有多大意义。如果您确实需要编写一个 return 是 单个 结果集的函数,请将其设为 return SETOF 或 TABLE 而不是游标:CREATE FUNCTION ... RETURNS TABLE (column_name column_type [, ...])
。除了更简单和更清晰之外,这也更有效,因为查询结果是直接 returned(取消引用游标涉及另一个数据库往返)。
请参阅 PostgreSQL docs 了解有关如何定义函数的更多信息 returning table。
在 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
这是为了便于理解的示例,所以如果您希望您的函数 return 单个结果集,那么请考虑 return 而不是 returning cursor
=] table
正如@Shay 建议的那样,或者创建一个 view
而不是 @CeOnSql 建议的 function
。
谢谢!
我有以下 Npgsql 2.2.7 版本的工作代码:
private static DataSet ExecuteFunction(string functionName)
{
DataSet ds = new DataSet();
var conn = new NpgsqlConnection("replace with connection string");
conn.Open();
var tran = conn.BeginTransaction();
var cmd = new NpgsqlCommand(functionName, conn);
cmd.CommandType = CommandType.StoredProcedure;
NpgsqlDataAdapter da = new NpgsqlDataAdapter(cmd);
da.Fill(ds);
//foreach (DataRow r in ds.Tables[0].Rows)
//{
// Console.WriteLine("{0}", r[0]);
//}
tran.Commit();
conn.Close();
return ds;
}