2014-04-03 41 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

谢谢。我尝试了一些你的想法并更新了我的问题。你能再看一次吗?在尝试存储过程之前,我需要获得客户端的许可。 –