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

时间:2017-01-03 20:41:17

标签: 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#并调用execute non query时,我收到以下消息错误: 后端发送了无法识别的响应类型:o

我可以在Postgres控制台中正常运行该功能,它完全正常。 我认为是返回类型,但我不知道应该返回什么才能获得执行成功。 EDITED 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();

                }

1 个答案:

答案 0 :(得分:1)

在我看来,Postgres在函数和存储过程之间的界限相当模糊。你正在做什么似乎它可以在Oracle中工作,并且它可能在Postgres中工作得很好。

那说,你执行的方式&#34; PostgreSQL中的存储过程只是select函数。本着这种精神,这是你的代码的一个版本(有一些重构 - 如果你讨厌的话,请原谅我),我相信它会执行:

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值相对应,您就可以了。

如果您的数据类型完美匹配(长,长,十进制,十进制,长),您甚至可以进一步重构这一步:

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);

另一件好事就是如果你有异常,我相信错误信息可能会非常有用。