新手问题 想用脚本修改 sql2005 表中数据 如何操作

juventusryp · 2012年11月14日 · 最后由 juventusryp 回复于 2012年11月15日 · 2812 次阅读

require 'win32ole'

class SqlServer
    # This class manages database connection and queries
    attr_accessor :connection, :data, :fields
    attr_writer :username, :password

    def initialize(host, username = 'sa', password='')
        @connection = nil
        @data = nil
    @host = host
    @username = username
    @password = password
    end

    def open(database)
        # Open ADO connection to the SQL Server database
        connection_string =  "Provider=SQLOLEDB.1;"
        connection_string << "Persist Security Info=False;"
        connection_string << "User ID=#{@username};"
        connection_string << "password=#{@password};"
        connection_string << "Initial Catalog=#{database};"
        connection_string << "Data Source=#{@host};"
        connection_string << "Network Library=dbmssocn"
        @connection = WIN32OLE.new('ADODB.Connection')
        @connection.Open(connection_string)
    end

    def query(sql)
        # Create an instance of an ADO Recordset
        recordset = WIN32OLE.new('ADODB.Recordset')
        # Open the recordset, using an SQL statement and the
        # existing ADO connection
        recordset.Open(sql, @connection)
        # Create and populate an array of field names
        @fields = []
        recordset.Fields.each do |field|
            @fields << field.Name
        end
        begin
            # Move to the first record/row, if any exist
            recordset.MoveFirst
            # Grab all records
            @data = recordset.GetRows
        rescue
            @data = []
        end
        recordset.Close
        # An ADO Recordset's GetRows method returns an array 
        # of columns, so we'll use the transpose method to 
        # convert it to an array of rows
        @data = @data.transpose
    end

    def add_person
        puts "Enter groupname:"
        groupname = gets.chomp
        puts "Enter username:"
        username = gets.chomp
        puts "Enter loginID:"
        loginID = gets.chomp
        puts "Enter password:"
        password = gets.chomp
        db.execute("INSERT INTO dbo.OtherUser (groupname,username,loginID,password)VALUES(?,?,?,?)",groupname,username,loginID,password)
    end




    def close
        @connection.Close
    end
end

db = SqlServer.new('ryp', 'sa', 'dallasryp123')
db.open('TowerBook')
db.add_person
db.query("select * from TowerBook;")
puts field_names = db.fields
cust = db.data
puts cust.size
puts cust[0].inspect
db.close

脚本如上,可是当使用 add_person 时却发生错误 (如下),请教是哪里的问题

D:/ruby/sql.rb:64:in add_person': undefined local variable or methoddb' for # SqlServer:0x2944e18 (NameError) from D:/ruby/sql.rb:77:in `

'

我猜把 64 行的 db.execute(...) 改成 @connection.execute(...) 就可以了

另外你贴的代码可以用

ruby

包起来格式化一下,看的人会舒服一些。请参看发帖帮助

我一般都用sequel这个 gem 来直接操作数据库

#1 楼 @luikore 你好,感谢你的提醒 我已经改过来了 可是按着你的方法 会出现下面的错误

D:/ruby/sql.rb:64:in `method_missing': (in OLE method `execute': ) (WIN32OLERun
imeError)
    OLE error code:0 in <Unknown>
      <No Description>
    HRESULT error code:0x8002000e
      Invalid number of parameters.
        from D:/ruby/sql.rb:64:in `add_person'
        from D:/ruby/sql.rb:77:in `<main>'

#2 楼 @ywjno 这个 gem 似乎不能操作 sql2005?

#4 楼 @juventusryp Offsets are supported when using SQL Server 2005 or 2008, using a ROW_NUMBER window function. However, you must specify an order for your dataset (which you probably are already doing if you are using offsets)

这是从它的 readme 文档里面找到的那么一段话,因此应该是支持的,至于怎么做,自己去翻翻它的 doc 吧,我在 oracle 上用过

#5 楼 @ywjno 嗯~我这个小白只能等有时间再去看看这个 gem~感谢

#1 楼 @luikore 你好 现在我发现当我使用这句时

db.query("INSERT INTO dbo.OtherUser (groupname,username,loginID,password)VALUES(1,1,1,1)")

可以正常插入数据,但是会出现下面的提示,不知道为什么

D:/ruby/sql.rb:48:in `method_missing': (in OLE method `Close': ) (WIN32OLERuntim
eError)
    OLE error code:800A0E78 in ADODB.Recordset
      对象关闭时,不允许操作。
    HRESULT error code:0x80020009
      Exception occurred.
        from D:/ruby/sql.rb:48:in `query'
        from D:/ruby/sql.rb:77:in `<main>'

#7 楼 @juventusryp

报错信息已经告诉你原因了:

| Invalid number of parameters.

@connection.execute("...") 只接受一个参数,所以你要把 sql 拼成一个字符串先...

如果不手动拼 sql 的话,可以用另一种方法 (大致应该是这样,但手头没有 windows 和 sqlserver, 没法验证)

statement = @connection.prepare "INSERT INTO dbo.OtherUser (groupname,username,loginID,password)VALUES(?,?,?,?)"
statement.execute groupname,username,loginID,password

#8 楼 @luikore 你好 按着你的方法 我测试了一下 出现下面错误

D:/ruby/sql1.rb:64:in `method_missing': (in OLE method `prepare': ) (WIN32OLERun
timeError)
    OLE error code:800A0BB9 in ADODB.Connection
      参数类型不正确,或不在可以接受的范围之内,或与其他参数冲突。
    HRESULT error code:0x80020009
      Exception occurred.
        from D:/ruby/sql1.rb:64:in `add_person'
        from D:/ruby/sql1.rb:76:in `<main>'

而且我上网查了下资料 并没有找到 connection 的 prepare 方法 不知道这个是什么

烦请解答

#9 楼 @juventusryp perl 有 prepare 所以我猜 ruby 也有... 结果不对就把 sql 拼好直接 execute 吧。

@connection.Execute("INSERT INTO dbo.OtherUser (groupname,username,loginID,password) VALUES('#{groupname}','#{username},'#{loginID}','#{password}');"

#10 楼 @luikore 这次可以了 十分感谢~~

需要 登录 后方可回复, 如果你还没有账号请 注册新账号