【问题标题】:How to call plpgsql function from c#如何从 C# 调用 plpgsql 函数
【发布时间】:2020-03-10 08:24:52
【问题描述】:

我在 plpgsql 中创建了一个函数,我正在尝试从 .net core api 调用存储过程 但是我在 c# 中遇到了以下异常

42883:函数 proc_insert_test(brndcode => 整数,brndname => 字符变化,brndsname => 字符变化,prdtype => 字符,中断 => 字符,crddate => 日期,状态 => 整数,recstat => 整数, brndgrpseqno => 整数,wefrom => 日期) 不存在

没有函数匹配给定的名称和参数类型。您可能需要添加显式类型转换。

程序:

CREATE OR REPLACE FUNCTION public.proc_insert_test(p_brndcode integer, 
                                                p_brndname varchar(100), 
                                                p_brndsname varchar(100), 
                                                p_prdtype char(1),
                                                p_discontinue char(1),
                                                p_crddate date,
                                                p_status integer,
                                                p_recstat integer,
                                                p_brndgrpseqno integer,
                                                p_wefrom date)
RETURNS char
LANGUAGE plpgsql
AS $body$
BEGIN
    Insert into arc_mmstbrndgroup(brndcode, brndname, brndsname, prdtype, discontinue, crddate, status, recstat, brndgrpseqno, wefrom) 
    values(p_brndcode, p_brndname, p_brndsname, p_prdtype, p_discontinue, p_crddate, p_status, p_recstat, p_brndgrpseqno, p_wefrom);
    return 'saved';
END;
$body$
;

从 c# 调用过程:

NpgsqlCommand cmd = new NpgsqlCommand("proc_insert_test", _connection);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@brndcode", NpgsqlTypes.NpgsqlDbType.Integer, 123);
cmd.Parameters.AddWithValue("@brndname", NpgsqlTypes.NpgsqlDbType.Varchar, 100, "Test3");
cmd.Parameters.AddWithValue("@brndsname", NpgsqlTypes.NpgsqlDbType.Varchar, 100, "Test3");
cmd.Parameters.AddWithValue("@prdtype", NpgsqlTypes.NpgsqlDbType.Char, 1, "T");
cmd.Parameters.AddWithValue("@discontinue", NpgsqlTypes.NpgsqlDbType.Char, 1, "T");
cmd.Parameters.AddWithValue("@crddate", NpgsqlTypes.NpgsqlDbType.Date, DateTime.Now);
cmd.Parameters.AddWithValue("@status", NpgsqlTypes.NpgsqlDbType.Integer, 1);
cmd.Parameters.AddWithValue("@recstat", NpgsqlTypes.NpgsqlDbType.Integer, 9);
cmd.Parameters.AddWithValue("@brndgrpseqno", NpgsqlTypes.NpgsqlDbType.Integer, 1234);
cmd.Parameters.AddWithValue("@wefrom", NpgsqlTypes.NpgsqlDbType.Date, DateTime.Now);
_connection.Open();
cmd.ExecuteNonQuery();
cmd.Dispose();
_connection.Close();

可能是什么问题?

【问题讨论】:

  • 尝试重命名.net中的参数以匹配sql脚本中的名称,@brndcode => @p_brndcode, @brndname => @p_brndname等等。
  • @ArjunVachhani OMG,非常感谢,我完全忘记了 XD 现在它工作正常

标签: c# postgresql plpgsql


【解决方案1】:

对我来说它正在工作

PGDbContext _context = new PGDbContext();
            string d1 = "mm5";
            string d2 = "mmTest6";
            int d3 = 11;
            string d4 = "1";
            var DistributionChannelGUID = _context.Database.SqlQuery<List<string>>("call dbo.insupdelglclassmaster({0},{1},{2},{3})", d1, d2, d3, d4).ToList();

【讨论】:

    【解决方案2】:

    我也遇到过这个问题。经过一些分析发现日期数据类型转换不起作用。所以我们改变了我们的调用方法,

    没有返回值:

    string strquery = "SELECT PROC_INSERT_TEST(123,'Test3','Test3','T','T',";
    strquery = strquery + "'" + DateTime.Now.ToString("MMM-dd-yyyy HH:mm:ss") + "',1,9,1234,";
    strquery = strquery + "'" + DateTime.Now.ToString("MMM-dd-yyyy HH:mm:ss") + "')";
    
    NpgsqlCommand cmd = new NpgsqlCommand(strquery, _connection);
    _connection.Open();
    cmd.ExecuteNonQuery();
    cmd.Dispose();
    _connection.Close();
    

    有返回值

    string strquery = "BEGIN; SELECT PROC_INSERT_TEST_WITH_RETURN(123,'Test3','Test3','T','T',";
    strquery = strquery + "'" + DateTime.Now.ToString("MMM-dd-yyyy HH:mm:ss") + "',1,9,1234,";
    strquery = strquery + "'" + DateTime.Now.ToString("MMM-dd-yyyy HH:mm:ss") + "')";
    
    NpgsqlCommand cmd = new NpgsqlCommand(strquery, _connection);
    _connection.Open();
    object cursorVal = cmd.ExecuteScalar();
    DataSet ds = FetchAll(_connection, cursorVal);
    cmd.Dispose();
    _connection.Close();
    
    
    private DataSet FetchAll(NpgsqlConnection _connection, object cursorVal)
    {
        try
        {
            DataSet actualData = new DataSet();
    
            string strSql = "fetch all from \"" + cursorVal + "\";";
            NpgsqlCommand cmd = new NpgsqlCommand(strSql, _connection);
            NpgsqlDataAdapter ada = new NpgsqlDataAdapter(cmd);
            ada.Fill(actualData);
    
            return actualData;
    
        }
        catch (Exception Exp)
        {
            throw new Exception(Exp.Message);
        }
    }
    

    【讨论】:

    • 谢谢,这行得通,但我需要像这样调用 plpgsql 程序??
    • 我怎样才能返回一个值/输出参数?
    • 感谢您的努力,我需要在程序的参数中添加输出参数吗?如何提及输出参数?我不能使用 Parameters.AddWithValue 或 Dapper 从 c# 调用过程?
    • 参数名不用提,但参数顺序很重要。
    • 应该避免通过联系参数来生成 SQL。它将系统暴露给 SQL 注入。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多