【问题标题】:Creating a temp table in SQL Server 2008 using an Excel Macro (ADODB)使用 Excel 宏 (ADODB) 在 SQL Server 2008 中创建临时表
【发布时间】:2013-02-03 02:06:54
【问题描述】:

经过大量的谷歌搜索,我最终得到了以下宏,我希望它可以连接到数据库,删除任何现有的临时表,然后创建一个新表(填充它并查看结果)。

Dim adoCn As ADODB.Connection
Dim adoRs As ADODB.Recordset
Dim adoCm As ADODB.Command
Dim strSQL As String

Set adoCn = New ADODB.Connection
With adoCn
    .ConnectionString = "Provider=SQLOLEDB;" & _
                        "Initial_Catalog=XXX;" & _
                        "Integrated Security=SSPI;" & _
                        "Persist Security Info=True;" & _
                        "Data Source=XXX;" & _
                        "Extended Properties='IMEX=1'"
    .CursorLocation = adUseServer
    .Open
End With

Set adoCm = New ADODB.Command

With adoCm
    Set .ActiveConnection = adoCn
    .CommandType = adCmdText
    .CommandText = "IF OBJECT_ID('tempdb..#AgedProducts') IS NOT NULL DROP TABLE #AgedProducts"
    .Execute
    .CommandText = "CREATE TABLE #AgedProducts " & _
                   "(Source_Order_Number VARCHAR(255)) " & _
                   "INSERT INTO #AgedProducts VALUES ('AB-123-456') " & _
                   "SELECT * FROM #AgedProducts (NOLOCK) "
    .Execute
End With

Set adoRs = New ADODB.Recordset
With adoRs
    Set .ActiveConnection = adoCn
    .LockType = adLockBatchOptimistic
    .CursorLocation = adUseServer
    .CursorType = adOpenForwardOnly
    .Open "SET NOCOUNT ON"
End With
adoRs.Open adoCm

MsgBox "Recordset returned...", vbOKOnly

While Not adoRs.EOF
    Debug.Print adoRs.Fields(0).Value
    adoRs.MoveNext
Wend

adoCn.Close

Set adoCn = Nothing
Set adoRs = Nothing

当我运行查询时,我收到以下错误消息:

Run-time error '-2147217887 (80040e21)':

The requested properties cannot be supported

NOCOUNT 行来自http://support.microsoft.com/kb/235340(与上面的大部分代码一样)。我添加了IMEX=1 以考虑订单号可能有多种类型,但我怀疑这就是问题所在。

非常感谢任何帮助!

【问题讨论】:

    标签: sql sql-server-2008 vba excel


    【解决方案1】:

    修改recodset的打开方式,将select从命令移到recodset open方法调用。

    With adoCm
        Set .ActiveConnection = adoCn
        .CommandType = adCmdText
        .CommandText = "IF OBJECT_ID('tempdb..#AgedProducts') IS NOT NULL DROP TABLE #AgedProducts"
        .Execute
        .CommandText = "CREATE TABLE #AgedProducts " & _
                       "(Source_Order_Number VARCHAR(255)) " & _
                       "INSERT INTO #AgedProducts VALUES ('AB-123-456') "
        .Execute
    End With
    
    Set adoRs = New ADODB.Recordset
    With adoRs
        Set .ActiveConnection = adoCn
        .LockType = adLockBatchOptimistic
        .CursorLocation = adUseServer
        .CursorType = adOpenForwardOnly
    
    End With
    adoRs.Open "SELECT * FROM #AgedProducts (NOLOCK)"
    

    【讨论】:

    • 感谢您的支持 - 很不错。你知道为什么这行得通而不是我的第一次尝试吗?
    • Recodset 需要知道里面应该有什么,所以你必须提供 SQL 代码。看看例如这里support.microsoft.com/kb/168336。如何打开记录集有不同的方法。祝你有美好的一天。
    【解决方案2】:

    我对临时表的理解是它们只对创建它们的连接可用。在这种情况下,尝试从另一个连接中删除一个是不明智的。

    错误消息没有说明是哪一行代码导致的。既然如此,我建议你逐个测试你的代码。首先创建连接。然后打开并关闭它。然后在连接打开时开始做事,但一次做一件事。

    【讨论】:

    • 在 SQL Server 中 ##temp_table 是一个全局临时表。通过在代码执行开始时尝试删除表,可以确保(除了竞争条件)代码在尝试创建已经存在的表时不会出错。在创建表之前删除(可能不存在的)表是最佳做法。
    猜你喜欢
    • 1970-01-01
    • 2011-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多