任何人都可以协助 postgresql 中函数的语法(来自 mysql)

发布于 2025-01-11 06:55:12 字数 778 浏览 0 评论 0原文

我试图在 PostgreSQL 中创建以下函数,但出现以下错误。这是来自我需要转换为 PostgreSQL 的 MySQL 过程。我无法将语法转换为 PostgreSQL。我是 PostgreSQL 的初学者。请帮助我。

CREATE OR REPLACE FUNCTION public.usp_failed_analyze4()
RETURNS TABLE(status varchar) as
$BODY$
    SET @maxdate = (SELECT MAX(analyzetime) FROM  wp_analyze_history);
    SET @maxdateint = (SELECT DATEDIFF(NOW() ,MAX(analyzetime)) FROM  wp_analyze_history);
    SET @STATUS = SELECT Status from wp_analyze_history WHERE Status NOT IN ('OK','Table is already up to date','The Analyze task DID NOT run!') AND  analyzetime = @maxdate);
    SET @STATUSNOTRUN = 'The Analyze task DID NOT run!';
    IF @maxdateint > 7
    THEN SELECT @STATUSNOTRUN;
    ELSE SELECT @STATUS as "";
$BODY$
    LANGUAGE sql;

错误:错误:“@”处或附近的语法错误 位置:109

I am trying to create the following function in PostgreSQL but get the following error. This is from a MySQL procedure that I need to convert to PostgreSQL. I am failing to convert the syntax to PostgreSQL. I am a beginner in PostgreSQL. Please assist me.

CREATE OR REPLACE FUNCTION public.usp_failed_analyze4()
RETURNS TABLE(status varchar) as
$BODY$
    SET @maxdate = (SELECT MAX(analyzetime) FROM  wp_analyze_history);
    SET @maxdateint = (SELECT DATEDIFF(NOW() ,MAX(analyzetime)) FROM  wp_analyze_history);
    SET @STATUS = SELECT Status from wp_analyze_history WHERE Status NOT IN ('OK','Table is already up to date','The Analyze task DID NOT run!') AND  analyzetime = @maxdate);
    SET @STATUSNOTRUN = 'The Analyze task DID NOT run!';
    IF @maxdateint > 7
    THEN SELECT @STATUSNOTRUN;
    ELSE SELECT @STATUS as "";
$BODY$
    LANGUAGE sql;

error: ERROR: syntax error at or near "@"
Position: 109

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

绝不服输 2025-01-18 06:55:12

当您尝试 1:1 复制 MySQL 时,很难说出您想要什么。

但是,您的代码中存在几个问题:

  1. 语言sql没有变量或IF语句。您需要使用 PL/pgSQL(语言 plpgsql
  2. PL/pgSQL 需要一个 declare 块来声明所有变量,实际代码需要一个 begin ... end ; 也阻止。
  3. 您可以使用 SET分配
  4. 将单行查询的结果存储在变量中使用 select ... into ... from
  5. 字符 @ 在 SQL 中无效标识符,不能用于变量名(遵循 SQL 标识符的规则)。在 Postgres 中,一个常见的习惯是在变量前面加上一些前缀,以避免列名产生歧义。我使用 l_ 作为局部变量(但这完全是个人喜好)
  6. 您似乎不想返回多行,而是返回单个值。因此,您不需要 returns table
  7. 从函数返回某些内容,使用return而不是select

将所有这些放在一起,它应该看起来像这样:

CREATE OR REPLACE FUNCTION usp_failed_analyze4()
  RETURNS varchar -- return a single value
AS
$BODY$
declare
  l_maxdate timestamp;
  l_maxdatediff interval;
  l_status text;
  l_statusnotrun text;
begin    
    select MAX(analyzetime), current_timestamp - MAX(analyzetime)
      into l_maxdate, l_maxdatediff
    FROM  wp_analyze_history;

    SELECT Status 
      into l_status
    from wp_analyze_history 
    WHERE Status NOT IN ('OK','Table is already up to date','The Analyze task DID NOT run!') 
      AND analyzetime = l_maxdate;
      
    l_statusnotrun := 'The Analyze task DID NOT run!';
    IF l_maxdatediff > interval '7 days' 
    THEN 
      return l_statusnotrun;
    ELSE 
      return ''; -- strings are enclosed in single quotes in SQL
    end if;
end;
$BODY$
LANGUAGE plpgsql;

仍然有空间很多优化,但这尽可能匹配您的初始代码。

It's hard to tell what you want as you tried to copy the MySQL 1:1.

However, there are several problems in your code:

  1. language sql does not have variables or IF statements. You need to use PL/pgSQL (language plpgsql)
  2. PL/pgSQL requires a declare block to declare all variables and the actual code needs a begin ... end; block as well.
  3. You can use SET for assignment
  4. To store the result of a single row query in a variable use select ... into ... from
  5. The character @ is invalid in an SQL identifier and can't be used for variable names (which follow the rules of SQL identifiers). In Postgres it's a common habit to prefix variable with something to avoid ambiguity with column names. I use l_ for local variables (but that's completely a personal preference)
  6. You don't seem to want to return multiple rows, but a single value. So you don't need returns table
  7. To return something from a function, use return not select

Putting that all together it should look something like this:

CREATE OR REPLACE FUNCTION usp_failed_analyze4()
  RETURNS varchar -- return a single value
AS
$BODY$
declare
  l_maxdate timestamp;
  l_maxdatediff interval;
  l_status text;
  l_statusnotrun text;
begin    
    select MAX(analyzetime), current_timestamp - MAX(analyzetime)
      into l_maxdate, l_maxdatediff
    FROM  wp_analyze_history;

    SELECT Status 
      into l_status
    from wp_analyze_history 
    WHERE Status NOT IN ('OK','Table is already up to date','The Analyze task DID NOT run!') 
      AND analyzetime = l_maxdate;
      
    l_statusnotrun := 'The Analyze task DID NOT run!';
    IF l_maxdatediff > interval '7 days' 
    THEN 
      return l_statusnotrun;
    ELSE 
      return ''; -- strings are enclosed in single quotes in SQL
    end if;
end;
$BODY$
LANGUAGE plpgsql;

There is still room for a lot of optimization, but this matches your initial code as much as possible.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文