首页 > 代码库 > QT unixODBC+freetds连接sqlserver并交叉编译移植到ARM上

QT unixODBC+freetds连接sqlserver并交叉编译移植到ARM上

最近产品需要做一个数据上传功能。客户要求直接写入SQLserver数据库。之前QT连接数据库是默认来年将诶sqlite数据库。由于sqlite是QT默认自带的操作起来比较简单,但是SQLserver QT没有带驱动所以需要安装驱动插件。下面我们来看一下是QT支持SQLServer所需要的插件。

一、unixODBC

二、QT的ODBC驱动

三、 FreeTDS

Ubuntu篇:

编译QT的ODBC驱动需要unixODBC,所以要先编译unixODBC

一、编译unixODBC

下载:http://pan.baidu.com/s/1hq25YjM

  1. tar -xzvf unixODBC-2.3.2.tar.gz  
  2. cd unixODBC-2.3.2  
  3. ./configure  --prefix=/usr/local/unixODBC
  4. ./make  
sudo make install

二、编译QT的ODBC驱动插件

下载QT源码:http://pan.baidu.com/s/1qW3BAEC

解压后进入:QTDIR/src/plugins/sqldriver/odbc/

qmake "INCLUDEPATH+=/usr/local/unixODBC/include" "LIBS+=-L/usr/local/unixODBC/lib -lodbc" odbc.pro

如果不成功,qmake用绝对路径如:/usr/local/Trolltech/QtEmbedded-4.7.1/bin/qmake "INCLUDEPATH+=/usr/local/unixODBC-arm/include" "LIBS+=-L/usr/local/unixODBC-arm/lib -lodbc" odbc.pro

编译完成后:将libqslqodbc.so 拷贝到QT的安装目录下的plugins/sqldriver里面。

此时在测试程序中可打印出:说明QODBC驱动已经安装。

还有个简单的办法:

apt-get  install libqt4-sql-odbc

dpkg -L libqt4-sql-odbc


拷贝红框中的内容到QT的驱动目录下。

这是连接SQLServer会报错

 Can‘t open lib ‘SQL SERVER‘ : file not found QODBC3: Unable to connect

这时候安装Freetds记好了。

三、FreeTDS的编译安装。

下载:http://pan.baidu.com/s/1o60XNQi

  1. cd freetds-0.9.1  
  2. ./configure --prefix=/usr/local/freetds  
  3. make 
sudo make install

安装好后还需要配置3个文件:

配置 /usr/local/freetds/etc/freetds.conf

   sudo vi /usr/local/freetds/etc/freetds.conf

   #A typical Microsoft server

   [testdsn]                     # SQL Server数据源名称,可以任意取有意义的名称

   host=192.168.10.22   # 数据库主机

   port=1344                   #数据库监听端口

2配置 /usr/local/unixODBC/etc/odbcinst.ini

[FreeTDS]
Description             = FreeTDS unixODBC Driver
Driver          = /usr/lib/libtdsodbc.so.0
UsageCount              = 1

[SQL Server]
Description             = FreeTDS unixODBC Driver
Driver          = /usr/local/ unixODBC/lib/libtdsodbc.so.0
UsageCount              = 1

3 配置 /usr/local/unixODBC/etc/odbc.ini

  1. testdsn]  # 数据源名称  
  2. Driver=FreeTDS# 指向odbcinst.ini的驱动配置  
  3. Description=MSSQL Server  
  4. Servername=testdsn # 数据源名称  
  5. Database=sqlscada    #数据库名称  
配置完成可以测试:

C/C++ code
 qDebug()<<QSqlDatabase::drivers();
 
    // 建立连接
    QSqlDatabase db=QSqlDatabase::addDatabase("QODBC");
    db.setDatabaseName("testdsn");
    db.setUserName("sa");
    db.setPassword("xxxxxx");
 
    if(!db.open())
    {
        qDebug("=== %s",qPrintable(db.lastError().text()));
    }else
    {
        qDebug("==== ok");
    }
