2015-11-18 71 views
0

我有一個使用OTA API查詢HP ALM數據庫的VBA腳本。如何在VBA腳本中編寫CTE遞歸查詢?

我想使用遞歸CTE查詢數據庫。我不知道如何在該VBA腳本中編寫該腳本。

VBA腳本:::

Sub Extractor() 

    Const QCADDRESS = "http://alm/qcbin" 
    Const DOMAIN = "DOMAIN" 
    Const PROJECT = "PROJECT" 
    Const QCUSR = "user.name" 
    Const QCPWD = "123456" 

    Dim QCConnection, com, recset 
    Dim XLS, Wkb, Wks, i 

    Set QCConnection = CreateObject("TDApiOle80.TDConnection") 
    QCConnection.InitConnectionEx QCADDRESS 
    QCConnection.Login QCUSR, QCPWD 
    QCConnection.Connect DOMAIN, PROJECT 

    Set com = QCConnection.Command 

    com.CommandText = "Select * from ALL_LISTS" 

    Set recset = com.Execute 

    Set XLS = CreateObject("Excel.Application") 
    XLS.Visible = False 
    Set Wkb = XLS.Workbooks.Add 
    Set Wks = Wkb.Worksheets(1) 

    i = 1 
    Wks.Cells(i, 1).Value = "Data" 


    If recset.RecordCount > 0 Then 
    i = 2 
    recset.First 
    Do While Not (recset.EOR) 
    Wks.Cells(i, 1).Value = recset.FieldValue(0) 'fieldvalue(0) because the query extract only 1 field. 
    i = i + 1 
    recset.Next 
    Loop 
    Wkb.SaveAs "C:\myfile.xls" 
    End If 


    Wkb.Close 
    XLS.Quit 

    QCConnection.Disconnect 

    Set recset = Nothing 
    Set com = Nothing 
    Set QCConnection = Nothing 
    Set XLS = Nothing 
    Set Wkb = Nothing 
    Set Wks = Nothing 


End Sub 

CTE查詢::::

with ReqCTE 
as 
(
SELECT 
RQ_REQ_ID, 
RQ_REQ_NAME, 
RQ_FATHER_ID, 
0 as lvl 
FROM 
td.REQ 
where 
RQ_REQ_ID = {?Father_ID} 

union all 

select 
Folders.RQ_REQ_ID, 
Folders.RQ_REQ_NAME, 
Folders.RQ_FATHER_ID, 
Child.lvl +1 
from 
ReqCTE as Child 
join td.REQ as Folders on Folders.RQ_REQ_ID = Child.RQ_FATHER_ID 
); 

select * from ReqCTE; 
+0

VBA中的scipt與SQL-Server中的相同。只需將SQL-Statemen放入一個字符串變量並打開一個記錄集 – CPMunich

+0

它可以用於多個語句查詢嗎? –

+1

是的。讀完所有行後,您需要使用['NextRecordset'](https://msdn.microsoft.com/en-us/library/ms677539%28v=vs.85%29.aspx)語句來開始下一行的行。 – Richard

回答

1

這裏是你的代碼查詢嵌入式和您的查詢變量聲明爲VBA變量和引用SQL腳本:

Sub Extractor() 

    Const QCADDRESS = "http://alm/qcbin" 
    Const DOMAIN = "DOMAIN" 
    Const PROJECT = "PROJECT" 
    Const QCUSR = "user.name" 
    Const QCPWD = "123456" 
    Dim par(0) As Variant 

    Dim QCConnection, com, recset 
    Dim XLS, Wkb, Wks, i 

    Set QCConnection = CreateObject("TDApiOle80.TDConnection") 
    QCConnection.InitConnectionEx QCADDRESS 
    QCConnection.Login QCUSR, QCPWD 
    QCConnection.Connect DOMAIN, PROJECT 

    Set com = QCConnection.Command 
    par(0) = 4 'set parameter value for Father_ID in SQL 

    com.CommandText = "with ReqCTE as (" & _ 
         "SELECT RQ_REQ_ID, RQ_REQ_NAME, RQ_FATHER_ID, 0 as lvl FROM td.REQ " & _ 
         "where RQ_REQ_ID = ? " & _ 
         "Union all " & _ 
         "select Folders.RQ_REQ_ID, Folders.RQ_REQ_NAME, Folders.RQ_FATHER_ID, Child.lvl +1 from ReqCTE as Child " & _ 
         "join td.REQ as Folders on Folders.RQ_REQ_ID = Child.RQ_FATHER_ID); " & _ 
         "select * from ReqCTE;" 


    Set recset = com.Execute(, par) 

    Set XLS = CreateObject("Excel.Application") 
    XLS.Visible = False 
    Set Wkb = XLS.Workbooks.Add 
    Set Wks = Wkb.Worksheets(1) 

    i = 1 
    Wks.Cells(i, 1).Value = "Data" 


    If recset.RecordCount > 0 Then 
    i = 2 
    recset.First 
    Do While Not (recset.EOR) 
    Wks.Cells(i, 1).Value = recset.FieldValue(0) 'fieldvalue(0) because the query extract only 1 field. 
    i = i + 1 
    recset.Next 
    Loop 
    Wkb.SaveAs "C:\myfile.xls" 
    End If 


    Wkb.Close 
    XLS.Quit 

    QCConnection.Disconnect 

    Set recset = Nothing 
    Set com = Nothing 
    Set QCConnection = Nothing 
    Set XLS = Nothing 
    Set Wkb = Nothing 
    Set Wks = Nothing 


End Sub 

更新,以避免注射

+0

這是一個SQL注入漏洞:***總是***使用參數。 – Richard

+0

有三部分原因。首先總是使用參數,避免在需要重新使用代碼時需要決定何時(以及更新參數)。其次,隨着劇本的擴展和重用,價值開始來自參數......。第三,這意味着你不需要考慮字符串中的引用或日期格式:它簡化了代碼。 – Richard

+0

恕我直言,避免開發人員看到導致許多黑客成功(可能比任何其他漏洞原因更多)的做法是每個人的工作。 – Richard