2014-04-03 40 views
0

*更新到下面* 我決定放棄執行該文件,並決定通過ADO.Execute傳遞一個長查詢字符串,將UseTransaction設置爲True,並且不返回任何記錄集。我遇到了一個新問題,只有一些記錄被插入,儘管錯誤代碼是0.總的執行時間不到一秒鐘。命令超時爲30,連接超時爲15.如何從Excel VBA代碼執行.SQL文件?

在查詢中,我正在運行6次刪除,然後通常超過54次插入。大約32個插入的行實際上出現在數據庫中,並且查詢的其餘部分被忽略,並且沒有返回錯誤。也許SQL服務器端有一個超時,最大字符串長度或它可以從ADO接受的最大命令數?如果我將整個查詢直接粘貼到SQL Server Management Studio中,則無論其執行時間多長都會執行。似乎有一個SQL Server端的限制。想法? *結束更新*

我用我的Excel數據生成一個複雜的查詢,將其發送到文件中。查詢鎖定DB,刪除記錄,使用@變量生成新密鑰並在INSERT語句中使用@變量。最後,它運行一個COMMIT語句。 .sql文件中至少有100個語句。

生成.sql文件後,我想從代碼執行文件並獲得成功狀態。我希望一次性完成此操作,而不是單擊DB 100或更多時間並檢查每個語句的狀態。

我已經嘗試在網上搜索答案,但沒有運氣追蹤它。

我該怎麼做?

如果我不能觸發該文件,我想我將不得不單獨運行每個語句(鎖定數據庫,運行單個刪除,運行單個插入),在每個語句之後檢查成功。如果一切正常,我會提交,否則請執行ROLLBACK。這會工作嗎?

謝謝。

如果有幫助,下面是我的SQL文件的示例,以瞭解包含哪些類型的語句。

use MY_DB_NAME; 
declare @i_xseq int; 
declare @deleteBeforeInsert int; 
set @deleteBeforeInsert = 1; 

begin transaction MyTransaction; 


-- *********************************** DELETE FUTURE EVENTS 
-- Delete all future records using application ID 12 and having a start date after the start date: 

if (@deleteBeforeInsert = 1) 
BEGIN 

    delete from dbo.TableA 
where EVENT_XSEQ in (select X_SEQ from dbo.TAbleB where START > CAST('2014-03-26 14:22:01' as datetime) and APPLICATION_ID = 12); 
END 

-- ************************************ GET NEXT SEQUENCE # 
-- begin retrieve new @i_xseq 
select @i_xseq=LAST_ID from [dbo].[AKey] WITH (XLOCK,READPAST) where TABLE_NAME = 'TableB'; 
Update [dbo].[AKey] 
Set LAST_ID = LAST_ID + 1 
where TABLE_NAME = 'TableB'; 

select @i_xseq=LAST_ID from [dbo].[AKey] where TABLE_NAME = 'TableB'; 
-- end retrieve new @i_xseq 

-- RUN Inserts (many) 
insert into dbo.TableB 
    (VAL1, VAL2,X_SEQ) 
Values 
    (1110, 37673.70, @i_xseq); 

-- ************************************* END AND COMMIT 
insert into dbo.SCHEDULE_LOG 
(DESCRIPTION, X_UPDATED, X_BY) 
Values 
('Close_Scheduling', CURRENT_TIMESTAMP, 'MY_ID'); 

COMMIT transaction MyTransaction; 

回答

0

在一個單獨的模塊中創建一個函數或過程,將SQL語句中的所有行寫入字符串。將該字符串傳遞到打開的數據庫連接。 您需要在項目中包含「Mircosoft ActiveX Data Objects Library」。

Public Function rstSomeName() 

Dim sSql As String 

sSql = "" 
sSql = sSql & "use MY_DB_NAME;        " & vbCrLf 
sSql = sSql & "declare @i_xseq int;       " & vbCrLf 
sSql = sSql & " etc.. to the end of you sql statement  " & vbCrLf 


Set rstSomeName= New ADODB.Recordset 
rstSomeName.Open sSql, "Your Database Connection String" 

End Function 
+0

該字符串將處理超過100,000個字符?你知道我會從運行一個像這樣的大查詢得到什麼樣的錯誤返回?你認爲我應該放棄提交/回滾語句,檢查錯誤狀態,然後發送提交或回滾,還是最終的語句必須是第一個事務的一部分? –

+0

VBA字符串的限制大約是2GB,大約是20億個字符。我會更關心你是否能夠通過你的數據連接傳遞很多東西,這可能是什麼。在那種情況下。爲什麼不把它創建爲存儲過程,只需從vba代碼中調用它?任何錯誤都是Oracle返回的錯誤,您可以在錯誤時處理。最後,如果它現在在數據庫上運行,而不是將它傳遞給數據庫,則不必修改任何SQL代碼也不應該成爲問題。 – keithD

+0

謝謝。我嘗試了一些你的想法並更新了我的問題。你能再看一次嗎?在嘗試存儲過程之前,我需要獲得客戶端的許可。 –