【问题标题】:sql not executed calling another store proceduresql 未执行调用另一个存储过程
【发布时间】:2018-05-09 09:51:12
【问题描述】:

我在将存储过程从 Firebird 转换为 MySQL 时遇到问题,我是 mysql 存储过程的新手,所以请提供示例:( .

这是我当前转换后的代码:

DELIMITER $$

CREATE PROCEDURE INSERT_MRR_DETAIL (
    IN in_transactionindex INT,
    OUT monthyear INT,
    OUT day INT,
    OUT amount DOUBLE PRECISION,
    OUT acmountcumm DOUBLE PRECISION,
    OUT selisih DOUBLE PRECISION)
BEGIN
DECLARE v_customerindex INT;
DECLARE v_invoiceid INT;
DECLARE v_subscribe_date TIMESTAMP;
DECLARE v_subscribe_date_end TIMESTAMP;
DECLARE v_subscribe_sales DOUBLE PRECISION;
DECLARE v_month_days INT;
DECLARE v_month_effective_days INT;
DECLARE v_daily_amount_average DOUBLE PRECISION;
DECLARE v_lastmonthdate TIMESTAMP;
DECLARE v_month_start INT;
DECLARE v_year_start INT;
DECLARE v_month INT;
DECLARE v_year INT;
DECLARE v_month_end INT;
DECLARE v_year_end INT;
DECLARE v_amountcummulative DOUBLE PRECISION;
DECLARE v_month_amount DOUBLE PRECISION;
DECLARE v_subscribe_period_days INT;

SELECT  mrr_transaction.custid,
        mrr_transaction.invoiceid,
        mrr_transaction.datestart,
        mrr_transaction.dateend,
        mrr_transaction.amount
INTO    v_customerindex,
        v_invoiceid,
        v_subscribe_date,
        v_subscribe_date_end,
        v_subscribe_sales
FROM mrr_transaction
WHERE mrr_transaction.noindex = in_transactionindex;



SET v_subscribe_period_days = v_subscribe_date_end - v_subscribe_date + 1;

IF (v_subscribe_period_days > 0) THEN  -- Trapping Period not Zero / Null
BEGIN

  -- Define Variable Value
  SET v_month                       = extract(month from v_subscribe_date);
  SET v_year                        = extract(year from v_subscribe_date);
  SET v_month_start                 = v_month;
  SET v_year_start                  = v_year;
  SET v_month_end                   = extract(month from v_subscribe_date_end);
  SET v_year_end                    = extract(year from v_subscribe_date_end);
  SET v_daily_amount_average        = round( v_subscribe_sales / v_subscribe_period_days , 0);


  SET v_amountcummulative           = 0;


  WHILE ((v_year * 100 + v_month) <= (v_year_end * 100 + v_month_end)) DO
  BEGIN
      SET @sql = GET_EOMONTH(v_month, v_year);
      SELECT LASTDATE from @sql into v_lastmonthdate;
      SET monthyear             = v_year * 100 + v_month;
      SET v_month_days           = extract(day from v_lastmonthdate);
      SET v_month_effective_days = v_month_days;

      if ( (v_year * 100 + v_month) = (v_year_Start * 100 + v_month_start) ) then --Same with first month
            BEGIN
              v_month_effective_days = v_month_days - extract(day from v_subscribe_date) + 1;
            end
      END IF
      if ( (v_year * 100 + v_month) = (v_year_end * 100 + v_month_end) ) then    -- Same with last month
            BEGIN
              SET v_month_effective_days = extract(day from v_subscribe_date_end);
            END
      END IF

      SET v_month_amount        = v_daily_amount_average * v_month_effective_days;
      SET v_amountcummulative   = v_amountcummulative + v_month_amount;

      if ( (v_year * 100 + v_month) = (v_year_end * 100 + v_month_end) ) then    -- Same with last month
            BEGIN
              SET v_month_amount = v_month_amount + v_subscribe_sales - v_amountcummulative ;

            END
      END IF

   update mrr_Detail set isactive='F'
        where yearmonth= v_year*100 + v_month and
              transactionid = IN_TRANSACTIONINDEX;
   insert into mrr_detail(
                        custid,
                        invoiceid,
                        transactionid,
                        day,
                        month,
                        year,
                        amount,
                        yearmonth,
                        isactive)
                values(
                        V_CUSTOMERINDEX,
                        v_invoiceid,
                        IN_TRANSACTIONINDEX,
                        V_MONTH_EFFECTIVE_DAYS,
                        v_month,
                        v_year,
                        v_month_amount,
                        v_year*100 + v_month,
                        'T');

      -- Temporary Output Checking
      SET day = v_month_effective_days;
      SET amount = v_month_amount;
      SET AMOUNTCUMM = v_amountcummulative;
      SET selisih =   v_subscribe_sales - v_amountcummulative ;

      -- next month
      SET v_month = v_month+1;
      if (v_month = 13) then
        BEGIN
          SET v_month = 1;
          SET v_year = v_year + 1;
        END
      END IF

  END
  END WHILE;
END
END$$
DELIMITER ;

当我在 HeidiSql 中运行上面的代码时,错误来了:

SQL 错误 (1064):您的 SQL 语法有错误;检查 与您的 MySQL 服务器版本相对应的手册 'CALL GET_EOMONTH(v_month, v_year); 附近使用的语法 SELECT LASTDATE from @sql into v_lastm' at line 63 *

任何帮助或建议将不胜感激 谢谢。

已编辑------------------

我想将我的代码修改成这样:

SET @output_variable = 0;
  call GET_EOMONTH(v_month, v_year, @output_variable);

  SELECT LASTDATE from @output_variable into v_lastmonthdate;

但是错误,我想要“FROM {动态输出来自 GET EOMONTH}”... 我该怎么做?

【问题讨论】:

  • get_eomonth 是什么样的?
  • @P.Salmon This link
  • 哦,等等,这与您创建过程的上一个问题有关。您只能 CALL 一个您尝试将一个过程用作函数的过程,您可能应该将 get_eomonth 重写为一个函数。
  • 所以我需要将 get_eomonth 重写为另一个名称的函数? @P.鲑鱼
  • 也许这将阐明函数和过程之间的区别stackoverflow.com/questions/3744209/… - 由您决定哪个最合适。

标签: mysql database stored-procedures


【解决方案1】:

您可能正在调用存储过程,在 MySQL 中,该过程不直接返回值(但函数会)您可以在 GET_EOMONTH 过程中添加一个 OUT 参数作为第三个参数。

之后,您可以使用该变量调用存储过程:

  SET @output_variable = 0;
  call GET_EOMONTH(v_month, v_year, @output_variable);
  -- do something with @output_variable
  if @output_variable > 0 then
    set v_lastmonthdate = @output_variable; 
  end if;

但是,如果你有一个函数,代码会变成这样:

  set @output_variable = GET_EOMONTH(v_month, v_year);
  -- do something with @output_variable
  if @output_variable > 0 then
    set v_lastmonthdate = @output_variable; 
  end if;

编辑:

如果你的@output_variable 中有一个表名,那么你必须使用准备好的语句:

-- use a session variable to get value from prepared statement 

set @lasmontdate_session_var = ''; -- or any value of you choose
set @sql = concat('SELECT LASTDATE from ',@output_variable,' into  @lasmontdate_session_var LIMIT 1 '); -- add limit to prevent error
prepare stmt from @sql;
execute stmt ;
deallocate prepare stmt;

-- at this point @lasmontdate_session_var contains the result of prepared query

【讨论】:

  • 这个例子是过程中的过程还是过程中的函数?因为我在我的 GET_EOMONTH 程序中添加了OUT
  • @NasihunAminSuhardiyan 我忘了提GET_EOMONTH是否是一个函数
  • 我修改了我的问题,请看一下
  • @NasihunAminSuhardiyan 我在回答中添加了更多信息
猜你喜欢
  • 2010-09-15
  • 2013-03-26
  • 1970-01-01
  • 1970-01-01
  • 2012-02-10
  • 1970-01-01
  • 1970-01-01
  • 2011-03-31
  • 1970-01-01
相关资源
最近更新 更多