为什么我在 .Net 中通过 npgsql 得到异常 运行 一个函数(存储过程)?

Why am I getting exceptions running a function (stored procedure) through npgsql in .Net?

我有一个 .Net 应用程序,它使用 NpgsqlPostgresql 数据库对话。网。 我有一个 postgresql 函数,我试图通过 Npgsql 调用它。 当我直接在 pgadmin 中 运行 时,函数 运行 没问题。 但是,当我从我的 .Net (C#) 应用程序 运行 它时,它抛出异常。

这是函数的 "cleansed" 版本:

CREATE OR REPLACE FUNCTION Function1(id_param integer, 
                                    date1_param date, 
                                    date2_param date)
RETURNS TABLE (
            field1 character varying,
            field2 character varying,
            field3 bigint)
AS $$
BEGIN

    RETURN QUERY 

        SELECT table1.field1,
            table2.field2,
            table3.field3
        FROM table1 
            LEFT JOIN table2 on table1.empno = table2.empno 
            LEFT JOIN public.table3 on table1.docnum = table3.number 
        WHERE table1.entrydate >= date1_param
            AND table2.date1 >= date1_param
            AND table2.date2 <= date2_param;
    END;
$$ LANGUAGE plpgsql;  

这是我在 运行 时得到的异常:

{"42P01: invalid reference to FROM-clause entry for table \"table1\""}

我的函数中的 JOIN 语句有什么问题导致了这个异常?

谢谢, 约翰B

我不能确定哪里出了问题,但我可以告诉您我在 NpgSql 中成功调用函数的秘诀并将其应用到您的示例中。

首先,您的代码,据我所知:

NpgsqlCommand command = null; 
DataTable dtResults = new DataTable(); 
command = new NpgsqlCommand(); 
command.Connection = connection; 
command.CommandType = CommandType.StoredProcedure; 
command.CommandText = functionName; 
NpgsqlDataAdapter da = new NpgsqlDataAdapter(command); 
da.Fill(dtResults);

在 PostgreSQL 中,函数和存储过程之间有一条模糊的界限(在我的最佳评估中)。为了调用函数,最简单的方法是使用 select,即使它没有 return 任何东西(虽然你的有),然后使用普通的 DbDataReaderDbDataAdapter.

此外,您上面的示例保证参数,none 其中出现在 C# 调用中。

最后,存储过程没有显示完全限定的表。是否有可能 运行 作为 psql 中与 .NET 应用程序中不同的用户 ID?无论哪种方式,添加模式名称都没有坏处。

这是我为您的 .NET 代码推荐的内容:

NpgsqlCommand command = new NpgsqlCommand("select * from Function1(:ID, :DATE1, :DATE2)",
    connection);
command.Parameters.Add(new NpgsqlParameter("ID", NpgsqlDbType.Integer));
command.Parameters.Add(new NpgsqlParameter("DATE1", NpgsqlDbType.Date));
command.Parameters.Add(new NpgsqlParameter("DATE2", NpgsqlDbType.Date));

command.Parameters[0].Value = id;
command.Parameters[1].Value = dt1;
command.Parameters[2].Value = dt2;

DataTable dtResults = new DataTable();
NpgsqlDataAdapter da = new NpgsqlDataAdapter(command);
da.Fill(dtResults);

同样,即使您不需要它们,我也会在表和函数前面添加架构名称。