Upload .csv to SQL server using C++ - c++

I am working with Visual Studio 2012 Express version under Windows 7. On the other hand, the SQL server is "SQL Server 2008 R2".
I've tried following C++ codes:
#include <iostream>
#include <windows.h>
#include <string>
#include <sql.h>
#include <sqltypes.h>
#include <sqlext.h>
using namespace std;
void main()
{
clock_t start = clock();
SQLHANDLE sqlevent, sqlconnection, sqlstatement;
if(SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &sqlevent))
{
cout<<"The sqlevent has failed to be created."<<endl;
system("pause");
return;
}
if(SQL_SUCCESS != SQLSetEnvAttr(sqlevent, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0))
{
cout<<"The sqlevent has failed to be initialized."<<endl;
system("pause");
return;
}
if(SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_DBC, sqlevent, &sqlconnection))
{
cout<<"The sqlconnection has failed to be created."<<endl;
system("pause");
return;
}
SQLCHAR retstring[10000];
SQLDriverConnect(sqlconnection, NULL, (SQLCHAR*)("DRIVER={SQL Server Native Client 10.0};SERVER=DATASERVER;DATABASE=DATABASE;UID=CrystalReports;PWD=PASSWORD"), SQL_NTS, retstring, 10000, NULL, SQL_DRIVER_NOPROMPT);
if(SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_STMT, sqlconnection, &sqlstatement))
{
cout<<"The sqlstatement has failed to be created."<<endl;
system("pause");
return;
}
string commandline;
commandline = "CREATE TABLE NEW_TABLE ( ID VARCHAR(10), AGE FLOAT) GO ";
if(SQL_SUCCESS != SQLExecDirect(sqlstatement, (SQLCHAR*)(commandline.c_str()), SQL_NTS))
{
cout<<"The create table sql command has failed to excute."<<endl;
system("pause");
return;
}
commandline = "BULK INSERT NEW_TABLE FROM 'C:/temp/datafile.csv' WITH ( FIELDTERMINATOR = ',', ROWTERMINATOR = '\n') GO";
if(SQL_SUCCESS != SQLExecDirect(sqlstatement, (SQLCHAR*)(commandline.c_str()), SQL_NTS))
{
cout<<"The import sql command has failed to excute."<<endl;
system("pause");
return;
}
clock_t end = clock();
cout<<"Import from .csv file to SQL Server costs "<<((end-start)/double(CLOCKS_PER_SEC))<<" seconds."<<endl;
system("pause");
return;
}
When I run this code, the program always stops at create table.
I wonder if I don't have the permission to create a table, thus I mannually created a table. And there is a warning pops out:
May I know if the warning shown in the above image is the reason my code fail, or I simply made mistakes in the code?
Many thanks.

Who owns the database? You need to find your database administrator and get them to grant you permission to add tables to the database.

You may want to check what permissions that account has been GRANTED.
You will need permissions to INSERT as well as to BULKADMIN server role.
But as you can see in this post it can get hairy depending on where the file is located. You can at

Related

SQLExecDirect command is not working same queries

