c# - 带有 c# 后端的 PostgreSQL 发送了无法识别的响应类型 : o

标签 c# postgresql

我正在尝试执行以下函数,例如 C# 中的 ExecuteNonQuery:

CREATE OR REPLACE FUNCTION Fifty(cpfDe bigint,cpfPara bigint, valorDe decimal,valorPara decimal, idPagamento bigint)
RETURNS void AS $$
DECLARE comissionamento bigint;
BEGIN
IF (cpfPara <> 0)
THEN
insert into tb_comissionamentos 
(
    cpf_autonomo, id_imobiliaria, cpf_comprador, 
    id_venda, id_pagamento, valor,
    id_status, data_alteracao, id_usuario, 
    valor_percentual_banco, valor_ted, valor_deb_boleto_comprador,
    valor_liquido, status_envio_efetivacao
) 
select 
    cpfPara, id_imobiliaria, cpf_comprador, 
    id_venda, id_pagamento, valorPara, 
    id_status, data_alteracao, id_usuario, 
    (valorPara * 0.02), valor_ted, 0.08, valor_liquido, 
    status_envio_efetivacao 
FROM tb_comissionamentos 
where 
    id_pagamento = idPagamento 
    and cpf_autonomo = cpfDe
    and valor = valorDe;

SELECT id_comissionamento 
    into comissionamento
FROM tb_comissionamentos
WHERE id_pagamento = idPagamento
AND cpf_autonomo = cpfPara; 

update tb_hist_comissionamentos set 
    cpf_autonomo = cpfPara,
    valor =valorPara,      
    valor_percentual_banco = valorPara * 0.02, 
    valor_deb_boleto_comprador = 0.08, 
    id_comissionamento = comissionamento
where 
    id_pagamento = idPagamento 
    and cpf_autonomo = cpfDe 
    and id_comissionamento = comissionamento;

delete from tb_comissionamentos 
where 
    id_pagamento = idPagamento 
    and cpf_autonomo = cpfDe 
    and id_comissionamento = comissionamento;
ELSE
DELETE FROM tb_hist_teds_enviadas
where id_comissionamento in 
    (SELECT id_comissionamento FROM
    tb_comissionamento where 
    id_pagamento = idPagamento 
    and cpf_autonomo = cpfDe     
    and valor = valorDe);

DELETE FROM tb_teds_enviadas
where id_comissionamento in 
    (SELECT id_comissionamento FROM
    tb_comissionamento where 
    id_pagamento = idPagamento 
    and cpf_autonomo = cpfDe     
    and valor = valorDe);

DELETE FROM tb_hist_comissionamentos
where 
    id_pagamento = idPagamento 
    and cpf_autonomo = cpfDe  
    and valor = valorDe;  

delete from tb_comissionamentos 
where 
    id_pagamento = idPagamento 
    and cpf_autonomo = cpfDe     
    and valor = valorDe;
END IF;
IF (cpfDe <> 0)
THEN
insert into tb_comissionamentos 
(
    cpf_autonomo, id_imobiliaria, cpf_comprador, 
    id_venda, id_pagamento, valor,
    id_status, data_alteracao, id_usuario, 
    valor_percentual_banco, valor_ted, valor_deb_boleto_comprador,
    valor_liquido, status_envio_efetivacao
) 
select 
    cpfPara, id_imobiliaria, cpf_comprador, 
    id_venda, id_pagamento, valorPara, 
    id_status, data_alteracao, id_usuario, 
    (valorPara * 0.02), valor_ted, 0.08, valor_liquido, 
    status_envio_efetivacao 
FROM tb_comissionamentos 
where 
    id_pagamento = idPagamento;

SELECT id_comissionamento 
    into comissionamento
FROM tb_comissionamentos
WHERE id_pagamento = idPagamento
AND cpf_autonomo = cpfPara; 

INSERT INTO tb_hist_comissionamentos( 
    cpf_autonomo,
    valor,      
    valor_percentual_banco, 
    valor_deb_boleto_comprador, 
    id_comissionamento,
    id_pagamento)
    VALUES(cpfPara, valorPara,valorPara * 0.02, 0.08, comissionamento,idPagamento);
END IF;
END
$$ LANGUAGE plpgsql;

当我将所有参数放入 C# 并调用执行非查询时,我收到以下消息错误: 后端发送无法识别的响应类型:o

我可以在 Postgres 控制台中正常运行该函数,它工作得很好。 我认为是返回类型,但我不知道应该返回什么才能成功执行。 已编辑 C#代码:

