【问题标题】:Error When Running Stored Procedure From VBA从 VBA 运行存储过程时出错
【发布时间】:2018-09-24 08:16:12
【问题描述】:

我正在使用 VBA 从 SQL Server 中提取信息。为了不让事情变得复杂,请阅读以下内容:

“我在 SQL 中有一个存储过程,它接收日期(@NeededDate 作为日期)和逗号分隔文本(@DelimitedAssets 作为 NVARCHAR(MAX) 返回所需的结果。

当我在 VBA 中运行我的代码时,当我传递的文本 (@DelimitedAssets) 不超过 7000 个字符(这不是确切的数字,但很接近)时,它可以工作。所以,换个说法:如果字符串不大,代码会按预期工作。

但是我从 VBA 传递给存储过程的文本加起来多达 12000 个字符。 NVARCHAR 应该能够处理它,但是当我从 VBA 传递它时没有这样做。

重要提示:如果我从 SQL Server Management Studio 运行相同的数据块(12000 个字符),它会完美运行。没有错误,数据正常。

行中发生错误:

Set oRecordSet = .Execute

VBA 代码*

Private Function RunMonthlyPricesSP(ByVal strDate As String, ByRef strAssetsDelimted As String, ByRef cnAccounting As Object, ByRef rDestination As Range) As Variant

    Dim oCmd As ADODB.Command
    Dim oRecordSet As ADODB.Recordset
    Dim ActivityParam As ADODB.Parameter
    Dim varPrices As Variant
    Dim strAction As String

    Set oCmd = New ADODB.Command
    Set oRecordSet = New ADODB.Recordset

    With oCmd
        .ActiveConnection = cnAccounting
        .CommandType = adCmdStoredProc
        .CommandText = "Usp_bondselectionprices"

        .Parameters("@NeededDate").Value = strDate
        .Parameters("@DelimitedAssets").Value = strAssetsDelimted

        Set oRecordSet = .Execute
    End With


    ' Return Array.
    ' Pending.
End Function

SQL 存储过程*

GO
/****** Object:  StoredProcedure [dbo].[Usp_bondselectionprices]    Script Date: 4/13/2018 5:41:57 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[Usp_bondselectionprices] @NeededDate      DATE,
                                                @DelimitedAssets VARCHAR(max)
AS
  BEGIN
      DECLARE @TblBuysSelectionBond BUYSSELECTIONBONDS

      INSERT INTO @TblBuysSelectionBond
      SELECT *
      FROM   dbo.Splittext(@DelimitedAssets)

      SELECT CASE
               WHEN Prices.Price * CurrencyPrices.Price IS NULL THEN Prices.Price
               ELSE Prices.Price * CurrencyPrices.Price
             END AS Price,
             Assets.AssetName
      FROM   Prices
             INNER JOIN Assets
                     ON Prices.AssetID = Assets.AssetID
             INNER JOIN Assets AS Currencies
                     ON Assets.CurrencyID = Currencies.AssetID
             LEFT OUTER JOIN Prices AS CurrencyPrices
                          ON Currencies.AssetID = CurrencyPrices.AssetID
                             AND Prices.PriceDate = CurrencyPrices.PriceDate
      WHERE  prices.PriceDate = @NeededDate
             AND assets.InstrumentTypeID = 4
             AND Assets.AssetName IN (SELECT *
                                      FROM   @TblBuysSelectionBond)
  END 

从存储过程中调用的函数将分隔的文本转换为表格*

GO
/****** Object:  UserDefinedFunction [dbo].[Splittext]    Script Date: 4/13/2018 6:10:02 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER FUNCTION [dbo].[Splittext] (@input AS VARCHAR(max))
RETURNS @Result TABLE(
  Value VARCHAR(max))
AS
  BEGIN
      DECLARE @str VARCHAR(max)
      DECLARE @ind bigint

      IF( @input IS NOT NULL )
        BEGIN
            SET @ind = Charindex(',', @input)

            WHILE @ind > 0
              BEGIN
                  SET @str = Substring(@input, 1, @ind - 1)
                  SET @input = Substring(@input, @ind + 1, Len(@input) - @ind)

                  INSERT INTO @Result
                  VALUES      (@str)

                  SET @ind = Charindex(',', @input)
              END

            SET @str = @input

            INSERT INTO @Result
            VALUES      (@str)
        END

      RETURN
  END 

请记住,这适用于小字符串分隔的文本。所以我们知道我的连接和其他参数都可以。

谢谢,

【问题讨论】:

    标签: sql sql-server vba


    【解决方案1】:

    好的。我找到了解决方案,而且非常非常简单。这就是为什么检查监视窗口以了解您的对象(在本例中为 oCMD)内部的内容如此重要的原因。

    默认情况下,它采用参数@DelimitedAssets 作为adVarChar。您需要指定它不是 adVarChar 而是 adLongVarChar。

    .Parameters("@DelimitedAssets").Value = strAssetsDelimted
    .Parameters("@DelimitedAssets").Type = adLongVarChar
    

    一旦我改变了这个,一切都按预期工作。

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      您是否尝试过指定类型和尺寸?

      param.SqlDbType = SqlDbType.VarChar;
      param.Size = -1;
      

      【讨论】:

      • 我应该把这个放在哪里?
      • 设置VBA参数属性
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多