【转载】Qt调用Server SQL中的存储过程

来源:互联网 发布:淘宝买家等级查询 编辑:程序博客网 时间:2024/04/29 23:41

Server SQL中的存储过程如下:

CREATE procedure PINSERTPC
 @pcnum int,
 @pcname varchar(50),
 @pctype int,
 @ipaddress varchar(50),
 @port  int,
 @pcid  int output
as

--declare @pcid int
if exists (select * from COMPUTERTABLE where PcNum = @pcnum)
 set @pcid = -1
else
begin
 insert into COMPUTERTABLE (PcNum, PcName, PcType, IpAddress, Port)
 values (@pcnum, @pcname, @pctype, @ipaddress, @port)
 select @pcid = SCOPE_IDENTITY()
end
--return @pcid
GO

根据网上搜索文章《qt中调用sql server的存储过程》内容如下:

写了个存储过程,准备使用qt调用,数据库是sqlserver 2000按照参考文档
调用是下面这样的

QSqlQuery query;
query.prepare("CALL InsertImgEntity( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
query.bindValue(0,datano);
query.bindValue(1,DataCorner);
query.bindValue(2,DataZD);
query.bindValue(3,DataCommon);
query.bindValue(4,ImgCode);
query.bindValue(5,ImgCodeZ);
query.bindValue(6,"png");
query.bindValue(7,pngImage,QSql::Binary);
query.bindValue(8,"GoldMap Gaoyong Sun");
query.bindValue(9,QDateTime::currentDateTime ());

但是我在windows下却无法调用成功。调试跟踪,发觉我在调试中存储过程是通过exec调用的,故此将代码修改如下,问题解决,造成这种结果的原因可能是数据库的不同吧。

query.prepare("exec InsertImgEntity ?, ?, ?, ?, ?, ?, ?, ?, ?, ?");
query.bindValue(0,datano);
query.bindValue(1,DataCorner);
query.bindValue(2,DataZD);
query.bindValue(3,DataCommon);
query.bindValue(4,ImgCode);

   在开发Android应用程序的实现,有时候需要引入第三方so lib库,但第三方so库比较大,例如开源第三方播放组件ffmpeg库, 如果直接打包的apk包里面, 整个应用程序会大很多.经过查阅资料和实验,发现通过远程下载so文件,然后再动态注册so文件时可行的。主要需要解决下载so文件存放位置以及文件读写权限问题。

 

二、主要思路

 

1、首先把so放到网络上面,比如测试放到:http://codestudy.sinaapp.com/lib/test.so

2、应用启动时,启动异步线程下载so文件,并写入到/data/data/packageName/app_libs目录下面

3、调用System.load 注册so文件。因路径必须有执行权限,我们不能加载SD卡上的so,但可以通过调用context.getDir("libs", Context.MODE_PRIVATE)把so文件写入到应用程序的私有目录/data/data/packageName/app_libs。

query.bindValue(5,ImgCodeZ);
query.bindValue(6,"png");
query.bindValue(7,pngImage,QSql::Binary);
query.bindValue(8,"GoldMap Gaoyong Sun");
query.bindValue(9,QDateTime::currentDateTime ());
可是工作需要,存储过程中要有返回值,或者输出参数,返回当前插入的ID号。通过测试得到解决方法。以最上方存储过程为例Qt中代码如下:

bool QtSqlServer::SqlInsertPcData(QtPcData* pcData)
{
    bool bFlag = false;
 
    QSqlQuery query;
    query.prepare("exec PINSERTPC ?, ?, ?, ?, ?, ? output");
    query.bindValue(0, pcData->GetPcNum());
    query.bindValue(1, pcData->GetPcName());
    query.bindValue(2, pcData->GetPcType());
    query.bindValue(3, pcData->GetIpAddress());
    query.bindValue(4, pcData->GetPort());
    query.bindValue(5, 0, QSql::Out);
    bFlag = query.exec();
    if (bFlag)
    {
        int pcID = query.boundValue(5).toInt();
        if (pcID < 0)
        {
            bFlag = false;
        }
        else
        {
            pcData->SetPcID(pcID);
            bFlag = true;
        }
    }
    else
    {
        QString str = query.lastError().text();
        QMessageBox::critical(0, QObject::tr("Error"),QObject::tr("%1").arg(str));
    }

    return bFlag;
}

也存在一些未知的疑问……这里的输出参数必须设置在存储过程的最后一个参数中返回,而且根据Server SQL中的要求必须有output的修饰,这样才可确保成功。

疑问1:如果存储过程想以返回值的形式返回,使用Qt如何调用。
疑问2:为何存储过程的输出参数必须设置才最后一个参数才可获取到正确的输出值,譬如想在第一个参数中返回,如何解决。
疑问3:有些存储过程有多个输出参数,但本人测试Qt只能以一个输出参数形式(设置为最后一个参数)调用……这事让我着实头疼!整的我其他的输出参数是在执着SQL语句查出来……

返回值的解决方法:

query.prepare("? = CALLPINSERTPC(?,?,?,?,?,?,?,?,?,?) ");

 

1 0