【问题标题】:Getting error to: MySQL stored procedure with parameters in Access frontend via VBA获取错误:通过 VBA 在 Access 前端中使用参数的 MySQL 存储过程
【发布时间】:2017-08-24 10:56:23
【问题描述】:

Mysql 数据库具有参数化存储过程(插入语句),它可以从两个日期范围生成多个日期列表,间隔为 1 年,如下所示:

autoid  id  tenant_id   ag_id   interval_start  interval_end    rate
10       1     28         1       24/07/2016    23/07/2017        95
11       2     28         1       24/07/2017    23/07/2018       105
12       3     28         1       24/07/2018    23/07/2019       115

我正在尝试使用下面的 vba 代码从我的 Access 前端调用该过程:

单行插入语句

Dim cmd As ADODB.Command
Dim rst As ADODB.Recordset
Dim tid, int_r, inc_r As Long
Dim sdate, edate As Date
Dim strConn, strServer As String

strServer = "192.168.20.2"
strConn = "ODBC;MySQL ODBC 5.2 Unicode Driver;UID=admin;PORT=3306;DATABASE=tenant_db;PASSWORD=1DBServer;SERVER=" & strServer & ";FILEDSN=C:\Users\abzalali\Dropbox\tenant_db\tenant_db.dsn;"

tid = Me.tenant_id
int_r = Me.initial_rate
inc_r = Me.increase_rate
sdate = Format(Me.startdate, "yyyy-mm-dd")
edate = Format(Me.enddate, "yyyy-mm-dd")

Set cmd = New ADODB.Command

With cmd
    .ActiveConnection = strConn
    .CommandText = "CALL make_intervals_v2(" & tid & ", " & int_r & ", " & inc_r & ",  '" & sdate & "', '" & edate & "')"
    .CommandType = adCmdText
    .Execute
End With

MsgBox ("Done")
Me.Refresh

Set cmd = Nothing

程序可以很好地使用此代码运行,但只插入第一行。之后,我为总记录集添加了如下循环:

多行插入语句

Dim cmd As ADODB.Command
Dim rst As ADODB.Recordset
Dim tid, int_r, inc_r As Long
Dim sdate, edate As Date
Dim strConn, strServer As String

strServer = "192.168.20.2"
strConn = "ODBC;MySQL ODBC 5.2 Unicode Driver;UID=admin;PORT=3306;DATABASE=tenant_db;PASSWORD=1DBServer;SERVER=" & strServer & ";FILEDSN=C:\Users\abzalali\Dropbox\tenant_db\tenant_db.dsn;"

tid = Me.tenant_id
int_r = Me.initial_rate
inc_r = Me.increase_rate
sdate = Format(Me.startdate, "yyyy-mm-dd")
edate = Format(Me.enddate, "yyyy-mm-dd")

Set cmd = New ADODB.Command

With cmd
    .ActiveConnection = strConn
    .CommandText = "CALL make_intervals_v2(" & tid & ", " & int_r & ", " & inc_r & ",  '" & sdate & "', '" & edate & "')"
    .CommandType = adCmdText
     Set rst=.Execute
End With

Do Until rst.EOF
    rst.MoveNext
Loop

MsgBox ("Done")
Me.Refresh

Set rst = Nothing
Set cmd = Nothing

终于报错了:

不知道我实际上错过了什么。

这是我的实际存储过程:

DELIMITER @@
DROP PROCEDURE make_intervals_v2 @@
CREATE PROCEDURE tenant_db.make_intervals_v2
(IN `t_id` INT, IN `InitRate` INT, IN `IncrRate` INT, IN `dateStart` DATE, IN `dateEnd` DATE)
BEGIN
    DECLARE unitval VARCHAR(10);
    DECLARE intval INT;
    DECLARE done INT DEFAULT FALSE;
    DECLARE thisDate,nextDate DATE;
    DECLARE rate DECIMAL;
    DECLARE ag_id INT;



DECLARE l_ID integer;
DECLARE l_startdate,l_enddate DATE;
DECLARE l_ag_id integer;
DECLARE theCursor CURSOR FOR SELECT tenant_id, dateStart, dateEnd, 1 FROM tbl_tenant_basic_info WHERE active=1 AND tenant_id=t_id;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

SET unitval='YEAR';
SET intval=1;

drop temporary table if exists year_intervals2;
create temporary table year_intervals2
(   id int AUTO_INCREMENT primary key,
    tenant_id INT NOT NULL,
    ag_id INT NOT NULL,
    interval_start DATE NOT NULL,
    interval_end DATE NOT NULL,
    rate DECIMAL
);

