MS SQL Access from Ruby in Windows

Can someone point me where to learn how to access a MS SQL 2000 database
server from within ruby in a Windows machine??

I wrote a ruby script that Using unixODBC drivers and Ruby's dbi module can
easily connect to the MS SQL database, make queries, etc from my Linux
machine.

Now I need to run the script from a windows machine so others non-linux users
can use my ruby script but I haven't found any tips on what I need to allow
MS SQL database connectivity from a windows machine.

any tips are apreciated

Horacio

Horacio Sanson wrote:

Can someone point me where to learn how to access a MS SQL 2000 database server from within ruby in a Windows machine??

I wrote a ruby script that Using unixODBC drivers and Ruby's dbi module can easily connect to the MS SQL database, make queries, etc from my Linux machine.

Now I need to run the script from a windows machine so others non-linux users can use my ruby script but I haven't found any tips on what I need to allow MS SQL database connectivity from a windows machine.

You need ADO driver for DBD. Here is how you get it into One-Click Ruby Installer.

QTE http://wiki.rubyonrails.com/rails/pages/HowtoConnectToMicrosoftSQLServer

Get the latest source distribution of Ruby-DBI from: http://ruby-dbi.rubyforge.org/ and copy the file:

src/lib/dbd_ado/ADO.rb

to:

X:/ruby/lib/ruby/site_ruby/1.8/DBD/ADO/ADO.rb

(you will need to create the ADO directory).

UNQTE

One-Click installer should probably include this driver.

AV

Here's some (sanitized) code from a project of mine. A System DSN was defined on the machine for connecting to a two different MSSQL dbs, one on the intranet and one over the Internet.

DB_LOGIN = $test_db_flag ? [ 'dbi:ODBC:TestDSNName' ] : [ 'dbi:ODBC:LiveDSNName', 'liveuser', 'livepassword' ]

begin
   require 'dbi'
   dbh = DBI.connect( *DB_LOGIN )

   # Ensure that the category exists, and get the ID
   CATEGORY_NAME = 'Latest Behaviors'
   row = dbh.select_one( 'SELECT acID FROM tblAssCategory WHERE acName=?', CATEGORY_NAME )
   if row
     SCRIPT_REFERENCE_CATEGORY_ID = row[ 0 ]
   else
     dbh.do( 'INSERT INTO tblAssCategory (acName) VALUES (?)', CATEGORY_NAME )
     SCRIPT_REFERENCE_CATEGORY_ID = dbh.select_one( 'SELECT CAST (@@IDENTITY AS int)' )[ 0 ]
   end

   #Prepare some SQL statements for speedier re-use
   get_article = dbh.prepare( <<-ENDSQL
     SELECT aID, aSummary, aBody, date_updated
     FROM tblAssItems
     WHERE acID=#{SCRIPT_REFERENCE_CATEGORY_ID} AND download_files=? AND aTitle=?
     ENDSQL
   )
   add_article = dbh.prepare( <<-ENDSQL
     INSERT INTO tblAssItems
     (author,aTitle,aSummary,aBody,download_files,acID,time_to_complete,difficulty,thumbnail,status)
     VALUES (?,?,?,?,?,#{SCRIPT_REFERENCE_CATEGORY_ID},'5 Minutes','(Reference)','#{THUMBNAIL_URL}','public')
     ENDSQL
   )
   update_article = dbh.prepare( <<-ENDSQL
     UPDATE tblAssItems
     SET
       author=?,
       aSummary=?,
       aBody=?,
       date_updated=#{Time.new.to_sql}
     WHERE aID=?
     ENDSQL
   )

   require 'erb'
   Behavior.all.each_with_index{ |bvs,i|
     puts "#{bvs.category}/#{bvs.name} (#{i+1}/#{$behavior_count})" if $DEBUG

     #Create fields for the DB entry
     author = bvs.author
     #Do not change the title arbitrarily! This is used to find existing articles in the DB
     #If you change the format of the title, you must manually remove all the old articles from the database
     title = "#{bvs.name} (#{bvs.category} Behavior)"
     summary = bvs.summary
     body = ERB.new( IO.read( 'template_onlinebody.rhtml' ) ).result( binding )
     download_path = "#{WEB_PATH_TO_BEHAVIORS}/#{bvs.category}/#{bvs.safe_name}.bvs"

     #Check to see if the item should be added or updated in the DB
     #(Don't just shove the current content, because that would invalidate 'date_updated')
     existing_article = get_article.execute( download_path, title )
     rows = get_article.fetch_all

     if rows.empty?
       #Couldn't find an existing article for the behavior, time to add a new one
       puts "Adding article entry '#{title}'" if $DEBUG
       body.sub!( '%%CURRENT_TIME%%', Time.new.to_pretty )
       add_article.execute( author, title, summary, body, download_path )
       $add_count += 1
     else
       existing_info = rows[ 0 ]
       #Time to update the entry
       puts "Updating article entry '#{title}'" if $DEBUG
       update_article.execute( author, summary, body, existing_info[ "aID" ] )
       $update_count += 1
     end
   }

rescue DBI::DatabaseError => e
   puts "An error occurred"
   puts "Error code: #{e.err}"
   puts "Error message: #{e.errstr}"

ensure
   #close out statements
   get_article.finish if get_article
   add_article.finish if add_article
   update_article.finish if update_article

   #unplug from the database
   dbh.disconnect if dbh
end #db safety

···

On Nov 4, 2005, at 12:42 AM, Horacio Sanson wrote:

Can someone point me where to learn how to access a MS SQL 2000 database
server from within ruby in a Windows machine??

I use DSN-less connections with the DBI ODBC driver using the
One-Click installer out of the box like this:

require 'dbi'

driver = 'ODBC'
server = "SQLSERVER_NAME"
# or this if you want to access an instance
#server = "SQLSERVER_NAME\\INSTANCE_NAME"
database = 'Database'
user = 'user'
password = 'password'

connection_string = "DBI:ODBC:Driver={SQL
Server};Server=#{server};Database=#{database};Uid=#{user};Pwd=#{password}"