成功打印:==== ok
"insert into [table1] values(‘10.5‘,‘2.0‘,‘2014-11-12 16:01:15‘,‘keke‘)" 

如果不成功刻印用tsql测试一下:tsql -H 119.232.XXX.xxx -p 1433 -U sa -P XXXXXX -D ncpjgSys
tsql –H 你的ip的名称 –U 数据库服务器连接用户名 –P 用户名对应的密码 –D 使用的数据库的名称


如果tsql可以而QT测试代码不行,那就是配置文件的问题,仔细检查配置文件的路径。也可用下面的代码测试。

  1. QSqlDatabase OpenDB()  
  2. {  
  3.     QSqlDatabase db=QSqlDatabase::addDatabase("QODBC");  
  4.     // 注意,对于express版本数据库, 一定要加\\sqlexpress这种后缀  
  5.     QString dsn="DRIVER={SQL SERVER};SERVER=192.168.10.22\\sqlexpress;DATABASE=sqlscada";  
  6.     db.setDatabaseName(dsn);  
  7.     db.setUserName("sa");  
  8.     db.setPassword("scada");  
  9.       
  10.     if(!db.open())  
  11.     {  
  12.         qDebug("Error:%s",qPrintable(db.lastError().text()));  
  13.         return db;  
  14.     }  
  15.     return db;  
  16. }  
ARM篇:

ARM需要移植就需要交叉编译;首先安装交叉编译器。根据板子具体定。接下还是三大步。

一、交叉编译unixODBC

./configure --prefix=/usr/local/arm/unixODBC --host=arm-linux   回车

4.#make

5.#make install

二、编译QT的ODBC驱动:

/usr/local/Trolltech/QtEmbedded-4.5.3-arm/bin/qmake "INCLUDEPATH+=/usr/local/arm/unixODBC/include" "LIBS+=-L/usr/local/arm/unixODBC/lib -lodbc" odbc.pro注:这个qmake是QT交叉编译的。

三、交叉编译 FreeTDS

./configure  --prefix=/usr/local/arm/freetds  --with-tdsver=7.1  --enable-msdblib  --disable-libiconv  --host=arm-linux

make

make install

四、拷贝文件:

