How To: Install FreeTDS and UnixODBC On OSX Using Homebrew For Use With Ruby, Php, And Perl
This little project started out as a basic script to connect to a Microsoft SqlServer and get data. It was a nightmare as I probably spent 15 hours learning about and troubleshooting both FreeTDS and UnixODBC. My pain is now your gain.
NOTICE: I have homebrew configured to install all packages into my local directory /Users/jared/.homebrew/
1) Install UnixODBC
[jared@localhost]$ brew install unixodbc ==> Downloading http://www.unixodbc.org/unixODBC-2.3.0.tar.gz File already downloaded in /Users/jared/Library/Caches/Homebrew ==> ./configure --disable-debug --prefix=/Users/jared/.homebrew/Cellar/unixodbc/2.3.0 --enable-gui=no ==> make install /Users/jared/.homebrew/Cellar/unixodbc/2.3.0: 24 files, 932K, built in 22 seconds [jared@localhost]$ |
2) Edit the FreeTDS formula And install
What we are doing is changing the default tds version, enabling the msdblib, and pointing out where unixodbc installed.
require 'formula' class Freetds > Formula url 'http://ibiblio.org/pub/Linux/ALPHA/freetds/stable/freetds-0.91.tar.gz' homepage 'http://www.freetds.org/' md5 'b14db5823980a32f0643d1a84d3ec3ad' def install system "./configure",· "--prefix=#{prefix}",· "--with-tdsver=7.0",· "--enable-msdblib", "--with-unixodbc=/Users/USERNAME/.homebrew/Cellar/unixodbc/2.3.0", "--mandir=#{man}" system 'make' ENV.j1 # Or fails to install on multi-core machines system 'make install' end end |
[jared@localhost]$ brew install freetds |
3) Start a new terminal session to make sure all your paths update
4) Confirm that you can connect to the server
We need to make sure that you can connect to the sqlserver and that the port is open and available to you.
To do this we use telnet. If you see the following, success! The port is open on the server.
[jared@localhost]$ telnet server.example.com 1433 Trying 192.168.1.101... Connected to server.example.com. Escape character is '^]'. |
If you see the following. You failed. Check the Sqlserver configuration, firewalls, or network configuration.
[jared@localhost]$ telnet server.example.com 1433 Trying 192.168.1.101... telnet: connect to address 192.168.1.101: Connection refused telnet: Unable to connect to remote host |
Note: Press the ctrl + ] keys to break to a prompt and then type exit.
5) Tsql
FreeTDS comes with a couple cli applications. One of them is tsql. It isn’t great, but I use it test and see if at least FreeTDS is working correctly. After you install FreeTDS using homebrew try and connect to the host using the following command.
[jared@localhost]$ tsql -H server.example.com -U USERNAME -P PASSWORD -v locale is "en_US.UTF-8" locale charset is "UTF-8" using default charset "UTF-8" 1>exit |
If you see a prompt, you haz awesome!
6) Sym link the FreeTDS and UnixODBC conf files
I create 3 sym links to the following files just for simplicity.
ln -s /Users/jared/.homebrew/Cellar/freetds/0.91/etc/freetds.conf ~/.freetds.conf ln -s /Users/jared/.homebrew/Cellar/unixodbc/2.3.0/etc/odbc.ini ~/.odbc.ini ln -s /Users/jared/.homebrew/Cellar/unixodbc/2.3.0/etc/odbcinst.ini ~/.odbcinst.ini |
7) edit the .freetds.conf and add the following
[example] host = server.example.com port = 1433 tds version = 7.0 |
8 ) edit the odbcinst.ini and add the following
You are telling unixodbc where your FreeTDS drivers are located using this configuration file.
[FreeTDS] Description = FreeTDS Driver = /Users/jared/.homebrew/lib/libtdsodbc.so Setup = /Users/jared/.homebrew/lib/libtdsodbc.so UsageCount = 1 |
9) edit the .odbc.ini and add the following
[myexample] Driver = FreeTDS // we just set this up a second ago Description = MyExample ServerName = example // this is the name of the configuration we used in the .freetds.conf file UID = USERNAME PWD = PASSWORD |
10) isql should work
[jared@localhost]$ isql sqlinternal USERNAME PASSWORD +---------------------------------------+ | Connected! | sql-statement | help [tablename] | quit +---------------------------------------+ SQL>quit |
11) Osql Error
If you try osql, it throws an error.
[jared@localhost]$ osql -S myexample -U USERNAME -P PASSWORD checking shared odbc libraries linked to isql for default directories... /Users/jared/.homebrew/bin/osql: line 53: ldd: command not found strings: can't open file: (No such file or directory) osql: problem: no potential directory strings in "/Users/jared/.homebrew/bin/isql" osql: advice: use "osql -I DIR" where DIR unixODBC\'s install prefix e.g. /usr/local isql strings are: checking odbc.ini files reading /Users/jared/.odbc.ini [myexample] found in /Users/jared/.odbc.ini found this section: [myexample] Driver = FreeTDS Description = MyExample Servername = example UID = USERNAME PWD = PASSWORD looking for driver for DSN [myexample] in /Users/jared/.odbc.ini found driver line: " Driver = FreeTDS" driver "FreeTDS" found for [myexample] in .odbc.ini found driver named "FreeTDS" "FreeTDS" is not an executable file looking for entry named [FreeTDS] in /odbcinst.ini found driver line: " Driver = /Users/jared/.homebrew/lib/libtdsodbc.so" found driver /Users/jared/.homebrew/lib/libtdsodbc.so for [FreeTDS] in odbcinst.ini /Users/jared/.homebrew/lib/libtdsodbc.so is not an executable file osql: error: no driver found for sqlinternal [jared@localhost]$ |
If you go through the error you will find that a certain driver is not executable. You just need to chmod the file.
[jared@localhost]$ chmod 554 /Users/jared/.homebrew/Cellar/freetds/0.91/lib/libtdsodbc.0.so |
Now run it again.
[jared@localhost]$ osql -S myexample -U USERNAME -P PASSWORD checking shared odbc libraries linked to isql for default directories... /Users/jared/.homebrew/bin/osql: line 53: ldd: command not found strings: can't open file: (No such file or directory) osql: problem: no potential directory strings in "/Users/jared/.homebrew/bin/isql" osql: advice: use "osql -I DIR" where DIR unixODBC\'s install prefix e.g. /usr/local isql strings are: checking odbc.ini files reading /Users/jared/.odbc.ini [myexample] found in /Users/jared/.odbc.ini found this section: [myexample] Driver = FreeTDS Description = myexamples Servername = myexample UID = USERNAME PWD = PASSWORD looking for driver for DSN [myexample] in /Users/jared/.odbc.ini found driver line: " Driver = FreeTDS" driver "FreeTDS" found for [myexample] in .odbc.ini found driver named "FreeTDS" "FreeTDS" is not an executable file looking for entry named [FreeTDS] in /odbcinst.ini found driver line: " Driver = /Users/jared/.homebrew/lib/libtdsodbc.so" found driver /Users/jared/.homebrew/lib/libtdsodbc.so for [FreeTDS] in odbcinst.ini /Users/jared/.homebrew/lib/libtdsodbc.so is an executable file Using ODBC-Combined strategy DSN [myexample] has servername "myexample" (from /Users/jared/.odbc.ini) /Users/jared/.freetds.conf is a readable file looking for [myexample] in /Users/jared/.freetds.conf found this section: [myexample] host = myexample.bendcable.net port = 1433 tds version = 7.0 Configuration looks OK. Connection details: DSN: myexample odbc.ini: /Users/jared/.odbc.ini Driver: /Users/jared/.homebrew/lib/libtdsodbc.so Server hostname: myexample.bendcable.net Address: 192.168.12.103 Attempting connection as username ... + isql myexample USERNAME PASSWORD -v +---------------------------------------+ | Connected! | sql-statement | help [tablename] | quit +---------------------------------------+ SQL> quit |
SUCCESS!!!
Some other useful commands.
Useful commands
odbcinst -j odbcinst -q -d odbcinst -q -s |