begin
  # connect
  db = DBI.connect(connection_string, user, password)
  # get data and print
  row = db.select_one("SELECT XETDATE()")
  puts "result: " + row[0].to_s
rescue DBI::DatabaseError => e
  puts "Error #{e.errstr}"
ensure
  # disconnect from server
  db.disconnect if db
end

Regards,

Sean

···

On 11/4/05, Horacio Sanson <hsanson@moegi.waseda.jp> wrote:

Can someone point me where to learn how to access a MS SQL 2000 database
server from within ruby in a Windows machine??

I've used this with good results to access an mssql:
http://sqlrelay.sourceforge.net/

Raph

···

On 11/4/05, Horacio Sanson <hsanson@moegi.waseda.jp> wrote:

Can someone point me where to learn how to access a MS SQL 2000 database
server from within ruby in a Windows machine??

I wrote a ruby script that Using unixODBC drivers and Ruby's dbi module can
easily connect to the MS SQL database, make queries, etc from my Linux
machine.

Now I need to run the script from a windows machine so others non-linux users
can use my ruby script but I haven't found any tips on what I need to allow
MS SQL database connectivity from a windows machine.

any tips are apreciated

Horacio

Alexey wrote:

Horacio Sanson wrote:

Can someone point me where to learn how to access a MS SQL 2000 database
server from within ruby in a Windows machine??

You need ADO driver for DBD. Here is how you get it into One-Click Ruby
Installer.

That's one way, but you don't need it. The Windows One-Click installer comes
with DBI and the ODBC DBD already installed - you can use DBI/ODBC out of
the box.

Make a DSN, say "foo", and

require 'dbi'
dbh = DBI.connect("dbi:odbc:foo")

and Bob's your uncle.

Cheers,
Dave

of keystrokes.

···

On 11/4/05, Sean O'Halpin <sean.ohalpin@gmail.com> wrote:

On 11/4/05, Horacio Sanson <hsanson@moegi.waseda.jp> wrote:
>
> Can someone point me where to learn how to access a MS SQL 2000 database
> server from within ruby in a Windows machine??
>

I use DSN-less connections with the DBI ODBC driver using the
One-Click installer out of the box like this:

require 'dbi'

driver = 'ODBC'
server = "SQLSERVER_NAME"
# or this if you want to access an instance
#server = "SQLSERVER_NAME\\INSTANCE_NAME"
database = 'Database'
user = 'user'
password = 'password'

connection_string = "DBI:ODBC:Driver={SQL
Server};Server=#{server};Database=#{database};Uid=#{user};Pwd=#{password}"

begin
# connect
db = DBI.connect(connection_string, user, password)
# get data and print
row = db.select_one("SELECT XETDATE()")
puts "result: " + row[0].to_s
rescue DBI::DatabaseError => e
puts "Error #{e.errstr}"
ensure
# disconnect from server
db.disconnect if db
end

Regards,

Sean

Unless you LOVE writing Klocs... use Rails. The framework saves a boatload

--
Peter Fitzgibbons

Sean,

I am trying to do a DSN-Less connection to my MS SQL 2000 server as you told
me in your email bu I cannot get it to work.

I get this error

Error S1090 (0) [unixODBC][Driver Manager]Invalid string or buffer length

Googling I found this thread that says ODBC does not support DSNLess
connections and was wondering how you did to get this working. Using DSN
works ok.

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/67352

Another question I have is what is the advantage of using DSN vs DSNLess?? I
prefer DSNLess to avoid external configurations in the running PC so my Ruby
script is easily executed in different machines.

thanks,
Horacio

Saturday 05 November 2005 02:03、Sean O'Halpin さんは書きました:

···

rescue DBI::DatabaseError => e
puts "Error #{e.errstr}"
ensure
# disconnect from server
db.disconnect if db
end

"Dave Burt" <dave@burt.id.au> wrote in message
news:LoJaf.8659$Hj2.184@news-server.bigpond.net.au...

Alexey wrote:

Horacio Sanson wrote:

Can someone point me where to learn how to access a MS SQL 2000 database
server from within ruby in a Windows machine??

You need ADO driver for DBD. Here is how you get it into One-Click Ruby
Installer.

That's one way, but you don't need it. The Windows One-Click installer
comes with DBI and the ODBC DBD already installed - you can use DBI/ODBC
out of the box.

Make a DSN, say "foo", and

require 'dbi'
dbh = DBI.connect("dbi:odbc:foo")

and Bob's your uncle.

Cheers,
Dave

ODBC isn't really a good way to connect to an access database.
ADO blows it out of the boat performance and quirk wise.

"Dave Burt" <dave@burt.id.au> writes:

Alexey wrote:

Horacio Sanson wrote:

Can someone point me where to learn how to access a MS SQL 2000 database
server from within ruby in a Windows machine??

You need ADO driver for DBD. Here is how you get it into One-Click Ruby
Installer.

That's one way, but you don't need it. The Windows One-Click installer comes
with DBI and the ODBC DBD already installed - you can use DBI/ODBC out of
the box.

Make a DSN, say "foo", and

require 'dbi'
dbh = DBI.connect("dbi:odbc:foo")

and Bob's your uncle.

Cheers,
Dave

Just yesterday I was trying the ODBC DBD and encountered SEGV when I
call stored procedures in a certain way. Definitely some memory
corruption is going on as commenting out some ruby codes that are never
accessed or adding some bogus ruby code would cause SEGV.

I ended up using jruby with the jtds driver to access mssql2k, and
found myself thinking about dbd:jdbc:

your code <--> local ruby <--> drb on local machine <--> drb on remote
machine <--> remote jruby <--> remote jdbc driver

YS,

I've been using it for 4-5 years now and never had a problem either
with stability or performance. What exactly did you do?

Regards,

Sean

···

On 11/4/05, Yohanes Santoso <ysantoso-rubytalk@dessyku.is-a-geek.org> wrote:

Just yesterday I was trying the ODBC DBD and encountered SEGV when I
call stored procedures in a certain way.

Sean O'Halpin <sean.ohalpin@gmail.com> writes:

Just yesterday I was trying the ODBC DBD and encountered SEGV when I
call stored procedures in a certain way.

I've been using it for 4-5 years now and never had a problem either
with stability or performance. What exactly did you do?

