Sql server 关闭对象时不允许Excel VBA-SQL调用-操作

Sql server 关闭对象时不允许Excel VBA-SQL调用-操作,sql-server,excel,ssms-2014,vba,Sql Server,Excel,Ssms 2014,Vba,我有几个宏可以调用SSMS 2014来运行查询,并在工作表中定义的单元格中返回结果。它们工作成功,但当我尝试对临时表使用某些查询时,会收到以下错误消息: 我在网上进行了研究,我能找到的最好答案是在我的查询开始处添加设置NOCOUNT ON。我试过了,但还是得到了同样的信息 调试带给我的代码如下: Dim cnn As New ADODB.Connection Dim rst As New ADODB.Recordset Dim ConnectionString As String Dim St

我有几个宏可以调用SSMS 2014来运行查询,并在工作表中定义的单元格中返回结果。它们工作成功,但当我尝试对临时表使用某些查询时,会收到以下错误消息:

我在网上进行了研究,我能找到的最好答案是在我的查询开始处添加
设置NOCOUNT ON
。我试过了,但还是得到了同样的信息

调试
带给我的代码如下:

Dim cnn As New ADODB.Connection
Dim rst As New ADODB.Recordset
Dim ConnectionString As String
Dim StrQuery As String
Dim SOURCE As String
Dim DATABASE As String
Dim QUERY As String
Dim intColIndex As Integer
Dim sDate As String
Dim eDate As String
Dim qt As Worksheet
Dim qtr As Worksheet
Dim bqr As Worksheet
Dim bp As Worksheet

ConnectionString = "Provider=SQLOLEDB;Data Source=" & SOURCE & "; Initial Catalog=" & DATABASE & "; Integrated Security=SSPI;"
cnn.Open ConnectionString

cnn.CommandTimeout = 900

StrQuery = QUERY

rst.Open StrQuery, cnn

bqr.Range("B6").CopyFromRecordset rst

For intColIndex = 0 To rst.Fields.Count - 1
    Range("B5").Offset(0, intColIndex).Value = rst.Fields(intColIndex).Name
Next
bqr.Range(“B6”).CopyFromRecordset rst

我的代码的要点以及重要的变量设置如下:

Dim cnn As New ADODB.Connection
Dim rst As New ADODB.Recordset
Dim ConnectionString As String
Dim StrQuery As String
Dim SOURCE As String
Dim DATABASE As String
Dim QUERY As String
Dim intColIndex As Integer
Dim sDate As String
Dim eDate As String
Dim qt As Worksheet
Dim qtr As Worksheet
Dim bqr As Worksheet
Dim bp As Worksheet

ConnectionString = "Provider=SQLOLEDB;Data Source=" & SOURCE & "; Initial Catalog=" & DATABASE & "; Integrated Security=SSPI;"
cnn.Open ConnectionString

cnn.CommandTimeout = 900

StrQuery = QUERY

rst.Open StrQuery, cnn

bqr.Range("B6").CopyFromRecordset rst

For intColIndex = 0 To rst.Fields.Count - 1
    Range("B5").Offset(0, intColIndex).Value = rst.Fields(intColIndex).Name
Next
最令人困惑的是,错误表明我的
rst
记录集已关闭,即使它是在我使用
CopyFromRecordset
之前打开的

我曾尝试在查询结束时添加
DROP TABLE
,在开始时添加
SET NOCOUNT ON
函数,甚至测试了一些较小的简单临时表作为测试

例如,我将我的
QUERY
变量设置为:

QUERY = "CREATE TABLE #Test1 (TestID INT, TestValue VARCHAR(20))"
QUERY = QUERY + " INSERT INTO #Test1"
QUERY = QUERY + " VALUES (1, 'Pass'), (2, 'Fail'), (3, 'Try Again')"
QUERY = QUERY + " SELECT * INTO #Test2 FROM #Test1 WHERE TestID = 1"
QUERY = QUERY + " SELECT * FROM #Test2"
然后运行代码提取并通过Excel,它就工作了

因此,我被难住了。也许查询的时间有限制?现在它有180行长,所以它相当大

任何建议都将不胜感激

编辑:下面的完整宏(减去实际查询):

