我正在使用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 STORED PROCEDURE *
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
请记住,这适用于小字符串分隔文本。所以我们知道我的连接和其他参数都没问题。
谢谢,
答案 0 :(得分:1)
确定。我找到了解决方案,非常非常容易。这就是为什么检查Watch窗口以了解你的对象(在这种情况下是oCMD)内部的重要性。
默认情况下,它将参数@DelimitedAssets作为adVarChar。您需要指定它不是adVarChar而是adLongVarChar。
.Parameters("@DelimitedAssets").Value = strAssetsDelimted
.Parameters("@DelimitedAssets").Type = adLongVarChar
一旦我改变了这一切,一切都按预期工作。
希望这有帮助。
答案 1 :(得分:0)
您是否尝试过指定类型&尺寸?
param.SqlDbType = SqlDbType.VarChar;
param.Size = -1;