【问题标题】:PostgresException: 42883: function X(timestamp without time zone) does not exist when trying to call procedurePostgresException: 42883: 函数 X(timestamp without time zone) 在尝试调用过程时不存在
【发布时间】:2020-07-24 13:00:55
【问题描述】:

我正在尝试使用 .net 核心调用存储过程。

我遇到了This 问题。在解决了我之前的问题后,我遇到了另一个语法错误。

PostgresException: 42883: 函数 GetActiveUserPackagesForOpenBillingPeriod(timestamp without time zone) 在尝试调用过程时不存在

这是代码:

        var date = DateTime.Now;
        List<ActivePackageForOpenBillingPeriod> activeUserPackagesForOpenBillingPeriod = null;

        using (var conn = new NpgsqlConnection ("Host=localhost;Port=xxx;Database=postgres;Username=postgres;Password=xxx;TrustServerCertificate=true;ApplicationName=xxx;")) 
        {                
            var s = "Select * FROM \"GetActiveUserPackagesForOpenBillingPeriod\"({0})";
            activeUserPackagesForOpenBillingPeriod = context.ActivePackageForOpenBillingPeriods.FromSql (s, date).ToList ();

        }

存储过程

create or replace function "GetActiveUserPackagesForOpenBillingPeriod"(somedate timestamp without time zone) returns TABLE("Amount" numeric, "Package" integer, "User" integer, "Account" integer, "AcceptanceActID" integer, "HasChangedPackage" boolean)
language plpgsql
as
$$
DECLARE
    BEGIN
      RETURN QUERY
        SELECT
            up."TotalAmount",
            up."PackageID",
            u."ID" AS "UserId",
            a."ID" AS "AccountId",
            th."AcceptanceActID",


            CASE
                  WHEN count(DISTINCT tl."PackageID") IN (0,1)  THEN false
                  ELSE true
            END AS "HasChangedPackage"

        FROM public."Accounts" as a
            LEFT JOIN billing."TransactionHeaders" AS th ON th."AccountID" = a."ID"
            INNER JOIN security."Users" AS u ON u."AccountID"= a."ID"
            INNER JOIN billing."UserPackages" AS up ON up."UserID"=u."ID" AND COALESCE(th."Date", date) BETWEEN up."StartDate" AND COALESCE(up."EndDate", date)
            LEFT JOIN billing."TransactionLines" AS tl ON th."Id" = tl."TransactionHeaderID"

        WHERE th."AcceptanceActID" IS NULL AND a."StatusID"!=4 AND a."StatusID"!=3 AND up."StatusID"=1


        GROUP BY a."ID", u."ID", up."PackageID", 
up."TotalAmount",th."AcceptanceActID";
RETURN;

END;
$$;

alter function "GetActiveUserPackagesForOpenBillingPeriod"(timestamp)  
owner 
to postgres;

public class ActivePackageForOpenBillingPeriod {
    public int Id { get; set; }

    public int AccountID { get; set; }

    [ForeignKey ("AccountID")]
    public Account Account { get; set; }
    public int UserID { get; set; }

    [ForeignKey ("UserID")]
    public User User { get; set; }
    public int PackageID { get; set; }

    [ForeignKey ("PackageID")]
    public Package Package { get; set; }
    public decimal TotalAmount { get; set; }
    public bool HasChangedPackage { get; set; }

}

【问题讨论】:

  • 可能是search_path 问题。
  • 先尝试在postgre上直接调用函数
  • @JuanCarlosOropeza 我运行了这个 Select * FROM GetActiveUserPackagesForOpenBillingPeriod(to_date('20190101','YYYYDDMM')) 并且错误提示“函数 getactiveuserpackagesforopenbillingperiod(date) 不存在提示:没有函数匹配给定的名称和参数类型。您可能需要添加显式类型转换。位置:15"
  • 日期不是postgress中的关键字吗?
  • @cdev 是的。我将参数更改为“somedate”。还是一样的输出。我更改了查询中的参数。事实证明他们不按顺序。因此,在运行 select query IN db 后,我得到了理想的输出。但是,仍然面临同样的问题

标签: c# sql postgresql asp.net-core


【解决方案1】:

我通过使用解决了这个问题

> @DateFrom::DATE

代码如下。我使用 Dapper 来调用函数。

Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;
            var f = _connection.Query<GeneralLedgerForSubsidyAccount>(@"
                                                       SELECT * FROM 
                                                       edudb.Fn_General_Ledger_Subsidy_Account
                                                       (@SearchType, @DateFrom::DATE, @DateTo::DATE, @OpeningBalanceIncludeORExcluding, @ChartOfAccountsId)
                                                     ",
                                                     new
                                                     {
                                                         SearchType = search.SearchType,
                                                         DateFrom = search.DateFrom.Date,
                                                         DateTo = search.DateTo.Date,
                                                         OpeningBalanceIncludeORExcluding = search.OpeningBalanceIncludeORExcluding,
                                                         ChartOfAccountsId = search.ChartOfAccountsId
                                                     }).ToList();

我的函数定义如下

CREATE OR REPLACE FUNCTION edudb.Fn_General_Ledger_Subsidy_Account
(
    Search_Type character varying(50),
    date_from DATE,
    date_to DATE,
    Opening_Balance_Include_Or_Exclude  character varying(50),
    chart_of_accounts_id_p INTEGER
)

【讨论】:

    【解决方案2】:

    不要使用timestamp参数,必须使用varchar参数。 并在存储过程中更改时间戳的类型 varchar。

    【讨论】:

    • 您创建了函数“GetActiveUserPackagesForOpenBillingPeriod”,但在稍后的帖子中表明您调用了函数 getactiveuserpackagesforopenbillingperiod。那些不一样。当您定义将名称放在双引号 (") 中的对象时,名称会区分大小写,因此您必须使用引号和大小写完全相同。解决方案,不要使用引号。
    猜你喜欢
    • 2013-11-25
    • 2012-04-04
    • 2021-11-12
    • 1970-01-01
    • 2013-10-26
    • 1970-01-01
    • 2011-07-22
    • 2023-01-10
    • 1970-01-01
    相关资源
    最近更新 更多