3

最近、よく知らないASPのWebサイトを継承しました。昨日、ページの1つがエラーをスローし始めました:

Microsoft VBScript runtime error '800a0009'

Subscript out of range: 'i'

default.asp, line 19

13〜27行目のコードは次のとおりです。

<%
set rs = Server.CreateObject("ADODB.Recordset")
rs.open "SELECT * FROM VENDORS_LIST_TBL WHERE inStr('"& dVendorStr &"','|'&ID&'|')", Cn

DIM dTitle(100), dDescription(100), dLink(100)
i = 0 : Do while NOT rs.EOF : i = i + 1
dTitle(i) = rs.fields.item("dTitle").value
dDescription(i) = rs.fields.item("dDescription").value
dLink(i) = rs.fields.item("dLink").value : if dLink(i) <> "" then dTitle(i) = "<a href=""" & dLink(i) & """>" & dTitle(i) & "</a>"
if NOT rs.EOF then rs.movenext
Loop
x = i

rs.Close : Set rs = Nothing
%>

ここで何が起こっているのか、どうすれば修正できるのかについてのアイデアはありますか?

ありがとうございました!

4

3 に答える 3

2

dTitle、dDescription、およびdLinkをサイズ100の配列として宣言しました。レコードセットをウォークスルーしているときに、これらの配列に要素を割り当てています。レコードセットに100を超えるレコードがあるように見えるため、ロジックは次のようなことを行おうとしています。

dTitle(101) = rs.fields.item("dTitle").value

配列がすべてのデータを保持するのに十分な大きさではないため、これはエラーをスローします。

于 2012-06-16T15:31:27.940 に答える
2

あなたが選んだ「解決策」はあまり良くありません。2年以内に500を超えるとしたらどうでしょうか。あなたはこれについてすべてを忘れて、もう一度時間を無駄にするでしょう。

固定サイズの配列の代わりに、動的配列を使用できます。

DIM dTitle(), dDescription(), dLink()
ReDim dTitle(0)
ReDim dDescription(0)
ReDim dLink(0)
i = 0
Do while NOT rs.EOF
    i = i + 1
    ReDim Preserve dTitle(i)
    ReDim Preserve dDescription(i)
    ReDim Preserve dLink(i)    
    dTitle(i) = rs.fields.item("dTitle").value
    dDescription(i) = rs.fields.item("dDescription").value
    dLink(i) = rs.fields.item("dLink").value
    If (Not(IsNull(dLink(i)))) And (dLink(i) <> "") Then
        dTitle(i) = "<a href=""" & dLink(i) & """>" & dTitle(i) & "</a>"
    End If
    rs.movenext
Loop

これは、各配列の1つの(空の)アイテムから始まります-何らかの理由でコードがこれを必要としているようです-その後、各反復でさらに1つのアイテムが追加され、他のアイテムは保持されます。

問題を引き起こす可能性のある小さな問題も修正したことに注意してください。「dLink」フィールドにNULL値がある場合、VBScriptではNULLは空の文字列ではないため、HTMLに空白のアンカーが表示されます。

于 2012-06-17T14:25:09.560 に答える
1

これGetRowsは、同じ目標を達成するためにどのように使用できますか。

<% 

Function VendorSearch(sVendor)

    Dim cn:  Set cn = SomeLibraryFunctionThatOpensAConnection()
    Dim cmd: Set cmd = Server.CreateObject("ADODB.Command")
    cmd.CommandType = adCmdText
    cmd.CommandText = "SELECT dTitle, dDescription, dLink FROM VENDORS_LIST_TBL WHERE inStr(?,'|'&ID&'|')"
    cmd.Parameters.Append cmd.CreateParameter("Vendor", adVarChar, adParamInput, Len(sVendor), sVendor)
    Set cmd.ActiveConnection = cn
    Dim rs : Set rs = cmd.Execute()

    VendorSearch = rs.GetRows()

    rs.Close()
    cn.Close()
End Function

Dim arrVendor : arrVendor =  VendorSearch(dVendorStr)

Const cTitle = 0, cDesc = 1, cLink = 2

Dim i
For i = 0 To UBound(arrVendor, 2)
    If IsNull(arrVendor(cLink, i) Or arrVendor(cLink, i) = "" Then
        arrVendor(cTitle, i) = "<a href=""" & arrVendor(cLink, i) & """>" & arr(cTitle, i) & "</a>"
    End If 
Next

%> 

ノート:

  • Selectステートメントには、結果に必要なフィールドのみが含まれているため、*の使用は避けてください。
  • パラメータ化されたコマンドは、SQLインジェクションによるSQLインジェクションの脅威を回避するために使用されます。
  • 結果の2次元配列へのフィールドインデックスに使用される定数。
  • このコードはタイトル値の元の変更を複製しますが、これは単なる例です。実際には、HTMLの構築はできるだけ遅くし、タイトルや説明などのすべての文字列の出力はServer.HTMLEncode、応答に送信する前にパススルーする必要があります。
于 2012-06-18T12:49:22.063 に答える