VBA-使用DAO对象的运行时错误3271

Sea*_*ean 4 ms-access vba dao access-vba

我正在尝试使用DAO.QueryDefAppendMicrosoft Access中的本地查询来更新SQL Server数据库。我正在更新的某些字段包含很长的字符串(从字符0700字符的任何地方)。

当字符串长度在从0255字符的范围内时,我毫无疑问将其传递到查询中并更新相应的表。但是,当它们超过255字符数时,我会收到以下运行时错误:

VBA运行时错误3271

我一直在使用随机字符串生成器网站来创建和测试不同长度的字符串。我还检查了我的数据库中的列数据类型,它们都NVARCHAR(MAX)在需要的地方。Microsoft Access显示与数据类型相同的各个列Long text

请参阅以下代码片段:

Dim dbs As DAO.Database
Dim qdf As DAO.QueryDef

Set dbs = CurrentDb

If Not IsNull(cmbboxFileNameLogic) Then
    Set qdf = dbs.QueryDefs("qryUpdateFile")

    qdf.Parameters("FileName").Value = txtboxUpdateConversionName.Value
    qdf.Parameters("ZipFileName").Value = txtboxZipFileNameLogic.Value
    qdf.Parameters("OutputFormat").Value = txtboxOutputFormat.Value
    qdf.Parameters("Delimeter").Value = txtboxDelimeter.Value
    qdf.Parameters("DestinationLocation").Value = txtboxDestinationLocation.Value
    qdf.Parameters("DeliveryMechinism").Value = txtboxDeliveryMechinism.Value
    qdf.Parameters("Note").Value = txtboxOutputFileInfoNotes.Value
    qdf.Parameters("Criteria").Value = txtboxOutputFileInfoCriteria.Value
    qdf.Parameters("CustomListKey").Value = txtboxCustomListKey.Value
    qdf.Parameters("ExcludeCustomListKey").Value = txtboxExcludeCustomListKey.Value
    qdf.Parameters("NewspaperFlag").Value = chkNewsPaperFlag.Value
    qdf.Parameters("WebsiteFlag").Value = chkWebsiteFlag.Value
    qdf.Parameters("MarketingFlag").Value = chkProfessionalMarketingFlag.Value
    qdf.Parameters("PrintFlag").Value = chkProfessionalPrintFlag.Value
    qdf.Parameters("WebsiteFlag").Value = chkWebsiteFlag.Value
    qdf.Parameters("BrokerDealerFlag").Value = chkBrokerDealerFlag.Value
    qdf.Parameters("ActiveOnly").Value = chkActiveOnly.Value
    qdf.Parameters("OutputFormatting").Value = txtboxFileFormatting.Value
    qdf.Parameters("Header").Value = txtboxHeader.Value
    qdf.Parameters("Footer").Value = txtboxFooter.Value
    qdf.Parameters("SQLStatement").Value = txtboxSQLStatement.Value
    qdf.Parameters("OrderBy").Value = txtboxOrderBy.Value
    qdf.Parameters("FileID").Value = cmbboxFileNameLogic.Value

    qdf.Execute dbSeeChanges
    qdf.Close

    lblOutputFileInfoAction.Caption = "File successfully updated"
    lblOutputFileInfoAction.Visible = True

Else
    -- Insert new values
End If
Run Code Online (Sandbox Code Playgroud)

查询定义:

UPDATE myTableNameGoesHere SET fldFileNameLogic = [FileName], 
fldZipFileNameLogic = [ZipFileName],fldOutputFormat = [OutputFormat],
fldDelimeter = [Delimeter], 
fldDestinationLocation = [DestinationLocation], fldDeliveryMechinism = [DeliveryMechinism], 
fldNote = [Note], fldCriteria = [Criteria], fldCustomListKey = [CustomListKey],
fldExcludeCustomListKey = [ExcludeCustomListKey], fldNewspaperFlag = [NewspaperFlag], 
fldProfessionalWebsiteFlag = [WebsiteFlag], fldProfessionalMarketingFlag = [MarketingFlag], 
fldProfessionalPrintFlag = [PrintFlag], fldWebsiteFlag = [WebsiteFlag], 
fldBrokerDealerFlag = [BrokerDealerFlag], fldActiveOnly = [ActiveOnly], 
fldFileOutputFormatting = [OutputFormatting], fldHeader = [Header], 
fldFooter = [Footer], fldSQLStatement = [SQLStatement], fldOrderBy = [OrderBy]
WHERE [fldFileID] = [FileID];
Run Code Online (Sandbox Code Playgroud)

Han*_*sUp 6

您面临Access SQL文本参数的限制。它们不能容纳超过255个字符的字符串值。

这是一个演示问题的简单示例。

Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim strUpdate As String
Dim strLongString As String
strLongString = String(300, "x")
strUpdate = "UPDATE tblFoo SET memo_field = [pLongString] WHERE id=2;"
Set db = CurrentDb
Set qdf = db.CreateQueryDef(vbNullString, strUpdate)
qdf.Parameters("pLongString").Value = strLongString
qdf.Execute dbFailOnError
Run Code Online (Sandbox Code Playgroud)

该代码将触发错误#3271,“无效的属性值”。...您看到的相同错误。

如果我将UPDATE语句更改为包含这样的PARAMETERS子句...

strUpdate = "PARAMETERS [pLongString] LongText;" & vbCrLf & _
    "UPDATE tblFoo SET memo_field = [pLongString] WHERE id=2;"
Run Code Online (Sandbox Code Playgroud)

...结果仍然是错误#3271。

我认为没有任何方法可以克服Access SQL的限制。

因此,如果文本参数值的长度大于255个字符,则需要使用其他方法。

一种DAO.Recordset方法是将长文本字符串存储在字段中的一种简单替代方法。

Dim rs As DAO.Recordset
Dim strSelect
strSelect = "SELECT id, memo_field FROM tblFoo WHERE id=2;"
Set rs = db.OpenRecordset(strSelect)
With rs
    If Not (.BOF And .EOF) Then
        .Edit
        !memo_field.Value = strLongString
        .Update
    End If
    .Close
End With
Run Code Online (Sandbox Code Playgroud)

DAO参考MSDN上 - Recordset对象

  • 哇,真有趣。让您想知道为什么`LongText`根本不是有效的参数数据类型。 (3认同)