Private子命令按钮1\u单击()
如果TextBox1.Value=“即20160101”或TextBox2.Value=“即20160131”,则
MsgBox“请在继续之前填写所有字段”
如果Len(TextBox1.Value)8或Len(TextBox2.Value)8或Not IsNumeric(TextBox1.Value)或Not IsNumeric(TextBox2.Value),则
MsgBox“请使用格式正确的日期键(即yyyymmdd)”
其他的
Application.DisplayAlerts=False
工作表(ActiveWorkbook.Sheets.Count)。选择
而ActiveSheet.Name“[我要保留的工作表]”
活动表。删除
工作表(ActiveWorkbook.Sheets.Count)。选择
温德
将cnn设置为新的ADODB.连接
将rst设置为新ADODB.Recordset
Dim ConnectionString作为字符串
作为字符串的Dim StrQuery
将源设置为字符串
将数据库设置为字符串
将查询设置为字符串
作为整数的Dim intColIndex
将sDate设置为字符串
像线一样变暗
Dim qtr作为工作表
Dim bqr As工作表
将bp设置为工作表
设置qtr=图纸([图纸名称])
表。添加在:=qtr之后
设置bqr=ActiveSheet
bqr.Name=“[sheet Name]”
表。添加在:=bqr之后
设置bp=ActiveSheet
bp.Name=“[sheet Name]”
SOURCE=“[server]”
DATABASE=“[DATABASE]”
sDate=UserForm1.TextBox1.Value
eDate=UserForm1.TextBox2.Value
QUERY=“[查询开始]”
QUERY=QUERY+“[more QUERY here]”“查询中的每一行都会重复很多次”
数量选择
范围(“B6”)。选择
而ActiveCell.Value为“”
QUERY=QUERY+“”+ActiveCell.Value
ActiveCell.Offset(1,0)。选择
温德
QUERY=QUERY+“[more QUERY here]”“对于查询中的其余行,这会重复很多次”
ConnectionString=“Provider=SQLOLEDB;Data Source=“&Source&”Initial Catalog=“&DATABASE&”集成安全性=SSPI;”
开放连接字符串
cnn.CommandTimeout=2000
StrQuery=QUERY
打开StrQuery,cnn
bhr.Range(“B6”).CopyFromRecordset rst
对于intColIndex=0到rst.Fields.Count-1
范围(“B5”).Offset(0,intColIndex).Value=rst.Fields(intColIndex).Name
下一个
如果结束
Application.DisplayAlerts=True
端接头

设置nocount为on时启动T-SQL查询

QUERY = "set nocount on;"
QUERY = QUERY & "declare @Test1 table (TestID INT, TestValue VARCHAR(20))"
QUERY = QUERY & " INSERT INTO @Test1"
QUERY = QUERY & " VALUES (1, 'Pass'), (2, 'Fail'), (3, 'Try Again')"
QUERY = QUERY & " SELECT * FROM @Test1 WHERE TestID = 1"
那么它应该会起作用。下一个示例也会起作用,并且更接近您的示例(但使用了表变量)


底部附近的
QUERY=
位。是在rst.Open中运行的,还是直接在SMSS中运行并将值粘贴回excel中。“然后运行代码提取并通过Excel,它成功了。”这句话不清楚。这句话是在
rst.Open
中运行的,很抱歉,这句话不清楚,但您还有其他一些查询没有成功?您能否共享不起作用的查询?通常,在尝试打开后关闭(或设置为“无”)的记录集是由于某种原因导致数据库出错的结果。正确。但是,这个不起作用的查询有180行……编辑掉敏感信息将是一项艰巨的任务。我要补充的是,查询在SSMS中成功运行,但它确实需要20分钟多一点的时间。在这一点上,我还尝试将
cnn.CommandTimeout=900
更改为
cnn.CommandTimeout=2000
,但它仍然给出了错误消息此子例程/函数中是否发生了任何可能隐藏数据库错误的错误捕获?像错误转到…
行中的
,这里没有列出?抱歉问了二十个问题。这是一种不确定的故障排除类型。如我在问题中所述,我尝试过,但仍然不起作用:(如果您坚持使用临时表,您是对的。如果您愿意使用表变量,那么它将按照所述方式工作。这里的基本经验法则是,您只能使用Excel执行多个
DML
s。如果您希望发出
DDL
s,则必须在单独的查询中发送它们。
set nocount on;
declare @Test1 table (TestID INT, TestValue VARCHAR(20))
declare @Test2 table (TestID INT, TestValue VARCHAR(20))

INSERT INTO @Test1
VALUES (1, 'Pass'), (2, 'Fail'), (3, 'Try Again')

insert into @Test2
select *
from @Test1 WHERE TestID = 1

select * from @Test2