Regards,

Sean

I'm using iodbc 3.52.2, freetds CVS (downloaded yesterday), ruby-odbc
0.996.

This is the error I'm getting. All data and exact query string has
been falsified since they contain sensitive info.

$ ruby1.8 create_account_odbc_trial.rb
Connecting...
There are 1 connections
List of tid:
99999936
99999836
99999906
99999979
99999921

···

On 11/4/05, Yohanes Santoso <ysantoso-rubytalk@dessyku.is-a-geek.org> wrote:

-------------------------
PAN=xxxxxxxxxxxxxxxxx
Connecting...
There are 2 connections
i=99999936
Connecting...
There are 3 connections
Done connecting...
i=99999836
Connecting...
There are 3 connections
Done connecting...
i=99999906
Connecting...
create_account_odbc_trial.rb:21: [BUG] Segmentation fault
ruby 1.8.2 (2005-04-11) [i386-linux]

aborted
$

I am also including the code that causes this SEGV. I am not trimming
down the code since the result is different, depending on the length
of the code.

E.g., if I have the following appended to line 75 and beyond:

exit
puts "hohohasijdoaifhkjhasdfkuh"
puts "hohohasijdoaifhkjhasdfkuh"
puts "hohohasijdoaifhkjhasdfkuh"
puts "hohohasijdoaifhkjhasdfkuh"
puts "hohohasijdoaifhkjhasdfkuh"
puts "hohohasijdoaifhkjhasdfkuh"
puts "hohohasijdoaifhkjhasdfkuh"
puts "hohohasijdoaifhkjhasdfkuh"
puts "hohohasijdoaifhkjhasdfkuh"

then the program completes gracefully.

YS.

     1 require 'odbc'
     2
     3 DBAUTH=[....]

     5 PANS = [

    14 ]
    15
    16 $total_connection = 0
    17
    18 def with_dbh
    19 result = nil
    20 puts "Connecting..."
    21 ODBC.connect(*DBAUTH) {|dbh|
    22 $total_connection += 1
    23 begin
    24 puts "There are #{$total_connection} connections"
    25 dbh.autocommit = false # need this, otherwise dbh.transaction will cause an error
    26 dbh.transaction{|dbh|
    27 result = yield dbh
    28 }
    29 ensure
    30 $total_connection -= 1
    31 end
    32 }
    33 puts "Done connecting..."
    34 result
    35 end
    36
    37
    38 def run_and_select_all(sql, *args)
    39 with_dbh{|dbh|
    40 dbh.run(sql, *args) {|stmt|
    41 all =
    42 stmt.each{|row|
    43 all << row
    44 }
    45 yield all
    46 }
    47 }
    48 end
    49
    50 def run_and_select_one(sql, *args)
    51 with_dbh{|dbh|
    52 dbh.run(sql, *args) {|stmt|
    53 row = stmt.fetch
    54 yield row
    55 }
    56 }
    57 end
    58
    59 run_and_select_all('select top 5 blablabla with one ?', FOO){|tids|
    60 puts "List of tid:"
    61 tids = tids.flatten
    62 puts tids.join("\n")
    63 puts "-"*25
    64 PANS.each{|pan|
    65 puts "PAN=#{pan}"
    66 run_and_select_one('select * from cust where blablablabla with one ?', pan) {
    67 tids.each{|tid|
    68 i = tid.to_i
    69 puts "i=#{i}"
    70 run_and_select_one('execute some_sp ?', i) {}
    71 }
    72 }
    73 }
    74 }

I see - I was referring to my experience on Windows.

We use ruby-odbc on Windows, Ubuntu and OS/X - we've had some
some odd error messages on OS/X but no show-stoppers. I suspect the
ruby-odbc code but haven't had time to ascertain exactly what is going
on.

What do you get if you use ODBC call syntax? I.e.

  run_and_select_one(' { call some_sp(?) }', i)

Regards,

Sean

···

On 11/4/05, Yohanes Santoso <ysantoso-rubytalk@dessyku.is-a-geek.org> wrote:

I'm using iodbc 3.52.2, freetds CVS (downloaded yesterday), ruby-odbc
0.996.