Hi Jared,
thank you very much for saving pain (!).
I just made it till step 10, while isql says:
[ISQL]ERROR: Could not SQLConnect
So I went ahead to step 11. osql says:
grep: /odbcinst.ini: No such file or directory
I copied the file odbcinst.ini to my users directory as .odbcinst.ini.
But what am I doing wrong?
Sincerely
Lars
Hi Lars,
What is the output from these commands?
odbcinst -j
odbcinst -q -d
odbcinst -q -s
$ odbcinst -j
unixODBC 2.3.1
DRIVERS…………: /usr/local/Cellar/unixodbc/2.3.1/etc/odbcinst.ini
SYSTEM DATA SOURCES: /usr/local/Cellar/unixodbc/2.3.1/etc/odbc.ini
FILE DATA SOURCES..: /usr/local/Cellar/unixodbc/2.3.1/etc/ODBCDataSources
USER DATA SOURCES..: /Users/lars/.odbc.ini
SQLULEN Size…….: 8
SQLLEN Size……..: 8
SQLSETPOSIROW Size.: 8
$ odbcinst -q -d
[FreeTDS]
$ odbcinst -q -s
[myexample]
And this?
ls -alh ~/.odbc*
Example:
[jared@jared-mbp:~]$ ls -alh ~/.odbc*
lrwxr-xr-x 1 jared staff 60B Jan 9 14:21 /Users/jared/.odbc.ini -> /Users/jared/.homebrew/Cellar/unixodbc/2.3.0/etc/odbc.ini
lrwxr-xr-x 1 jared staff 64B Jan 9 14:21 /Users/jared/.odbcinst.ini -> /Users/jared/.homebrew/Cellar/unixodbc/2.3.0/etc/odbcinst.ini
I think the difference here is that I install homebrew in my home directory. You look to be using /usr/local/
You installation is looking here.
DRIVERS…………: /usr/local/Cellar/unixodbc/2.3.1/etc/odbcinst.ini
So one solution (a hack) would be to edit that odbcinst.ini file directly.
$ ls -alh ~/.odbc*
lrwxr-xr-x 1 lars staff 45B 18 Feb 20:22 /Users/lars/.odbc.ini -> /usr/local/Cellar/unixodbc/2.3.1/etc/odbc.ini
lrwxr-xr-x 1 lars staff 49B 18 Feb 20:21 /Users/lars/.odbcinst.ini -> /usr/local/Cellar/unixodbc/2.3.1/etc/odbcinst.ini
Luftbuch:~ lars$
Yep, after I found out to make simlinks (not copies), I deleted the copies and made simlinks the same way you did.
the content of that file is (only):
[FreeTDS]
Description = FreeTDS
Driver = /usr/local/lib/libtdsodbc.so
Setup = /usr/local/lib/libtdsodbc.so
UsageCount = 1
So is the problem solved?
unfortunately, no … I still get the message, that odbcinst.ini is not found, hm … maybe there is an issue to the rights of the file or its directory? Just to chill myself, I do a restart right now (even if I know, that this won’t help
Yup. Sounds like a permissions issue. And yeah, a restart is not going to do anything
Again, because I install homebrew in my home directory, my user easily has access to everything. Your user is trying to access libraries found in /usr/local which could potentially be a problem.
You could always assume root with `sudo -i`, and try running tsql, isql, osql as root to see what happens. No guarantees though.
Yep, so I will repeat all that, after I did the same – installed homebrew to my home directory. Before I do that I’ll try it as root with simlinks to /var/root. I will let you know what happens.
Sounds good.
Yeah … got it
After I installed brew in home, osql still doesn’t found odbcinst.ini.
However … I simlink(ed) it to / … quick and dirty
(Dont’t know if it’s maybe also an 10.7.3 issue? I’ll have a look to that later)
So for now … I can connect to my business SQL Server via a VPN connection (I bundled all traffic over that VPN connection to solve an DNS problem connecting to the SQL Server) and have following response:
+—————————————+
| Connected!
|
| sql-statement
| help [tablename]
| quit
|
+—————————————+
Also fired successfully some Statements and get the expected … fantastic!!!!
Thanks a lot Jared.
I really appreciate your help (!).
Well done!
FWIW, I’m running 10.7.2
Installed successfully and can query tables via the command line but PHP won’t connect to the ODBC driver even though it appears to be active from phpinfo().
odbc
ODBC Support enabled
Active Persistent Links 0
Active Links 0
ODBC library iodbc
ODBC_INCLUDE -I/usr/include
ODBC_LFLAGS -L/usr/lib
ODBC_LIBS -liodbc
Directive Local Value Master Value
odbc.allow_persistent On On
odbc.check_persistent On On
odbc.default_cursortype Static cursor Static cursor
odbc.default_db no value no value
odbc.default_pw no value no value
odbc.default_user no value no value
odbc.defaultbinmode return as is return as is
odbc.defaultlrl return up to 4096 bytes return up to 4096 bytes
odbc.max_links Unlimited Unlimited
odbc.max_persistent Unlimited Unlimited
Hi Bill,
The cli bit is an interesting piece to the puzzle. I am assuming you are running the .php scripts as your linux user, no?
Where as, the {web_server_user} is running the .php scripts for the webserver.
You see where I am headed?
1) su to the webserver user and run
odbcinst -j
2) edit the odbc.ini files and odbcinst.ini files to match your users .ini file
That is the first thing to come to my mind upon reading your comment.
Let me know how it turns out.
-peace
^Sorry,
s/linux/osx/g
Hi Jared,
I seem to have gotten most of this working. Tsql, Isql both work.
I can’t get the Osql portion to work. My Ip address is always coming back as an empty string. Some more background here. I am trying to connect to a virtual machine and have added its static ip address and machine name to my mac’s hosts file. It seems that osql calls the host command which doesnt resolve. I’m pretty new to unix/mac etc and networking isn’t my strong point. Anyhow below is the error I get:
“FreeTDS” is not an executable file
looking for entry named [FreeTDS] in /odbcinst.ini
found driver line: ” Driver = /usr/local/lib/libtdsodbc.so”
found driver /usr/local/lib/libtdsodbc.so for [FreeTDS] in odbcinst.ini
/usr/local/lib/libtdsodbc.so is an executable file
Using ODBC-Combined strategy
DSN [concur] has servername “seanswin7″ (from /Users/seansilvestri/.odbc.ini)
/Users/seansilvestri/.freetds.conf is a readable file
looking for [seanswin7] in /Users/seansilvestri/.freetds.conf
found this section:
[seanswin7]
host = 192.168.179.101
port = 1433
tds version = 7.0
client charset = UTF-8
dump file = /Users/seansilvestri/Documents/Concur/freetds.log
dump file append = yes
looking up hostname for ip address 192.168.179.101
osql: warning: no DNS hostname found for “192.168.179.101″
Usage: host [-aCdlriTwv] [-c class] [-N ndots] [-t type] [-W time]
[-R number] [-m flag] hostname [server]
-a is equivalent to -v -t ANY
-c specifies query class for non-IN data
-C compares SOA records on authoritative nameservers
-d is equivalent to -v
-l lists all hosts in a domain, using AXFR
-i IP6.INT reverse lookups
-N changes the number of dots allowed before root lookup is done
-r disables recursive processing
-R specifies number of retries for UDP packets
-s a SERVFAIL response should stop query
-t specifies the query type
-T enables TCP/IP mode
-v enables verbose output
-w specifies to wait forever for a reply
-W specifies how long to wait for a reply
-4 use IPv4 query transport only
-6 use IPv6 query transport only
-m set memory debugging flag (trace|record|usage)
osql: no IP address found for “”
anyhow many thanks in advance it would be cool to get this to work.
~Sean
Sean,
Why are you assigning an IP address to the hostname value? Maybe try the following.
BEGIN
[1] edit hosts file add ip and hostname entry
jared@localhost$ sudo vi /etc/hosts
##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting. Do not change this entry.
##
127.0.0.1 localhost
255.255.255.255 broadcasthost
192.168.179.101 seans_win_seven_host
[2] edit seanswin7 definition adding the hostname
[seanswin7]
host = seans_win_seven_host
port = 1433
tds version = 7.0
client charset = UTF-8
dump file = /Users/seansilvestri/Documents/Concur/freetds.log
dump file append = yes
END
This is a shot in the dark based solely on your output.
good luck
jared
Hi Jared,
I tried that same thing and I get the same error e.g. it can’t find the ip address. Odd thing is that I can successfully access my virtual machine via a web browser but not via the ‘host’ command. I think that osql is using that command and its failing…
Sean
Sean,
When you access the virtual machine, are you using the named definition or IP address?
This was incredibly helpful, thank you for the post!
@Marc, glad you got some use out of it!
First of all, I’ve been trying different things and researching this for more hours than I care to recall and this is probably the best resource I’ve found, so kudos…… ok, now…. I’ve worked down through your instructions up until the simlink of the three files (freetds.conf,odbc.ini,odbcinst.ini)…. and up until that instruction everything went smoothly. I can telnet and tsql in to my SQLServer instance but I don’t think those config files exist!?!
My homebrew installed to /usr/local/Cellar instead of /Users/aaronireland/ like your example did, but for example I found /usr/local/Cellar/unixodbc/2.3.1/ but there’s not odbc.ini file there.
Any ideas why homebrew didn’t install those files? Do I need to create them manually?
OK, so freetds.conf and odbc.ini seem to be ok (?) But I can’t get isql or osql to work osql tells me “grep: /odbcinst.ini: No such file or directory”
Aaron, hit me up on gtalk if you like. This thread is stinking long.
OK (again), I used the trick Lars used and that seemed to solve that issue, but now I get a different error with osql (and still no isql):
[S1000][unixODBC][FreeTDS][SQL Server]Unable to connect to data source
[01000][unixODBC][FreeTDS][SQL Server]Unknown host machine name.
[ISQL]ERROR: Could not SQLConnect
Are you connected to the network using a VPN?
I had the same “grep: /odbcinst.ini: No such file or directory” — took a look at the osql script, and the logic to determine the path is just bugged — it does have an option -I that you can use to specify the correct path though, so:
osql -S myexample -U USERNAME -P PASSWORD -I /usr/local/Cellar/unixodbc/2.3.1/etc/
worked great
— thanks for the article Jared, very clear, saved me some time.
Sean, did you ever resolve the no IP address found issue??
I get an error when using the osql command:
no IP address found for
Solution:
the source for osql REQURES the use of a host name. In my case I am restricted to using an IP address, due to reasons I won’t bore people with. The osql requires a host name because it uses the linux host command to verify the server connectivity before issueing the isql command to connect to the database. The linux host command ignores the /etc/hosts file and will only check DNS servers. Due to my current circumstance, I must avoid using a DNS entry (Don’t ask).
I modified this file to remove the host resolution and got the connection to work with an IP:
/usr/local/bin/osql
also this has been a helpful URL as well:
http://dtemplatelib.sourceforge.net/ReadMeLinux.htm
Nice job Suzanne! Thanks for the feedback, I’m sure it will help others.
Hi
great tutorial.. but need a little help.
On the promt the conection to the sql server is running great also i can retrieve information from the server BUT when i used the php code no result…
Any idea??.
thanks in advanced
Please Help , i am getting error
My odbcinst.ini file
[FreeTDS]
Description = TDS driver (Sysbase/MS SQL)
Driver = /usr/local/freetds/lib/libtdsodbc.so
Setup = /usr/local/freetds/lib/libtdsodbc.so
UsageCount = 1
My odbc.ini file
[SERVER]
Driver = FreeTDS
Description = ODBC connection via FreeTDS
ServerName = SERVER
My freetds.conf file
# A typical Microsoft server
[SERVER]
host = xxx.xxx.xxx.xxx
port = 1433
tds version = 7.2
$ sudo TDSVER=7.2 osql -S SERVER -U devuser2 -P ZqZMNfVP
checking shared odbc libraries linked to isql for default directories...
trying /usr ... no
trying /loc ... no
trying /tmp/sql.log ... no
trying /home ... no
trying /.odbc.ini ... no
trying /usr/local/etc ... OK
checking odbc.ini files
reading /home/perlzuser/.odbc.ini
[SERVER] not found in /home/perlzuser/.odbc.ini
reading /usr/local/etc/odbc.ini
[SERVER] found in /usr/local/etc/odbc.ini
found this section:
[SERVER]
Driver = FreeTDS
Description = ODBC connection via FreeTDS
ServerName = SERVER
looking for driver for DSN [SERVER] in /usr/local/etc/odbc.ini
found driver line: " Driver = FreeTDS"
driver "FreeTDS" found for [SERVER] in odbc.ini
found driver named "FreeTDS"
"FreeTDS" is not an executable file
looking for entry named [FreeTDS] in /usr/local/etc/odbcinst.ini
found driver line: " Driver = /usr/local/freetds/lib/libtdsodbc.so"
found driver /usr/local/freetds/lib/libtdsodbc.so for [FreeTDS] in odbcinst.ini
/usr/local/freetds/lib/libtdsodbc.so is an executable file
Using ODBC-Combined strategy
DSN [SERVER] has servername "" (from /usr/local/etc/odbc.ini)
Hi jared.folkins, with isql, osql and others.. I can connect… but with PHP I’m getting SQLSTATE[08001] error… could you help-me with that?
Please note that new versions of homebrew include a freetds recipe but for this to work—specifically to get isql working—you need to do `brew install –with-unixodbc freetds`.
This article was a super big help. Thanks so much!