using (NpgsqlCommand command = new NpgsqlCommand())
                {
                    if (!dllConexao.open(Processadora.Comum.tipoConexao, 1, true))
                    {
                        clsRetorno.ret = 99;
                        clsRetorno.msg = "Sistema temporariamente indisponível, tente novamente mais tarde";
                    }
                    if (this.dllConexao.transactionIsOpen())
                    {
                        command.Transaction = this.dllConexao.TransacaoBd;
                    }
                    command.Connection = this.dllConexao.ConexaoBd;
                    command.CommandType = CommandType.StoredProcedure;
                    command.CommandText = "Fifty";
                    var parm = command.CreateParameter();
                    parm.ParameterName = "cpfDe";
                    parm.DbType = DbType.Int64;
                    parm.Value = cpfDe;
                    var parm1 = command.CreateParameter();
                    parm1.ParameterName = "cpfPara";
                    parm1.DbType = DbType.Int64;
                    parm1.Value = cpfPara;

                    var parm2 = command.CreateParameter();
                    parm2.ParameterName = "valorDe";
                    parm2.DbType = DbType.Decimal;
                    parm2.Value = valorDe;

                    var parm3 = command.CreateParameter();
                    parm3.ParameterName = "valorPara";
                    parm3.DbType = DbType.Decimal;
                    parm3.Value = valorPara;

                    var parm4 = command.CreateParameter();
                    parm4.ParameterName = "idPagamento";
                    parm4.DbType = DbType.Int32;
                    parm4.Value = idPagamento;


                    command.Parameters.Add(parm);
                    command.Parameters.Add(parm1);
                    command.Parameters.Add(parm2);
                    command.Parameters.Add(parm3);
                    command.Parameters.Add(parm4);


                    command.ExecuteNonQuery();
                    this.dllConexao.commitTransacao();
                    this.dllConexao.closeTransaction();

                }

最佳答案

在我看来,Postgres 在函数和存储过程之间的界限相当模糊。您正在做的事情似乎可以在 Oracle 中运行,据我所知,它可能在 Postgres 中运行良好。

也就是说,您在 PostgreSQL 中“执行”存储过程的方式是简单地选择函数。本着这种精神,这是您的代码版本(经过一些重构——如果您不喜欢它,请原谅我),我非常有信心可以执行它:

using (NpgsqlCommand command = new NpgsqlCommand(
    "select Fifty(:CDE, :CPARA, :VDE, :VPARA, :IDP)", this.dllConexao.ConexaoBd))
{
    if (!dllConexao.open(Processadora.Comum.tipoConexao, 1, true))
    {
        clsRetorno.ret = 99;
        clsRetorno.msg = "Sistema temporariamente indisponível, " +
           "tente novamente mais tarde";
    }
    if (this.dllConexao.transactionIsOpen())
    {
        command.Transaction = this.dllConexao.TransacaoBd;
    }

    command.Parameters.Add("CDE", NpgsqlDbType.Bigint);
    command.Parameters.Add("CPARA", NpgsqlDbType.Bigint);
    command.Parameters.Add("VDE", NpgsqlDbType.Numeric);
    command.Parameters.Add("VPARA", NpgsqlDbType.Numeric);
    command.Parameters.Add("IDP", NpgsqlDbType.Bigint);

    command.Parameters[0].Value = cpfDe;
    command.Parameters[1].Value = cpfPara;
    command.Parameters[2].Value = valorDe;
    command.Parameters[3].Value = valorPara;
    command.Parameters[4].Value = idPagamento;

    command.ExecuteScalar();

    this.dllConexao.commitTransacao();
    this.dllConexao.closeTransaction();
}

我故意更改了参数的名称,以便与函数中的参数名称不匹配。这是因为没关系。只要您的 SQL 使用 :@ 列出参数的名称并且对应于您命名的 NpgSqlParameter 值,您就可以了去。

如果您的数据类型完全匹配(long、long、decimal、decimal、long),您甚至可以进一步重构这一步:

command.Parameters.AddWithValue("CDE", cpfDe);
command.Parameters.AddWithValue("CPARA", cpfPara);
command.Parameters.AddWithValue("VDE", valorDe);
command.Parameters.AddWithValue("VPARA", valorPara);
command.Parameters.AddWithValue("IDP", idPagamento);

另一个好处是,如果您确实有异常,我相信错误消息可能会很有帮助。

关于c# - 带有 c# 后端的 PostgreSQL 发送了无法识别的响应类型 : o,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41451991/

相关文章:

c# - 访问任务的结果属性

c# - 如何从共享类中访问 ViewState?

c# - 如何将 ItemsSource 绑定(bind)到多个集合?

c# - 如何从 Visual Studio 2012 导出 C# 应用程序以在其他计算机上运行?

ruby-on-rails - Postgres 问题 - Google Container Engine 上的 Ruby on Rails (Postgres)

postgresql - SQLAlchemy 在没有 to_tsvector 的 ts_vector 列上搜索

c# - 在Google Play商店中提交 “500 No individual errors”的原因

sql - PostgreSQL:间隔 '10 DAY' 和当前行之间的范围

sql - 什么是运行缓慢的 PostgreSQL 查询?

java - 如何配置 Spring Data 以在没有 XML 的情况下将 Postgres 与 Hibernate 一起使用?