如何将ADO中的Command对象的参数与VBScript相关联?

Kra*_*n5k 5 vbscript ado

我一直在使用ADO VBScript,它需要接受参数并将这些参数合并到传递数据库的Query字符串中.当记录集对象尝试打开时,我不断收到错误.如果我传递没有参数的查询,记录集将打开,我可以处理数据.当我通过调试器运行脚本时,命令对象不显示参数对象的值.在我看来,我错过了与Command对象和Parameter对象相关联的东西,但我不知道是什么.这里有一些VBScript代码:

...
'Open Text file to collect SQL query string'
Set fso = CreateObject("Scripting.FileSystemObject")
fileName = "C:\SQLFUN\Limits_ADO.sql"
Set tso = fso.OpenTextFile(fileName, FORREADING)

SQL = tso.ReadAll

'Create ADO instance'
 connString = "DRIVER={SQL Server};SERVER=myserver;UID=MyName;PWD=notapassword;   Database=favoriteDB"
 Set connection = CreateObject("ADODB.Connection")
 Set cmd = CreateObject("ADODB.Command")

  connection.Open connString
  cmd.ActiveConnection = connection
  cmd.CommandText = SQL
  cmd.CommandType = adCmdText

  Set paramTotals = cmd.CreateParameter
  With paramTotals
       .value = "tot%"
       .Name = "Param1"
  End With

  'The error occurs on the next line'
  Set recordset = cmd.Execute

  If recordset.EOF then
      WScript.Echo "No Data Returned"
  Else
      Do Until recordset.EOF
            WScript.Echo recordset.Fields.Item(0) ' & vbTab & recordset.Fields.Item(1)
            recordset.MoveNext
      Loop
  End If
Run Code Online (Sandbox Code Playgroud)

我使用的SQL字符串是相当标准的,除了我想传递一个参数.它是这样的:

SELECT column1
FROM table1
WHERE column1 IS LIKE ?
Run Code Online (Sandbox Code Playgroud)

我知道ADO应该取代"?" 使用脚本中指定的参数值.我看到的问题是Parameter对象显示正确的值,但根据我的调试器,命令对象的参数字段为null.

小智 5

我知道这是旧的,但对于任何仍然坚持这一点的人(就像我通过谷歌做的那样):

如果您使用的是存储过程:

set cmd = Server.CreateObject("ADODB.Command")
with cmd
    .ActiveConnection = db_connection
    .CommandText = "stored_procedure_name"
    .CommandType = adCmdStoredProc
    .Parameters.Append .CreateParameter("@Parameter1",adInteger,adParamInput,,1)
        .Parameters.Append .CreateParameter("@Parameter2",adVarChar,adParamInput,100,"Up to 100 chars")
        .Parameters.Append .CreateParameter("@Parameter3",adBoolean,adParamInput,,true)
        .Parameters.Append .CreateParameter("@Parameter4",adDBTimeStamp,adParamInput,,now())
end with
set rs = cmd.execute
    'do stuff with returned results from select or leave blank if insert/delete/etc stored procedure
set rs = nothing
set cmd = nothing
Run Code Online (Sandbox Code Playgroud)

如果没有,我相信您将.CommandText更改为SQL语句,并且问题标记就位,并且您的参数必须遵循相同的顺序.

请参阅http://www.devguru.com/technologies/ado/quickref/command_createparameter.html 有关使用CreateParameter传递的值的细分,以及类型列表及其说明.


Tho*_*ith 1

我从来没有CreateParameter做我想做的事。正确的参数化是避免 SQL 注入的必要条件,但却CreateParameter是一个完整的 PITA。值得庆幸的是,还有一个替代方案:Command.Execute直接接受参数。

dim cmd, rs, rows_affected
set cmd = Server.createObject("adodb.command")
cmd.commandText = "select from Foo where id=?"
set cmd.activeConnection = someConnection
set rs = cmd.execute(rows_affected, Array(42))
Run Code Online (Sandbox Code Playgroud)

当包裹在适当的抽象中时会好得多。我编写了自己的数据库类包装ADODB.Connection,因此我不必手动完成所有这些工作。它有点依赖于其他自定义类,但其要点应该很明显:

class DatabaseClass
'   A database abstraction class with a more convenient interface than
'   ADODB.Connection. Provides several simple methods to safely query a
'   database without the risk of SQL injection or the half-dozen lines of
'   boilerplate otherwise necessary to avoid it.
'   
'   Example:
'   
'   dim db, record, record_set, rows_affected
'   set db = Database("/path/to/db")
'   set record = db.get_record("select * from T where id=?;", Array(42))
'   set record_set = db.get_records("select * from T;", empty)
'   rows_affected = db.execute("delete from T where foo=? and bar=?",
'                              Array("foo; select from T where bar=", true))

    private connection_
'       An ADODB connection object. Should never be null.

    private sub CLASS_TERMINATE
        connection_.close
    end sub

    public function init (path)
'       Initializes a new database with an ADODB connection to the database at
'       the specified path. Path must be a relative server path to an Access
'       database. Returns me.

        set connection_ = Server.createObject ("adodb.connection")
        connection_.provider = "Microsoft.Jet.OLEDB.4.0"
        connection_.open Server.mapPath(path)

        set init = me
    end function

    public function get_record (query, args)
'       Fetches the first record returned from the supplied query wrapped in a
'       HeavyRecord, or nothing if there are no results. 

        dim data: set data = native_recordset(query, args)
        if data.eof then
            set get_record = nothing
        else
            set get_record = (new HeavyRecordClass).init(data)
        end if
    end function

    public function get_records (query, args)
'       Fetches all records returned from the supplied query wrapped in a
'       RecordSet (different from the ADODB recordset; implemented below).

        set get_records = (new RecordSetClass).init(native_recordset(query, args))
    end function

    public function execute (query, args)
'       Executes the supplied query and returns the number of rows affected.

        dim rows_affected
        build_command(query).execute rows_affected, args
        execute = rows_affected
    end function

    private function build_command (query)
'       Helper method to build an ADODB command from the supplied query.

        set build_command = Server.createObject("adodb.command")
        build_command.commandText = query
        set build_command.activeConnection = connection_
    end function

    private function native_recordset (query, args)
'       Helper method that takes a query string and array of arguments, queries
'       the ADODB connection, and returns an ADODB recordset containing the
'       result.

        set native_recordset = build_command(query).execute( , args) ' Omits out-parameter for number of rows
    end function
end class
Run Code Online (Sandbox Code Playgroud)