Sample stored procedure execute from c++ program - c++

DBPROCESS *dbconnect(DBPROCESS *dbproc)
int i,count;
char choice;
char num[2];
int page;
int index;
unsigned long num_recs = 0;
char db_epass[40], db_user[40], db_pass[40], db_database[60], db_server[40], db_dbname[60];
bool status,valid;
LOGINREC *loginrec;
int y=ScrWidth/2-10;
count=0;
/I WANT TO EXECUTE STORED PROCEDURE FROM HERE/
dbexit();
I'm new to c++ programming, I have the script above where I want to execute a SP with one parameter, passing the information of the 'db_user'.
can anyone guide my how to script it.
Database: mssql 2008

to connect to database and execute various pl/sql command (including stored procedure call) every vendor provides ODBC driver. In your question it is not clear where you are using the ODBC driver in your code and to what database you are trying to connect to. Frist check ODBC driver for your database and read vendor provided documentation/manual about how to use their driver with some examples. Every ODBC driver API are different and codes to execute pl/sql will also be different for different vendor provided ODBC driver APIs. Some third party provided ODBC driver APIs are generic for all the different database and you no need to write separate codes for different database, only database connecting string is different. One of them is datadirect. Read first vendor provided material on ODBC driver and you will get all the information in it. Wish you all the very best.

Related

How to convert unicode to ebcdic CCSIDs-1025 and write to a db2

My problem is that the input is an XML file with UTF-8 encoding.
The database is encoded with CCSIDs-1025 (DB2).
The application itself is windows-1251 encoded.
After parsing the XML, I save the data to a regular char array. Of course, in my system there is no mapping for Unicode conversion and the array stores the correct byte representation, but something like this:
"RњRRќRR •R RЎRR'Rћ PYPyPPŽPP R R•RРRЈR'R›RRR R R•R›RR RRR€ RR™R†R"
It's not a problem.
I can convert it to windows-1251 and write it correctly to DB2 with ebcdic or work in my code.
But!
Is it possible to directly convert unicode to EBCDIC before writing to a table?
I Found one useful instrument ICU4C and tried to convert "Moscow" (Москва) to a EBCDIC CCSIDs-1025.
```lang-cpp
// CONVERTION USING ICU
UChar source[] = { 0x041C, 0x043E, 0x0441, 0x043A, 0x0432,
0x0430, 0x0021, 0x0000 };
char target[100];
UErrorCode status = U_ZERO_ERROR;
UConverter *conv;
int32_t len;
// set up the converter
//! [ucnv_open]
conv = ucnv_openCCSID(1154, UCNV_IBM, &status);
//! [ucnv_open]
assert(U_SUCCESS(status));
// convert to EBCDIC-1154.
len = ucnv_fromUChars(conv, target, 100, source, -1, &status);
assert(U_SUCCESS(status));
```
And again it converted correctly. And codes of symbols corresponds to a target CCSID.
\xCF \x9E \xAB \x9A \xAF \x77 \x4F - this is the result.
But how i can store result and insert it to a table with correct mapping?
It still takes symbols from windows-1251 (my application encoding) and "Москва" mapped as "ПћљЇwO". How can i said to DB2 to use characters from CCSIDs-1025.
Also i use embedded SQL and host variables in c++ application.
May be i need to set encoding of host variables during bind?
Thank you!
#Dastin_DV regarding your questions about CCSID for embedded SQL and host variables and the data encoding scheme your application handles, I'd like to explain it further here.
In Db2 for z/OS applications, one CCSID is associated with the source code and one or more CCSIDs can be associated with the data that your application manipulates. The CCSID that Db2 associates with the data is called the application encoding scheme.
There are a few general rules:
for application source code which includes SQL statements and literal strings in the SQL statements, if you are using the Db2 precompiler, use the CCSID SQL processing option when you precompile the application, specify the same CCSID when you compile the application; if you are using the Db2 coprocessor, use the language compiler to set the CCSID.
for application data, like values that are passed through host variables and parameter markers, within SQL statements, use one or more of the following Db2 mechanisms to set the CCSID value of the application data, which is called the application encoding scheme
use the ENCODING bind option.2.c This option typically yields the best performance.
override the CCSID for a particular host variable by using the DECLARE VARIABLE statement with the CCSID option.
override the CCSID for parameter markers in dynamic SQL by specifying the CURRENT APPLICATION ENCODING SCHEME special register. Db2 uses the value of this special register at the time that the statement is executed
for application data that is referenced outside of SQL statements, use the rules of the programming language, in some cases, the CCSID of this data is the same as the CCSID of the source code.

