2017-08-24 21 views
1

Mysql數據庫具有參數化存儲過程(insert語句),使多個日期列表用1年的間隔,從兩個日期範圍如下圖所示:獲取錯誤:通過VBA在訪問前端MySQL的存儲過程的參數

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-代碼我訪問前端調用過程:

單列插入statment

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 

過程很好地使用此代碼運行,但只插入第一行。從那以後,我增加了循環總記錄如下圖所示:

多行INSERT statment

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 

最後我得到的錯誤:

enter image description here

不知道是什麼我真的錯過了。

這裏是我的實際存儲過程:

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 ; 
+0

您在哪一行得到該錯誤? –

+0

直到rst.EOF –

+0

您的存儲過程是否返回結果集? –

回答

0

您必須添加一個連接到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:關於 「單行INSERT語句」 的問題:

存儲過程的這條線捕獲所有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); 
+0

顯示相同的錯誤 –

+0

@MirAbzalAli添加了更多代碼以避免錯誤 –

+0

是的,錯誤消失了,但它仍然只返回單行。這很好,我以前的***單行插入語句***。 –