/usr/local/arm/freetds 和/usr/local/arm/unixODBC打包拷贝到ARM的对应目录下(一定是对应目录即:/usr/local/arm/

也可适当裁剪。

libqsqlodbc.so库文件,将此库文件拷贝到ARM板子里的QT驱动目录下。




错误总结篇:

在移植的过程中遇到了各式各样的错误,汇总如下:

一、缺少QT的ODBC驱动插件

QSqlDatabase: QODBC driver not loaded 
QSqlDatabase: available drivers: QSQLITE 说明在连接odbc驱动的数据库时,缺少了libqt4-sql-odbc驱动包
解决办法:# sudo apt-get install libqt4-sql-odbc执行完重启后还是QSqlDatabase: QODBC driver not loaded 
QSqlDatabase: available drivers: QSQLITE

此时缺少QT的ODBC驱动插件虽然sudo apt-get install libqt4-sql-odbc安装了但还是找不到需要将libqsqlodbc.so拷贝到$QTDIR/plugins/sqldriver目录下。

二、缺少Freetds

("QSQLITE", "QODBC3", "QODBC", "QPSQL7", "QPSQL") 

=== [unixODBC][Driver Manager]Data source name not found, and no default driver specified QODBC3: Unable to connect
安装Freetds并配置:置文件没有配置好,配置好上面的三个文件。实在不行拷贝3个文件到/etc下

三、不执行SQL语句:

"insert into table1 values(‘10.5‘,‘2.0‘,‘2014-11-12 16:01:15‘,‘keke‘)" 
QODBCResult::exec: Unable to execute statement: "[FreeTDS][SQL Server]Invalid object name ‘table1‘." 
error==  

由于语句错误导致的。SQLserver在执行SQl语句时必须先加use database(database为数据库名)

四、编译Freetds时:make install时 arm-linux-ranlib:command not found

原因如下:

1.我添加arm交叉编译器目录到PATH中是放在//etc/profile里的,这是用户的配置文件,我的用户为yan。

2.执行make install时,加了sudo前缀,变成了root的工作环境和root的权限。

根据以上两点,make install是在root下做的,而arm-linux-ranlib在wmm用户的工作环境中才能找到。所以产生了这里的错误。

那我既要取得root权限,又要具有当前用户yan的工作环境,怎办呢?

解决如下:

执行make install之前,先用下sudo -i命令取得root权限。然后再执行make install。

su 和 sudo 的区别:

1.共同点:都是root用户的权限;

2.不同点:su仅仅取得root权限,工作环境不变,还是在切换之前用户的工作环境;sudo是完全取得root的权限和root的工作环境。

注意:sudo su切换到root时原用户的环境变量也一并丢失。应使用sudo -i

索性就手动添加PATH环境变量export $PATH=/opt/arm/4.3.2./bin:$PATH

然后make install,安装成功

五、 tsql: iconv.c:354: tds_iconv_open: Assertion `ret == 0‘ failed.

这种情况就是编码问题,解决方法:#./configure --enable-msdblib --prefix=/usr/local/freetds --with-tdsver=7.1 --disable-libiconv
重新编译下freetds,增加一个参数(红色字体的)
然后#make && make install

六、  Unable to connect: Adaptive server is unavailable or does not exist

 Unable to connect: Adaptive server is unavailable or does not exist.

       我的FreeTDS配置如下:

       [SQLSERVER]
       host = xxx.xxx.xxx.xxx
       port = 1433
       tds version = 8.0
       client charset = UTF-8

       看了不下N遍相关配置信息,没有任何问题。ldd了相关驱动文件,也没有任何连接库的问题。最关键的是,在这之几还成功过,百思不得其解。

       后面,把FreeTDS的调试日志功能打开:修改FreeTDS安装目录下etc子目录的freetds.conf文件,在“[global]”结点下有一行“; dump file = /tmp/freetds.log”,行首缺省用“;”屏蔽调试日志功能,把行首的“;”符号去掉,即可打开调试日志功能,然后保存退出。

       再用isql或者tsql进行连接数据库测试,结果肯定还是失败。然后cat调试日志文件(配置文件指定的/tmp/freetds.log文件),会发现有一行显示连接信息如下:

       Connecting to xxx.xxx.xxx.xxx port 4000 (TDS version 5.0)
       答案就在上面一行的红色加粗字符中。我的配置文件设置的TDS Version是8.0,调试日志打印的是5.0。我配置文件设置的端口号是1433,而调试日志打印的是4000。

        原来我的FreeTDS采用源代码编译安装,的进行configure未设置“--with-tdsver=8.0”选项,所以安装时缺省使用5.0,而5.0的缺省端口就是4000。知道了问题的原因后,一切就好办了。重新对FreeTDS进行configure;make;make install,configure时增加--with-tdsver=8.0选项。

--with-tdsver设置FreeTDS的版本,我这里设置了7.1是为了能连接SQL2005,网上有的文档说这里设置成8.0,但是我设置成8.0后编译出来的居然是5.0的,不知道什么原因,按这样设置成7.1编译出来的FreeTDS的版本就是7.1的

参考文章:/http://heyunhuan513.blog.163.com/blog/static/1602042201362921645593/
//http://www.2cto.com/database/201303/194968.html
//http://blog.163.com/e_rommel/blog/static/18738304520124234476314/
//http://tcspecial.iteye.com/blog/1972740
http://blog.chinaunix.net/uid-20680966-id-4425876.html
//http://www.oschina.net/question/565065_57069
http://www.linuxidc.com/Linux/2011-08/41198.htm
http://tech.rfidworld.com.cn/2014_09/b028d801fed451f5.html
http://china.ygw.blog.163.com/blog/static/6871974620117110752710/
http://www.linux521.com/2009/system/201204/16763.html

同时非常感谢

Qt/C++开发群
 259787236
 的落木和群主,他们很热心的帮助新人。

QT unixODBC+freetds连接sqlserver并交叉编译移植到ARM上