存储过程错误“例程的参数 1..不是 BEFORE 触发器中的变量或新的伪变量”

本文关键字:变量 触发器 BEFORE 不是 错误 例程 参数 例程的参数 存储过程 | 更新日期: 2023-09-27 17:56:36

DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `Get_Next_Processing_Video`(   
    OUT out_IDVideo                   INT ,
    OUT out_YoutubeIDVideo            VARCHAR(15) 
)
BEGIN
    DECLARE a INT;
    DECLARE b VARCHAR(15);
    set a = 0;
    set b = "ciao";
    SELECT  NP.IDVideo, NP.YoutubeIDVideo INTO a, b 
    FROM    next_processing AS NP
    LIMIT 1; 
    UPDATE  Video AS V 
    SET     V.SchedulingFlag = TRUE
    WHERE   IDVideo = a;
SET out_IDVideo = a;
SET out_YoutubeIDVideo = b;
END

MySQL 返回:

OUT 或 INOUT 参数 1 用于常规 youtubedb。Get_Next_Processing_Video 不是 BEFORE 触发器中的变量或新的伪变量。

问题出在哪里?代码似乎是正确的。

这是我的调用过程的 C# 代码:

using (MySqlConnection conn = new MySqlConnection(ConfigurationManager.ConnectionStrings["AxWaveConnection"].ToString()))
        {
            try
            {
                conn.Open();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            MySqlCommand cmd = new MySqlCommand("Get_Next_Processing_Video", conn);
            cmd.CommandType = System.Data.CommandType.StoredProcedure;
            cmd.Parameters.Add(new MySqlParameter("out_IDVideo", idVideo));
            cmd.Parameters.Add(new MySqlParameter("out_YoutubeIDVideo", youtubeId));
            try
            {
                cmd.ExecuteNonQuery();  
            }
            catch (Exception e)
            {
            }
            conn.Close();
        }

存储过程错误“例程的参数 1..不是 BEFORE 触发器中的变量或新的伪变量”

我认为问题出在您调用该程序上。

对于不支持OUT参数的 MySQL 连接器版本,正常的解决方法是使用 MySQL 用户变量来保存返回值,然后运行查询以获取这些变量的值。

首先,执行存储过程,并让MySQL将OUT参数的值放入变量中:

CALL `Get_Next_Processing_Video`(@IDVideo, @YoutubeIDVideo);

请注意,这些变量不是命令参数;它们是保存在MySQL会话中的变量。要获取这些变量的值,请在调用过程后立即使用相同的MySQL连接:

SELECT @IDVideo, @YoutubeIDVideo ;

并处理来自该查询的结果集,就像处理您希望返回一行的任何其他 SELECT 语句一样。


更新:

对于支持 OUT 参数的最新版本的 MySQL 连接器,我认为您需要通过设置成员属性来指定这些参数是 OUT 参数:

cmd.Parameters["out_IDVideo"].Direction = ParameterDirection.Output;
cmd.Parameters["out_YoutubeIDVideo"].Direction = ParameterDirection.Output;

正如我之前指出的...

在不支持OUT参数的旧版本的MySQL连接器中,解决方法是使用MySQL变量作为参数调用该过程。从过程调用返回的值保留在 MySQL 会话中。调用该过程后,我们将立即运行 SELECT 来检索用户变量的内容。

遇到

同样的问题,从构建器 c++ 调用存储过程以创建批处理记录,其中调用成功而其他调用则不成功。

CREATE DEFINER=`root`@`localhost` PROCEDURE `article_import`(IN `idclient` INT(11) UNSIGNED, IN `code` VARCHAR(16), IN `shortdesc` VARCHAR(16),
                                        IN `descrip` VARCHAR(32),IN `status` VARCHAR(12), IN `fifo` SMALLINT(1), IN `maxfifo` SMALLINT(3),
                                        IN `flvduration` SMALLINT(3),IN `retendays` SMALLINT(3), IN `maxconserv` SMALLINT(3),
                                        IN `flcduration` SMALLINT(3), IN `flvunits` SMALLINT(1),IN `conservunits` SMALLINT(1),
                                        IN `flcunits` SMALLINT(1), IN `entrymode` SMALLINT(1), IN `exitmode` SMALLINT(1),
                                        IN `section` SMALLINT(1), IN `family` SMALLINT(1), IN `origen` SMALLINT(1), IN `mgroup` SMALLINT(1),
                                        IN `sgroup` SMALLINT(1), IN `invclass` SMALLINT(1), IN `created` DATE, INOUT `result` VARCHAR(64)) 
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
  BEGIN
  GET DIAGNOSTICS CONDITION 1 @sqlstate = RETURNED_SQLSTATE, @errno = MYSQL_ERRNO, @text = MESSAGE_TEXT;
  SET result = CONCAT('KO:', @text,':',@errno);
END;
INSERT INTO articles_imp (`idclient`,`code`,`shortdesc`,`descrip`,`status`,`fifo`,`maxfifo`,`flvduration`,`retendays`,`maxconserv`,
                                        `flcduration`,`flvunits`,`conservunits`,`flcunits`,`entrymode`,`exitmode`,`section`,`family`,
                                        `origen`,`mgroup`,`sgroup`,`invclass`,`created`)
      VALUES  (idclient,code,shortdesc,descrip,status,fifo,maxfifo,flvduration,retendays,maxconserv,
                                        flcduration,flvunits,conservunits,flcunits,entrymode,exitmode,section,family,
                                        origen,mgroup,sgroup,invclass,created);
SET result = CONCAT('OK:inserted:',LAST_INSERT_ID());
END

我查找了 myodbc.sql通过将日志查询设置为...复选框生成的 MySql 连接器/ODBC 数据源配置的"调试"选项卡中,并发现了成功和不成功调用之间的区别:

1418923873:使用预准备语句;
1418923873:拨打article_import(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ;
1418923873:SSPS 已被执行;
1418923873:查询已执行;

1418923873: 呼叫article_import(355, '20804', '', 'ANCHOAS ACEITE TIRAS90GRS', '', 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

0, '2014-12-18', '') ;
1418923873:采用直接执行;
1418923873:查询已执行;
例程gedispa.article_import的 1418923873:OUT 或 INOUT 参数 24 不是 BEFORE 触发器中的变量或 NEW 伪变量;

在生成器中,ADOStoredProc 具有 Prepare 属性,但将其设置为 true 没有任何区别。最后,我将结果参数声明为 INOUT 参数而不是 OUT 参数并修复了它。

没有日志,我们什么都不是。

我修复了将方向添加到所有变量的相同错误:

MySQL SP 参数:

OUT P_IDAGENTE_NETWORK int(11),
INOUT P_PROTOCOLO varchar(45)

C# 代码:

new MySqlParameter("P_IDAGENTE_NETWORK",0){Direction = ParameterDirection.Output},
new MySqlParameter("P_PROTOCOLO", network.Protocol){Direction=ParameterDirection.InputOutput}