我正在尝试执行以下函数,例如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();
}
答案 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);
另一件好事就是如果你有异常,我相信错误信息可能会非常有用。