I am using the SOCI library to programmatically interact with a SQL Server DB via ODBC. I am having trouble getting values via output parameters in stored procedures. Some code (modeled after SOCI documentation)...

/*
 * 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;
  }
}

My code does not throw any errors or exceptions, but nothing is fetched, either. I have tried calling it many different ways (normal exec syntax, ODBC call syntax, etc.), but nothing seems to work. I'm wondering if the error goes back to this from here...

If an input/output parameter is omitted, or if a literal is supplied for the parameter, the driver discards the output value.

Unfortunately, SOCI doesn't really seem to support parameter markers, at least as far as I can tell.

I have made the code work by using this kind of syntax...

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));

But that isn't ideal, for reasons that I think are obvious.

Has anyone out there used SOCI and have some input into what I need to do differently to get this to work?

EDIT: I received the following response from the soci-users forum/mailing list...

I haven't used SOCI for a couple of years but I did successfully get stored procedures to work with ODBC on SQL Server, end of 2011, soci version 2 (I think).

I remember that to do it I had to use statement rather than procedure.

I had to amend the backend to call SQLMoreResults in a loop.

Output parameters I think were not supported in SOCI and I handled them direct with ODBC over which I also had a C++ layer.

However, since I'm a recent college grad (just started my first job this month!) and relatively inexperienced with C++ and database applications, I would really appreciate as much help as people are able to offer! For instance, regarding the above response - the last two points are not exactly clear to me.

有帮助吗?

解决方案

The problems is that I was using the SOCI ODBC, which apparently does not support stored procedures.

In the months since I initially asked this question, I have implemented my own SOCI backend, for which stored procedures work perfectly!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top