I'm working Visual Studio 2017 and SQL Server 2017 .
I want to do is create a query with C ++ and that will run it on SQL Server.
if (SQL_SUCCESS != SQLExecDirect(sqlStmtHandle, (SQLWCHAR*)L"SELECT ##VERSION", SQL_NTS)) {
cout << "Database Already Exits or Cannot Created";
cout << "\n";
goto COMPLETED;
}
else {
cout << "Success !!!";
cout << "\n";
}
I use this sample : https://www.techhowtos.com/programming/how-to-connect-to-sql-server-from-visual-c-plus-plus/
But ,
if (SQL_SUCCESS != SQLExecDirect(sqlStmtHandle, (SQLWCHAR*)L"SELECT ##VERSION", SQL_NTS))
on this line , if i'm write
if (SQL_SUCCESS != SQLExecDirect(sqlStmtHandle, (SQLWCHAR*)L"**USE database_name**", SQL_NTS))
or
if (SQL_SUCCESS != SQLExecDirect(sqlStmtHandle, (SQLWCHAR*)L"**SELECT * FROM sampletable**", SQL_NTS))
or
if (SQL_SUCCESS != SQLExecDirect(sqlStmtHandle, (SQLWCHAR*)L"INSERT INTO sampletable (one,two,three) VALUES (1,2,3)", SQL_NTS))
this query is not working .
But ,
if i'm running this queries (some sample) ;
if (SQL_SUCCESS != SQLExecDirect(sqlStmtHandle, (SQLWCHAR*)L"**CREATE DATABASE blablabla**", SQL_NTS))
or
if (SQL_SUCCESS != SQLExecDirect(sqlStmtHandle, (SQLWCHAR*)L"**DELETE DATABASE blablabla**", SQL_NTS))
Queries are working .
i have a 2 function
void run_query(string query);
void create_query();
create query function working is normally . generate a query and this query goes to run_query .
What should I do in the run_query() function so that every created query works?
My all codes in here : https://paste.laravel.io/7c693fdb-2dc9-41cc-b183-6e45fd3d9b6d
Thanks for everything :)
SQLExecDirect can return values besides SQL_SUCCESS when the statement succeeds. For example, USE will normally return SQL_SUCCESS_WITH_INFO to indicate the statement succeeded and that informational/warning messages ("changed database context") were returned. Messages can be retrieved with SQLGetDiagRec if desired.
I suggest you consider at least all the "happy path" ODBC function call return values and handle each appropriately, raising an exception with diagnostic information when an unexpected value is returned.

Very long query execution using C++, Sql Server and ODBC connection

I'm using the following code to connect to a sql-server database. I can run all other queries with no difficulties using the same function. However, one query executes in Sql management studio and in R using RODBC in ~11 seconds but takes over an hour (at the "SQLExecDirect" function) using c++. Has anyone else had this issue and how did you resolve it?
std::string sqlQuery="[myquery]";
SQLHANDLE sqlconnectionhandle;
SQLAllocHandle(SQL_HANDLE_DBC, sqlenvhandle, &sqlconnectionhandle);
SQLCHAR retconstring[1024];
SQLDriverConnect (sqlconnectionhandle, NULL,
conn_str,
len, retconstring, 1024, NULL,SQL_DRIVER_NOPROMPT);
SQLHANDLE sqlstatementhandle;
SQLAllocHandle(SQL_HANDLE_STMT, sqlconnectionhandle, &sqlstatementhandle);
//this is where the program "hangs" for over an hour
if(SQL_SUCCESS!=SQLExecDirect(sqlstatementhandle, (SQLCHAR*)(sqlQuery.c_str()), SQL_NTS)){
show_error(SQL_HANDLE_STMT, sqlstatementhandle, errorMsg);
return;
}
int numRow=0;
while(SQLFetch(sqlstatementhandle)==SQL_SUCCESS){
for(int i=1; i<=numFields+1; ++i){
double myVal;
SQLGetData(sqlstatementhandle, i, SQL_C_DOUBLE, &myVal, 0, NULL);
cb(myVal, numRow, i-1); //callback function defined elsewhere
}
numRow++;
}
SQLFreeHandle(SQL_HANDLE_STMT, sqlstatementhandle );
SQLDisconnect(sqlconnectionhandle);
SQLFreeHandle(SQL_HANDLE_DBC, sqlconnectionhandle);
That is because the ArithAbort property on your database is off.
See also http://www.sommarskog.se/query-plan-mysteries.html
You can check it and correct it with this small script
declare #value sql_variant
select #value = SESSIONPROPERTY('ARITHABORT')
if #value <> 1
begin
USE master
ALTER DATABASE [your_database] SET ARITHABORT ON WITH NO_WAIT
use your_database
end
I figured this out: my connection string's default database was different than the one that I had as the default database in SSMS. Switching this made the query run in the same speed as SSMS.

C++ SQLExecDirect INSERT doesn't work