OPEN theCursor;
read_loop: LOOP
    FETCH theCursor INTO l_ID,l_startdate,l_enddate, l_ag_id;
    IF done THEN
        LEAVE read_loop;
    END IF;
    set thisDate = l_startdate;
    set ag_id= l_ag_id;
    set rate = InitRate;

    repeat
      select
         case unitval
            when 'MICROSECOND' then timestampadd(MICROSECOND, intval, thisDate)
            when 'SECOND'      then timestampadd(SECOND, intval, thisDate)
            when 'MINUTE'      then timestampadd(MINUTE, intval, thisDate)
            when 'HOUR'        then timestampadd(HOUR, intval, thisDate)
            when 'DAY'         then timestampadd(DAY, intval, thisDate)
            when 'WEEK'        then timestampadd(WEEK, intval, thisDate)
            when 'MONTH'       then timestampadd(MONTH, intval, thisDate)
            when 'QUARTER'     then timestampadd(QUARTER, intval, thisDate)
            when 'YEAR'        then timestampadd(YEAR, intval, thisDate)
         end into nextDate;

        insert into year_intervals2 (tenant_id,interval_start,interval_end, rate, ag_id) select l_ID,thisDate, date_add(nextDate,INTERVAL -1 DAY), rate, ag_id;
      set thisDate = nextDate;
      set rate = rate+IncrRate;
    until thisDate >= l_enddate 
    end repeat;
END LOOP;
insert into tbl_agreement_years (id, tenant_id, ag_id, interval_start,interval_end, rate) 
select * from year_intervals2;
END @@ 
DELIMITER ; 

【问题讨论】:

  • 您在哪一行收到该错误?
  • 执行到 rst.EOF
  • 您的存储过程是否返回结果集?
  • 不知道。你能帮我吗,如何看到回报?
  • 你没有给我们提供实际的存储过程,所以我帮不了你。

标签: mysql vba ms-access stored-procedures parameter-passing


【解决方案1】:

您必须添加到 DB 的连接

Dim conn As ADODB.Connection

...

Set conn = New ADODB.Connection
conn.Open strConn  

...

With cmd
    .ActiveConnection = conn

    ...

    Set rst=.Execute
End With

编辑 1:向记录集循环添加额外检查

If rst.State= adStateOpen then
    Do Until rst.EOF
        rst.MoveNext
    Loop
End If

编辑2:关于“单行插入语句”问题:

这行存储过程捕获了所有select|fetch ... into ... 语句:

DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

read_loop 块中有两个,解决方案:

换行:

  select
     case unitval
        when 'MICROSECOND' then timestampadd(MICROSECOND, intval, thisDate)
        when 'SECOND'      then timestampadd(SECOND, intval, thisDate)
        when 'MINUTE'      then timestampadd(MINUTE, intval, thisDate)
        when 'HOUR'        then timestampadd(HOUR, intval, thisDate)
        when 'DAY'         then timestampadd(DAY, intval, thisDate)
        when 'WEEK'        then timestampadd(WEEK, intval, thisDate)
        when 'MONTH'       then timestampadd(MONTH, intval, thisDate)
        when 'QUARTER'     then timestampadd(QUARTER, intval, thisDate)
        when 'YEAR'        then timestampadd(YEAR, intval, thisDate)
     end into nextDate;

到:

  set nextDate = (select
     case unitval
        when 'MICROSECOND' then timestampadd(MICROSECOND, intval, thisDate)
        when 'SECOND'      then timestampadd(SECOND, intval, thisDate)
        when 'MINUTE'      then timestampadd(MINUTE, intval, thisDate)
        when 'HOUR'        then timestampadd(HOUR, intval, thisDate)
        when 'DAY'         then timestampadd(DAY, intval, thisDate)
        when 'WEEK'        then timestampadd(WEEK, intval, thisDate)
        when 'MONTH'       then timestampadd(MONTH, intval, thisDate)
        when 'QUARTER'     then timestampadd(QUARTER, intval, thisDate)
        when 'YEAR'        then timestampadd(YEAR, intval, thisDate)
     end );

【讨论】:

  • 是的,错误消失了,但它仍然只返回一行。这对我之前的单行插入语句来说很好。
  • @MirAbzalAli 我添加了第二个编辑,解决了这个问题
  • 当我在 MySql 中执行时,我的存储过程返回相同,并且在更改之后,SP 中的行(如您所推荐的)在我通过 VBA 执行时也像以前一样返回单行。我希望 VBA 站点出现问题,而不是 MySQL sp。仅供参考,当我将.CommandType = adCmdText 更改为.CommandType = adCmdStoredProc 时,它会产生另一个错误。它们之间有什么区别。
猜你喜欢
  • 2017-04-11
  • 2016-07-21
  • 1970-01-01
  • 2016-10-19
  • 1970-01-01
  • 1970-01-01
  • 2016-07-17
  • 2011-03-03
  • 1970-01-01
相关资源
最近更新 更多