Postgres 函数(通过 npgsql)调用 ExecuteNonQuery 返回 -1 作为受影响行的结果

发布于 2024-09-28 16:35:27 字数 853 浏览 0 评论 0 原文

我有一个简单的函数,只需将提供给它的参数值插入到表中的列中。

当我通过命令对象上的 ExecuteNonQuery() 方法运行该函数时,即使发生了插入,我总是得到 -1。

如果我运行与文本命令相同的查询,它将给出正确的结果 1。

我是 postgresql/npgsql 的新手。是否有技巧可以让函数反馈受影响的行数? SQL Server 中类似“set nocount off”的东西?

编辑: 我正在使用的代码:(使用 npgsql 2.0.11)

var connStr = @"Server=127.0.0.1;Port=5432;User Id=postgres;Password=***;Database=Test;";
using (var conn = new NpgsqlConnection(connStr)) {
    conn.Open();
    using (var cmd = conn.CreateCommand())
    {
        cmd.CommandText = "insert_something";
        cmd.CommandType = CommandType.StoredProcedure;
        NpgsqlCommandBuilder.DeriveParameters(cmd);
        cmd.Parameters["_id"].Value = 1;
        cmd.Parameters["_val"].Value = 2;
        var rowsAffected = cmd.ExecuteNonQuery();
        Console.WriteLine(rowsAffected);
    }
}

I have a simple function that just inserts the parameter values provided to it into columns in a table.

When I run the function via the ExecuteNonQuery() method on the command object I always get -1, even if the insert took place.

If i run the same query as a Text command it gives be the correct result of 1.

I'm new to postgresql/npgsql. Is there trick to making the function feed back the number of rows affected? Something like "set nocount off" in SQL Server?

EDIT:
The code I am using: (with npgsql 2.0.11)

