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

hgtggwj0  于 2022-11-04  发布在  PostgreSQL
关注(0)|答案(3)|浏览(246)

我有一个简单的函数,它只是将提供给它的参数值插入到表的列中。
当我通过ExecuteNonQuery()方法在命令对象上运行函数时,总是得到-1,即使插入发生了。
如果我运行相同的查询作为一个文本命令,它给出的是正确的结果1。
我是postgresql/npgsql的新手。有什么诀窍可以让函数反馈受影响的行数吗?比如SQL Server中的“set nocount off”?

**EDIT:**我正在使用的代码:(使用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);
    }
}
bxgwgixi

bxgwgixi1#

我没有使用过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,而函数内部执行的操作对您来说是不透明的。

ozxc1zmp

ozxc1zmp2#

要使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(),则应该获得插入的行数。

chhkpiq4

chhkpiq43#

以下是我如何实施的,它对我的工作没有任何问题:
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参数,很容易在客户端捕获受影响的行。

相关问题