我使用SOCI库通过ODBC以编程方式与SQL Server数据库交互。我在通过存储过程中的输出参数获取值时遇到问题。一些代码(以SOCI文档为模型)。。。
/*
* create procedure
* Dan.soci_proc @id int, @name varchar(32) output
* as begin
* set nocount on;
* select @name = name from Dan.soci_test where id = @id
* end
*/
std::string sql = "Dan.soci_proc :id, :name";
std::string name;
int proc_ndx = 1;
soci::procedure proc = (my_soci.get_session().prepare << sql, soci::use(proc_ndx),
soci::use(name));
std::cout << "nAttempting to execute stored procedure " << size << " times."
<< std::endl;
for (; proc_ndx < adj_size; ++proc_ndx) {
try {
proc.execute();
while (proc.fetch())
std::cout << "Fetched: " << name << std::endl;
} catch (const soci::odbc_soci_error& e) {
std::cerr << "Error executing stored procedure." << std::endl;
std::cerr << e.what() << std::endl;
std::cerr << e.odbc_error_message() << std::endl;
return;
}
}
我的代码没有抛出任何错误或异常,但也没有提取任何内容。我尝试过用多种不同的方式(普通的exec
语法、ODBCcall
语法等)调用它,但似乎都不起作用。我想知道错误是否会从这里回到这里。。。
如果省略了输入/输出参数,或者提供了文字对于该参数,驱动程序将丢弃输出值。
不幸的是,SOCI似乎并不真正支持参数标记,至少据我所知。
我已经通过使用这种语法使代码工作。。。
std::string sql = "declare @name varchar(32); "
"exec Dan.soci_proc :id, @name = @name output; select @name";
...
soci::procedure proc = (my_soci.get_session().prepare << sql, soci::use(proc_ndx),
soci::into(name));
但这并不理想,原因我认为是显而易见的。
有没有人使用过SOCI,并对我需要做的不同事情有一些意见,以使其发挥作用?
编辑:我收到了以下来自soci用户论坛/邮件列表的回复。。。
我已经有几年没有使用SOCI了,但我确实成功地获得了在SQL Server上使用ODBC的存储过程,2011年底,soci版本2(我认为)。
我记得要做到这一点,我必须使用语句而不是程序。
我不得不修改后端以循环调用SQLMoreResults。
我认为输出参数在SOCI中不受支持,我处理了它们直接与ODBC连接,在ODBC上我还有一个C++层。
然而,由于我刚从大学毕业(本月刚开始我的第一份工作!),对C++和数据库应用程序相对缺乏经验,我真的很感激人们能提供的帮助!例如,关于上述回应,最后两点对我来说并不完全清楚
问题是我使用的是SOCI ODBC,它显然不支持存储过程。
- SOCI现有后端
- SOCI ODBC后端-存储过程
自从我最初提出这个问题以来的几个月里,我已经实现了自己的SOCI后端,存储过程可以完美地工作!