var connStr = @"Server=127.0.0.1;Port=5432;User Id=postgres;Password=***;Database=Test;";
using (var conn = new NpgsqlConnection(connStr)) {
    conn.Open();
    using (var cmd = conn.CreateCommand())
    {
        cmd.CommandText = "insert_something";
        cmd.CommandType = CommandType.StoredProcedure;
        NpgsqlCommandBuilder.DeriveParameters(cmd);
        cmd.Parameters["_id"].Value = 1;
        cmd.Parameters["_val"].Value = 2;
        var rowsAffected = cmd.ExecuteNonQuery();
        Console.WriteLine(rowsAffected);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

心碎无痕… 2024-10-05 16:35:27

我没有使用过 Npgsql,但文档中有一个示例
下面的代码:

NpgsqlCommand command = new NpgsqlCommand("insert into table1 values(1, 1)", conn);
Int32 rowsaffected;

try
{
    rowsaffected = command.ExecuteNonQuery();
}

如果您正在谈论像这样的某些 PostgreSQL 函数:

CREATE FUNCTION myinsert(integer) RETURNS void
LANGUAGE 'sql' AS 'INSERT INTO mytable VALUES ($1)';

并且您正在执行类似 SELECT myinsert(1); 的操作,则无法获取受影响的行数,因为您正在运行SELECT 以及该函数内部执行的操作对您来说是不透明的。

I haven't used Npgsql, but the documentation has an example with
the following code:

NpgsqlCommand command = new NpgsqlCommand("insert into table1 values(1, 1)", conn);
Int32 rowsaffected;

try
{
    rowsaffected = command.ExecuteNonQuery();
}

If you are talking about some PostgreSQL function like this:

CREATE FUNCTION myinsert(integer) RETURNS void
LANGUAGE 'sql' AS 'INSERT INTO mytable VALUES ($1)';

and you are doing something like SELECT myinsert(1);, you can't get the number of affected rows, because you are running a SELECT and what the function does internally is opaque to you.

美人迟暮 2024-10-05 16:35:27

为了让 ExecuteNonQuery() 获取受影响的行数,您的 postgresql 函数应该返回该值。一个例子是:

CREATE OR REPLACE FUNCTION insert_something(_id int, _val int)
RETURNS int as $
DECLARE count int;
BEGIN
    INSERT INTO some_table (id, value) VALUES(_id, _val);
    GET DIAGNOSTICS count = ROW_COUNT;
    RETURN count;
END;
$ language plpgsql;

现在,如果您从代码中调用 ExecuteNonQuery(),您应该获得插入的行数。

For ExecuteNonQuery() to get the number of rows affected, your postgresql function should return just that. An example would be:

CREATE OR REPLACE FUNCTION insert_something(_id int, _val int)
RETURNS int as $
DECLARE count int;
BEGIN
    INSERT INTO some_table (id, value) VALUES(_id, _val);
    GET DIAGNOSTICS count = ROW_COUNT;
    RETURN count;
END;
$ language plpgsql;

Now if you call ExecuteNonQuery() from your code, you should get the inserted rows count.

柳若烟 2024-10-05 16:35:27

以下是我的实现方式,它对我来说没有任何问题:

向您的函数添加一个 OUT 参数。

CREATE OR REPLACE FUNCTION schema.UpdateSomeValue(
IN par_updateId text,
OUT par_returnvalue INT4)

BEGIN
    UPDATE schema.TableToUpdate
    SET status = 1 
    WHERE ID = par_updateId;
                
    GET DIAGNOSTICS par_returnvalue = ROW_COUNT;

END;

现在在 C# 方面

private int UpdateSomeValue()
{
    var connStr = @"Server=127.0.0.1;Port=5432;UserId=postgres;Password=***;Database=Test;";
    int result = -1;
    using (var conn = new NpgsqlConnection(connStr)) {
                conn.Open();
                using (var cmd = conn.CreateCommand())
                {
                    cmd.CommandText = "shema.UpdateSomeValue";
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("par_updateId",NpgsqlTypes.NpgsqlDbType.INT, 1);
                    NpgsqlParameter outParm = new NpgsqlParameter("par_returnvalue", 
                    NpgsqlTypes.NpgsqlDbType.Integer)
                        {
                            Direction = ParameterDirection.Output
                        };
                    cmd.ExecuteNonQuery();
                    result = Convert.ToInt32(outParm.Value);
                }
            }
      return result;    

}

PS:我尝试了 ExecuteNonQuery() 方法,但它总是为我返回 -1 (就好像没有行受到影响NpgsqlDocumentation)使用上述方式我能够捕获受 PostgreSQL 影响的行数函数和 OUT 参数可以很容易地在客户端捕获受影响的行。

Here's how I have implemented and its working for me without any issues:

Add an OUT Parameter to your function.

CREATE OR REPLACE FUNCTION schema.UpdateSomeValue(
IN par_updateId text,
OUT par_returnvalue INT4)

BEGIN
    UPDATE schema.TableToUpdate
    SET status = 1 
    WHERE ID = par_updateId;
                
    GET DIAGNOSTICS par_returnvalue = ROW_COUNT;

END;

Now on the C# side

private int UpdateSomeValue()
{
    var connStr = @"Server=127.0.0.1;Port=5432;UserId=postgres;Password=***;Database=Test;";
    int result = -1;
    using (var conn = new NpgsqlConnection(connStr)) {
                conn.Open();
                using (var cmd = conn.CreateCommand())
                {
                    cmd.CommandText = "shema.UpdateSomeValue";
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("par_updateId",NpgsqlTypes.NpgsqlDbType.INT, 1);
                    NpgsqlParameter outParm = new NpgsqlParameter("par_returnvalue", 
                    NpgsqlTypes.NpgsqlDbType.Integer)
                        {
                            Direction = ParameterDirection.Output
                        };
                    cmd.ExecuteNonQuery();
                    result = Convert.ToInt32(outParm.Value);
                }
            }
      return result;    

}

PS : I tried the just ExecuteNonQuery() approach but it was always returning -1 for me (as if no rows has been affected NpgsqlDocumentation) Using above way I was able to capture the Number of rows affected from the PostgreSQL function and with OUT parameter it was easy to catch the affected rows on the client side.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文