I've wrote a simple SQL C++ Wrapper-Class, where I encountered a real strange Problem. When I call an INSERT-Command with SQLExecDirect, the data does not appear in the SQL Database (SQL Server 2012), although SQLRowCount returns one row. The table, which I'm trying to write to, is named "Person" and has four columns (ID (AUTOINCREMENT), Firstname (nvarchar(100)), Lastname (nvarchar(100)), Birthday (date))
Here is my code:
Class-Constructor (EnvHandle, DBCHandle and StmtHandle are class-members)
SQLDatabase::SQLDatabase()
{
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &EnvHandle);
SQLSetEnvAttr(EnvHandle, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);
SQLAllocHandle(SQL_HANDLE_DBC, EnvHandle, &DBCHandle);
SQLSetConnectAttr(DBCHandle, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, SQL_IS_INTEGER);
}
Query-Member-Function
int SQLDatabase::ExecuteNonQuery(std::wstring Command)
{
SQLRETURN RetCode = -1;
SQLINTEGER RowCount = 0;
SQLAllocHandle(SQL_HANDLE_STMT, DBCHandle, &StmtHandle);
RetCode = SQLExecDirect(StmtHandle, (SQLWCHAR*)Command.c_str(), Command.length());
if (RetCode == SQL_SUCCESS || RetCode == SQL_SUCCESS_WITH_INFO)
{
SQLRowCount(StmtHandle, &RowCount);
SQLFreeHandle(SQL_HANDLE_STMT, StmtHandle);
return RowCount;
}
else
{
SQLFreeHandle(SQL_HANDLE_STMT, StmtHandle);
return -1;
}
}
Function-Call in main.cpp
wcout << "Firstname:\n>";
wcin >> Firstname;
wcout << "Lastname:\n>";
wcin >> Lastname;
wcout << "Birthday:\n>";
wcin >> Birthday;
InsRows = database.ExecuteNonQuery(L"INSERT INTO Person (Firstname,Lastname,Birthday) VALUES ('" + Firstname + L"','" + Lastname + L"','" + Birthday + L"')");
if (InsRows == -1)
database.Error();
else
std::wcout << InsRows << " rows affected!" << std::endl;
As already said, "database.ExecuteNonQuery" returns one row.
When take a look at the table in SQL Management Studio, the datarow hasn't been added. I've already traced the queries on the table. The query appears in the tracelog correctly without any additional info. My IDE is Visual Studio 2013.
Any ideas how I could get the data into the table?
Thanks!
Sebastian
In general, whenever a query is executed that changes a table (without error) and the results are not shown, this means that the changes were not committed.
Looking at your code, you have this:
SQLSetConnectAttr(DBCHandle, SQL_ATTR_AUTOCOMMIT,
(SQLPOINTER)SQL_AUTOCOMMIT_OFF, SQL_IS_INTEGER);}
You set the connection attribute to have auto commit turned off. Either specify you want auto commit on, or issue a call to SQLEndTran to commit the changes.
You're using SQL_AUTOCOMMIT_OFF, which means your statements won't be automatically committed, so your new record is visible only in your transaction and will never be committed in the database. Try to use the auto-commit feature of the MS SQL Server (setting SQL_ATTR_AUTOCOMMIT to SQL_AUTOCOMMIT_ON or just leave it uninformed since it's the default behaviour) or explicitly begin and commit your transaction.
http://msdn.microsoft.com/en-us/library/ms713605(v=vs.85).aspx

libmysql mysql_real_connect fails with IP address but works with localhost

Okay so my issue is pretty straight forward, I am relatively new to C++ so this may be an easy answer for some, but I am using libmysql to connect to a database and so far it works just as I need it too. But I want to be able to connect to a database not found at local host, the database will still be on my LAN but just not on the local machine. I am pretty sure that the unix_socket parameter is all that i need to change but i have no clue how or what to change it to or how to make a "unix_socket". Below i will post my code and thank you in advanced for help thanks!
void readFromDB(){
skip:
MYSQL *connect; // Create a pointer to the MySQL instance
connect=mysql_init(NULL); // Initialise the instance
/* This If is irrelevant and you don't need to show it. I kept it in for Fault Testing.*/
if(!connect) /* If instance didn't initialize say so and exit with fault.*/
{
fprintf(stderr,"MySQL Initialization Failed");
}
/* Now we will actually connect to the specific database.*/
connect=mysql_real_connect(connect,"10.1.3.253",USER,PASSWORD,DATABASE,3306, NULL,0);
/* Following if statements are unneeded too, but it's worth it to show on your
first app, so that if your database is empty or the query didn't return anything it
will at least let you know that the connection to the mysql server was established. */
if(connect){
printf("First Connection Succeeded\n");
system("PAUSE");
}
else{
printf("Connection Failed!\n");
Sleep(800);
goto skip;
}
MYSQL_RES *result; /* Create a pointer to recieve the return value.*/
MYSQL_ROW row; /* Assign variable for rows. */
//mysql_query(connect,"SELECT * FROM locationTime");
/* Send a query to the database. */
if(!(mysql_query(connect,"SELECT * FROM locationtime") == 0)){
mysql_close(connect);
Sleep(300);
goto skip;
}
result = mysql_store_result(connect); /* Receive the result and store it in res_set */
unsigned int numrows = mysql_num_rows(result); /* Create the count to print all rows */
/* This while is to print all rows and not just the first row found, */
if(numrows != 0){
while ((row = mysql_fetch_row(result)) != NULL){
ids.push_back(row[0]);
dateTime.push_back(row[1]);
locs.push_back(setLocation(row[2]));
strLocs.push_back(row[2]);
imgPaths.push_back(row[3]);
//for(int i = 0; i<(sizeof(row) ); i++){
// //printf("%s\n",row[i] != NULL ? row[i] : "NULL"); /* Print the row data */
//}
//cout<<endl<<endl;
}
}else if(numrows <= 0){
mysql_close(connect); /* Close and shutdown */
mysql_free_result(result);
Sleep(200);
goto skip;
}
mysql_close(connect); /* Close and shutdown */
mysql_free_result(result);
return;
}
and here is my header file:
#include "my_global.h" // Include this file first to avoid problems
#include "mysql.h" // MySQL Include File
#define SERVER "10.1.3.253"
#define USER "user"
#define PASSWORD "pass"
#define DATABASE "DBName"
Usually if you're having a problem connecting via IP it's that your user account is not allowed to connect from a "remote" address.
Normally this is fixed by:
GRANT ALL PRIVILEGES ON *.* TO `user`#`%` IDENTIFIED BY '...'
Where user is your username. You may want to lock down access more, obviously.
localhost is what's used for "local" connections via UNIX socket. All others are treated as remote.

Excute create table in SQL Server with C++

I am trying to create a table in SQL Server with following code:
#include <iostream>
#include <windows.h>
#include <string>
#include <sql.h>
#include <sqltypes.h>
#include <sqlext.h>
using namespace std;
void main()
{
SQLHANDLE sqlevent, sqlconnection, sqlstatement;
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &sqlevent);
SQLSetEnvAttr(sqlevent, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);
SQLAllocHandle(SQL_HANDLE_DBC, sqlevent, &sqlconnection);
SQLCHAR retstring[10000];
SQLDriverConnect(sqlconnection, NULL, (SQLCHAR*)("DRIVER={SQL Server Native Client 10.0};SERVER=SERVER;DATABASE=DATABASE;UID=CrystalReports;PWD=PASSWORD"), SQL_NTS, retstring, 10000, NULL, SQL_DRIVER_NOPROMPT);
SQLAllocHandle(SQL_HANDLE_STMT, sqlconnection, &sqlstatement);
string commandline;
commandline = "CREATE TABLE NEW_TABLE01(Name VARCHAR(10), Age INT, Salary DOUBLE PRECISSION)";
if(SQL_SUCCESS != SQLExecDirect(sqlstatement, (SQLCHAR*)(commandline.c_str()), SQL_NTS)) // SQLExecDirect always failed to excute
{
cout<<"The create table sql command hasn't been excuted successfully."<<endl;
return;
}
return;
}
However, the code if(SQL_SUCCESS != SQLExecDirect(sqlstatement, (SQLCHAR*)(commandline.c_str()), SQL_NTS)) always return a TRUE, which means the SQL command was not sucessfully excuted.
I've got all the permission to create a table, and I've check the SQL command in SQL server manually, and it works.
May I know what am I wrong? And how can I achieve my goal?
Many thanks in advance.
I think I've got answer since inspired by C++ SQL Database program
I realised that there are different schemas in SQL Server, thus I use CREATE TABLE [ROU].[NEW_TABLE01] instead. Now my code works well.