Cannot make connection to SQL Server via ODBC

In the past, I have used ADO to access SQL Server, the connection string for the ADO connection object is:
Provider=sqloledb;Data Source=MYPC;Integrated Security=SSPI;
where MYPC is the name of my computer, and SQL Server is installed on my computer as the default instance.
The above connection string works well.
However, now it is said that ADO is outdated and ODBC is recommended again by Microsoft (see https://blogs.msdn.microsoft.com/sqlnativeclient/2011/08/29/microsoft-is-aligning-with-odbc-for-native-relational-data-access/ ), so I have to modify my code to use ODBC instead.
So I changed the connection to SQL Server to the following code:
CDatabase Database;
// Provider=sqloledb;Data Source=MYPC;Integrated Security=SSPI;
Database.OpenEx(_T("Driver = {SQL Native Client}; Server = MYPC; Trusted_Connection = yes;"), CDatabase::noOdbcDialog);
Database.ExecuteSQL(_T("create database [MyDB2019] on primary (name=[MyDB2019_File],filename='F:\\MyDB2019.mdf')"));
Database.Close();
However, this code does not work. After executing Database.OpenEx, there will be a CDBException indicating
Data source name not found and no default driver specified.
Why?
Note: I am using Visual C++ 2008 and ADO
The error/exception is pointing to the problem (albeit it seems a bit generic at first).
"Data source name not found and no default driver specified"
Data source name not found --> You did not specify a DSN, you do not
want to use a DSN, ignore this part
.
and no default driver specified --> You intend to use a driver, so this part of the error most likely applies to you.
The connection string appears syntactically correct: "Driver={Driver Name}...", so the next
step is to check whether the driver you try to use, named SQL Native Client, exists
on your machine.
"SQL Native Client" was/is the driver name for SQL Server 2005.
From SQL2008 the driver name got a version descriptor.
Driver={SQL Native Client} ,sql2005
Driver={SQL Server Native Client 10.0} ,sql2008
Driver={SQL Server Native Client 11.0} ,sql2012 and later
Driver={ODBC Driver 11 for SQL Server} ,sql2012 and later, odbc appears in the name
Driver={ODBC Driver 13 for SQL Server}
Driver={ODBC Driver 17 for SQL Server}
An easy way to find the installed 'SQL Native' and 'ODBC Driver for SQL Server' drivers on your machine, would be to run the ODBC Data Source Administrator. Type Odbc data sources in your search box or odbcad32.exe in the command/address bar (for 64bit: %windir%\system32\odbcad32.exe)
When in ODBC Data Source Administrator, switch to the Drivers tab and there you will find all the available/installed drivers, at your disposal.
Here is a powershell script that opens a connection to localhost using odbc. Adjust accordingly to your installed driver(s)
cls
$conn = new-object system.data.odbc.odbcconnection
$conn.connectionstring =
# all these installed on my pc and working
#"Driver={SQL Server Native Client 11.0};Server=localhost; Database=master;Trusted_Connection=yes;"
#"Driver={SQL Server};Server=localhost; Database=master;Trusted_Connection=yes;"
#"Driver={ODBC Driver 11 for SQL Server};Server=localhost; Database=master;Trusted_Connection=yes;"
"Driver={ODBC Driver 17 for SQL Server};Server=localhost; Database=master;Trusted_Connection=yes;"
$conn.Open()
$conn.State
$conn.Close();
..and an mfc button
void CMFCDBTestDlg::OnBnClickedButton1()
{
// TODO: Add your control notification handler code here
CDatabase database;
CString connectionstring = _T("Driver={SQL Server Native Client 10.0};Server=localhost;Trusted_Connection=yes;");
CString messagetext;
TRY{
//database.Open(NULL, FALSE, FALSE, connectionstring, FALSE); //ok
database.OpenEx(connectionstring, CDatabase::noOdbcDialog); //ok
if (database.IsOpen()){
messagetext = _T("open, database:") + database.GetDatabaseName();
database.Close();
}
}CATCH(CDBException, e) {
messagetext = _T("Database error: ")+e->m_strError;
}
END_CATCH;
AfxMessageBox(messagetext, 0, 0);
}
Create a file with udl extension. Example: test.udl
Double click the file. Use the GUI to connect to your database. Once done, open the UDL file using notepad and extract the connection string.
See https://www.dmxzone.com/go/312/how-to-generate-an-ado-connection-string/
The problem comes from the extra spaces in the connection string, after removing extra spaces from:
"Driver = {SQL Native Client}; Server = MYPC; Trusted_Connection = yes;"
to(and change the driver name as well):
"Driver={SQL Server Native Client 10.0};Server=MYPC;Trusted_Connection=yes;"
The connection will succeed.

Unable to connet to SQL server using soci library

I am beginner in c++,my problem on Linux for connecting to SQL Server with soci library, my code this but I have error and I don't found solution for my problem, my code this:
I have error:
[unixODBC][Driver Manager]Data source name not found, and no default driver specified (SQL state IM002)
Here is the code:
try{
soci::session sql("odbc","DSN=ODBC;UID=sa;PWD=sa123; Connection Driver=TDS;Database=ReportServer; Server=192.168.1.52;Port=1433;");
}
catch(soci::odbc_soci_error const & e){
cout<<"start error";
cout<<e.odbc_error_code()<<endl;
cout<<e.what();
}
Your ODBC connection string in incorrect, your first parameter specifies a datasource called "ODBC", which you haven't configured in your operating system/odbc manager.
So either you should configure a data source with the given parameters like UID=sa;PWD=sa123; Connection Driver=TDS;Database=ReportServer; Server=192.168.1.52;Port=1433; with the corresponding ODBC data source manager/linux administration program, with a useable name like "local_test_db" and just use "DSN=local_test_db" as your connection string
or (exclusive or)
remove the "dsn=ODBC" part from your connection string and try it again with "UID=sa;PWD=sa123; Connection Driver=TDS;Database=ReportServer; Server=192.168.1.52;Port=1433;"

Use mysql embedded and --local-infile=1 with c++?

I am connecting to a mysql database using the embedding server (linking against mysqld) in c++. I have the following code:
static char *server_options[] = \
{ (char *)"mysql_test",
(char *)"--datadir=/home/cquiros/temp/mysql/db2",
(char *)"--default-storage-engine=MyISAM",
(char *)"--loose-innodb=0",
(char *)"--local-infile=1",
(char *)"--skip-grant-tables=1",
(char *)"--myisam-recover=FORCE",
(char *)"--key_buffer_size=16777216",
(char *)"--character-set-server=utf8",
(char *)"--collation-server=utf8_bin",
NULL };
int num_elements = (sizeof(server_options) / sizeof(char *)) - 1;
mysql_library_init(num_elements, server_options, NULL);
m_mysql = mysql_init(NULL);
char enable_load_infile = 1;
if (mysql_options(m_mysql,MYSQL_OPT_LOCAL_INFILE, (const char *)&(enable_load_infile)))
qDebug() << "Error setting option";
mysql_real_connect(m_mysql, NULL,NULL,NULL, "database1", 0,NULL,0);
The connection works and I can query and create tables however, when I try to execute "load data local infile ..." I always get "The used command is not allowed with this MySQL version" even though I am setting --local-infile=1 in the server options or setting it in code in:
char enable_load_infile = 1;
if (mysql_options(m_mysql,MYSQL_OPT_LOCAL_INFILE, (const char *)&(enable_load_infile)))
qDebug() << "Error setting option";
Any idea what I am doing wrong and how to fix it?
Many thanks for your help.
Carlos.
#QLands I realize its over a year since you've asked this question, but I figured I'd reply just for posterity in case others like me are googling for solutions.
I'm having the same issue, I can get LOAD DATA LOCAL INFILE statements to work from the Linux mysql CLI after I explicitly enabled it in the /etc/mysql/my.cfg file. However I CANNOT get it to work with the MySQL C++ connector -- I also get the error "The used command is not allowed with this MySQL version" when I try and run a LOAD DATA LOCAL INFILE command through the MySQL C++ connector. wtf right?
After much diligent googling and finding some back alley tech support posts I've come to conclude that the MySQL C++ connector did not (for whatever reason) decide to implement the ability for developers to be able to allow the local-infile=1 option. Apparently some people have been able to hack/fork the MySQL C++ connector to expose the functionality, but no one posted their source code -- only said it worked. Apparently there is a workaround in the MySQL C API after you initialize the connection you would use this:
mysql_options( &mysql, MYSQL_OPT_LOCAL_INFILE, 1 );
Here are some reference articles that lead me to this conclusion:
1.)
How can I get the native C API connection structure from MySQL Connector/C++?
2.)
Mysql 5.5 LOAD DATA INFILE Permissions
3.)
http://osdir.com/ml/db.mysql.c++/2004-04/msg00097.html
Essentially if you want the ability to use the LOAD DATA LOCAL INFILE functionality -- you have to use the mysql C API or execute it from the command line or hack/fork the existing mysql C++ api to expose the connection structure
:(

Good C/C++ connector library for PostgreSQL [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking us to recommend or find a book, tool, software library, tutorial or other off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it.
Closed 8 years ago.
Improve this question
My application is a commercial GIS C++ application, and I'm looking for a robust/easy to use connector for Postgresq. (Side note: I also plan to use PostGIS)
Does anyone have any recommendations based on your experience? A plus would be if you have tried out various ones.
I have looked at:
Postgres's C client
pqxx
QSql
EDIT
Also, does anyone know what's a good admin GUI tool? I see a community list here. But there are so many! I'm developing on Windows, and dont mind paying for commercial tools.
Someone in another Stackoverflow post suggested Maestro.
libpq++ is one provide very good connector for PostgreSQL
SQLAPI++ is a C++ library for accessing multiple SQL databases (Oracle, SQL Server, DB2, Sybase, Informix, InterBase, SQLBase, MySQL, PostgreSQL and ODBC, SQLite).
Abstract Database Connector is a C/C++ library for making connections to several databases (MySQL, mSQL, PostgreSQL, Interbase, Informix, BDE, ODBC). It runs on Linux, UNIX, BeOS, and Windows, and a dynamic driver loader for ELF OSes is under development
Navicat is Nice GUI tool for PostgrSQL
Take a look at SOCI. Is an open source lib under Boost Software License (one of the most non-restrictive licenses at all).
This lib is designed especially for C++ with the idea of generic programming and type safety in mind.
SOCI Site
I wrote a wrapper around libpq for our needs. I was a long time Zeoslib (http://sourceforge.net/projects/zeoslib/) but they were riped with problems last I used them, didn't support cached datasets and plain slow.
libpq is very, very fast.
I simply download the Windows version of Postgres, copy all the DLLs to a lib directory and export the calls, include the .h and link accordingly.
I realize this is very low level but I can't emphasize enough the performance increase I'm realizing as a result.
Our application is an accounting/ERP type business application with fairly large install base some with fairly significant concurrent many user base (60, 100 connections)... This has served us very well... You can reply back if you want more details on how we wrap libpq and handle cached updates.
UPDATE:
From a request here are the steps to wrap libpq or make use of it directly under windows.
First, to level set, I use Embarcadero RAD XE these days so the commands that follow are the command line tools that ship with RAD XE. You also need to make sure that your command line tools are in the PATH environment variable if not already. If using Visual Studio, then you will have to work out the equivalent commands. Basically I'm creating a .lib file out of a .DLL
TEST.C is a minimalist test code I wrote to make sure I understood how to use libpq and also to test my success.
1. Put all the DLLs into a directory and copy the include directory.
You do not need to install PostgreSQL using the MSI build to get these DLLs, although that would work too. I copied the DLLs from the binary build. The .H files were also taken from the binary build as well. So my directory looks like this:
include\
libpq-fe.h
postgres_ext.h
libeay32.dll
libiconv-2.dll
libintl-8.dll
libpq.dll
ssleay32.dll
zlib1.dll
2. Create an import library against LIBPQ.DLL as follows:
implib -c -a libpq.lib libpq.dll
should now have a libpq.lib file in the same directory as your DLLs.
3. build the test program (or any program) as follows:
bcc32 test.c -l libpq.lib
test.c
#include <stdio.h>
#include "include/libpq-fe.h"
char *db = "mydatabasename";
char *dbserver = "hostname";
char *uname = "username";
char *pass = "password";
char *SQL = "select * from public.auditlog;";
// char *SQL = "select userid, stationid from public.auditlog";
char buff[200];
PGconn *dbconn;
PGresult *res;
void main(void)
{
int nFields, i, j;
printf("Attempting to Connect to Database Server:\n");
printf("Database: %s\n", db);
printf("Server : %s\n", dbserver);
sprintf(buff, "dbname=%s host=%s port=5432 user=%s password=%s",
db, dbserver, uname, pass);
dbconn = PQconnectdb(buff);
if( PQstatus(dbconn) != CONNECTION_OK )
printf("Connection Failed: %s\n", PQerrorMessage(dbconn) );
else
{
printf("Connected Successfully!\n");
sprintf(buff, "BEGIN; DECLARE my_portal CURSOR FOR %s", SQL);
res = PQexec(dbconn, buff);
if( PQresultStatus(res) != PGRES_COMMAND_OK )
{
printf("Error executing SQL!: %s\n", PQerrorMessage(dbconn) );
PQclear(res);
}
else
{
PQclear(res);
res = PQexec(dbconn, "FETCH ALL in my_portal" );
if( PQresultStatus(res) != PGRES_TUPLES_OK )
{
printf("ERROR, Fetch All Failed: %s", PQerrorMessage(dbconn) );
PQclear(res);
}
else
{
nFields = PQnfields(res);
// Print out the field names
for(i=0; i<nFields; i++ )
printf("%-15s", PQfname(res, i) );
printf("\n");
// Print out the rows
for(i=0; i<PQntuples(res); i++)
{
for(j=0; j<nFields; j++)
printf("%-15s", PQgetvalue(res, i, j) );
printf("\n");
}
res = PQexec(dbconn, "END" );
PQclear(res);
}
}
}
PQfinish(dbconn);
}
Now to access a PostgreSQL system I simply copy the libpq.lib file into any new RAD-XE project and add the libpq.lib to the project. I have wrapped the libpq into a database transport driver that sort of separates my database access code away.
The following screen shot shows a RAD-XE project called ptidb that, in turn, uses libpq to provide PostgreSQL support. I also support SQLite except with SQLite I just compile the database directly.
Then I simply ship the DLLs, listed above, along with my final product making sure the DLLs wind up in the same directory as my product.
This should get you going. If you're also interested in the C++ wrapping I do, let me know and I'll post another update with some of it.