我正在尝试执行以下函数,例如 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/