Qt: Low speed when transferring data from remote database - sql-server

I am using Qt5 on Windows7.
I am writing a Qt app to replace an old C# app (written 7-8 years ago). The goal is to connect and transfer data from some remote databases. The remote DB servers are MS SQL Server 2000.
I already have the app running, but I noticed the data transfer takes much more time comparing to the old C# app...
So, I was just wondering what may cause such a low data transfer rate?
Maybe I forgot something or maybe I am doing something wrong...
Here is the code I am using to connect to the remote database(s):
void RemoteDB::openConnection(const QString & serverIP, const QString & dbName)
{
QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
db.setDatabaseName(QString("DRIVER={SQL Server};SERVER=%1;DATABASE=%2;").arg(serverIP).arg(dbName));
db.open("user", "password");
}
Query code:
SqlRecord record;
QSqlQuery query(QSqlDatabase::database());
if(query.exec("SELECT * FROM VehicleStatus") == true)
{
while(query.next() == true)
{
record.Vehicle = query.value("Vehicle").toInt();
record.Status = query.value("Status").toInt();
record.AppVersion = query.value("AppVersion").toString();
record.DateTime = query.value("DateTime").toString();
...
}
}
Please help, any idea?
Thanks for your time!

Beside trimming the fat (i.e. only selecting the fields you need instead of *), check that you're using the best ODBC driver possible.
SQL Server has a "ODBC SQL Server Native Client" that you can install and use, it should be faster than the default ODBC driver. It might already be installed on your PC, but not selected for your data source, or you can try to install it from some dusty SQL Server 2000 DVD (or was it CDs back then ? or - not kidding - floppy disks ?), or from a more recent SQL Server version. YMMV.
Not sure about C#, but a C# app has probably access to a fast-line driver that doesn't need ODBC.

Related

Database and Dataset data is empty [duplicate]

Apparently, using AttachDbFilename and user instance in your connection string is a bad way to connect to a DB. I'm using SQL server express on my local machine and it all seems to work fine. But what's the proper way to connect to SQL server then?
Thanks for your explanation.
Using User Instance means that SQL Server is creating a special copy of that database file for use by your program. If you have two different programs using that same connection string, they get two entirely different copies of the database. This leads to a lot of confusion, as people will test updating data with their program, then connect to a different copy of their database in Management Studio, and complain that their update isn't working. This sends them through a flawed series of wild goose chase steps trying to troubleshoot the wrong problem.
This article goes into more depth about how to use this feature, but heed the very first note: the User Instance feature has been deprecated. In SQL Server 2012, the preferred alternatives are (in this order, IMHO):
Create or attach your database to a real instance of SQL Server. Your connection string will then just need to specify the instance name, the database name, and credentials. There will be no mixup as Management Studio, Visual Studio and your program(s) will all be connecting to a single copy of the database.
Use a container for local development. Here's a great starter video by Anna Hoffman and Anthony Nocentino, and I have some other resources here, here, and here. If you're on an M1 Mac, you won't be able to use a full-blown SQL Server instance, but you can use Azure SQL Edge if you can get by with most SQL Server functionality (the omissions are enumerated here).
Use SqlLocalDb for local development. I believe I pointed you to this article yesterday: "Getting Started with SQL Server 2012 Express LocalDB."
Use SQL Server Compact. I like this option the least because the functionality and syntax is not the same - so it's not necessarily going to provide you with all the functionality you're ultimately going to want to deploy. Compact Edition is also deprecated, so there's that.
Of course if you are using a version < SQL Server 2012, SqlLocalDb is not an option - so you should be creating a real database and using that consistently. I only mention the Compact option for completeness - I think that can be almost as bad an idea as using AttachDbFileName.
EDIT: I've blogged about this here:
Bad Habits : Using AttachDBFileName
In case someone had the problem.
When attaching the database with a connection string containing AttachDBFile
with SQLEXPRESS, I noticed this connection was exclusive to the ASP.NET application that was using the database. The connection did block the access to all other processes on the file level when made with System.Data.SqlClient as provider.
In order to assure the connection to be shareable with other processes
instead use DataBase to specify the database name in your connection string
Example or connection string :
Data Source=.\SQLEXPRESS;DataBase=PlaCliGen;User ID=XXX;password=ZZZ; Connect Timeout=30
,where PlaCliGen is the name (or logical name) by which SQLEXPRESS server knows the database.
By connecting to the data base with AttachDBFile giving the path to the .mdf file
(namely : replacing DataBase = PlacliGen by AttachDBFile = c:\vs\placligen\app_data\placligen.mdf) the File was connected exclusively and no other process could connect to the database.

Connecting to sql database

(I am a sql noob and I just can not figure this out on my own)
For some time now I have been trying to establish a connection to a SQL database in codename one but to no avail. First I tried connecting to a MariaDB database from one.com. All that's needed for the connection is
Database db = Display.getInstance().openOrCreate("databaseName");
if I am not mistaken, but I am guessing this implies that I have somehow already established a connection to the database. This is not the case however so it creates a new .sql file, right? I can recall that you can connect to a database in the services tab in Netbeans. I chose the MySQL(Connector/ J Driver) which should work with MariaDB, or should it? I entered all my data and i says that it can not establish connection to the database.
the error i get
So I thought I might as well try using localhost. I used XAMPP to host a database and connected in the netbeans services tab.
connected?
Now testing was needed to see if this works. I started the SQL journey with this https://www.codenameone.com/manual/files-storage-networking.html#_sql and integrated the part after "You can probably integrate this code into your app as a debugging tool". I changed database name to "mybase" (it's existance can be confirmed in picture 2). Ran the app, opened the dialog, entered "select ID from customers" and got: java.sql.SQLException: [SQLITE_ERROR] SQL error or missing database (no such table: customers) It does not get past the first call to "executeQuery". The customers table definitely exists so what am I missing to establish connection?
I really need instructions to connect to the localhost database and ideally also to the one hosted by my webhost provider.
Thanks,
Jona
The Database class is to access the SQLite DB on the mobile device. To connect to external databases, you'd have to do something different, such as a ConnectionRequest or Socket I think.

Generate reports that query data from MS SQL database on Linux/CentOS?

I'm trying FastReport.Mono on Linux (CentOS 7) to see if I can make an app to generate reports. Example Mono app seems to work fine with PDF and JPG export from custom dataset.
Now I need to query data from MS SQL database. I have a sample report that works well under Windows, but fails on Linux:
private static void ReportExportJPG()
{
Report report = new Report();
report.Load(#"sql-report.frx");
report.Prepare(); // <<<--- Error here
...
}
Error message is:
Cant find object MsSqlDataConnection
Feature table says that MS SQL connectivity (nor ODBC, nor many others) is not available in FastReport.Mono. Does this mean it's entirely missing or I should use other ways and provide ready-made connection to FastReport somehow? If so - How?
P.S. Running Windows report generator with MS SQL connection under Wine works well, so I assume connecting to MS SQL from CentOS is somehow viable.
I was able to resolve this by adding the following to my project source:
using FastReport.Data;
using FastReport.Utils;
...
RegisteredObjects.AddConnection(typeof(MsSqlDataConnection));

file share error if Sql Compact 4 in windows application

I am sorry but I want a final answer about that.
First I used SQL compact 3.5 for long time and it take from me long time to make tables and it is work good per one user application but now I have customer who want to run my soft on 8 computer by local network so I said ok then I try to share data file .sdf on server and use it but I get an error I don't remember it so I am searched on the internet and I saw that I must update to SQL compact 4 so update it and after that I get this Stupid error
I can’t Believe that this data don't support this type of use and it take too long time to make tables and other things on SQL compact database and the my customer will not wait me so what is the Reason
My SQL statement is this:
dt = New SqlCeConnection("Data Source=" & dpaa & "\MoveData.sdf;Encrypt Database=True;Password=123cdswdaas;File Mode=Read Write;Persist Security Info=False")
I think that previous answer is slightly misleading - you are definitely able use SQL Server CE 4.0 with database file located on network share. In fact, I am using this functionality in one of my active projects right now. "File Mode=Exclusive" parameter is not necessary - exclusive mode is the only available mode in such case.
The major drawback of this approach is that only one client is able to read from or write to database file at a given time, due to exclusive locking of entire SDF file. But there a circumstances when it is not possible to have full-featured SQL server in your environment (domain policy etc.). In such case shared database file is the only solution available.
Accessing SQL Compact database .sdf file on a network share by multiple users is not supported. You should use SQL Server Express edition for this. There are also multiple posts on stackoverflow on this subject. The version 3.5 supports opening .sdf file exclusively from a network share but 4.0 does not. But no SQL CE version supports shared access of multiple network users to 1 .sdf file.
But upgrading your application to support both SQL Express and SQL Compact databases could be relatively easy task. It depends on how your application access data. For example using Entity Framework your queries could be generated depending on your actual database connection.
You can also use generic classes DbConnection, DbCommand etc. instead of SqlCeConnection, SqlCeCommand etc. - thus you can change used database type without having to maintain two separate versions of your project.
Download SQL Express 2014 with Tools SQLEXPRWT http://msdn.microsoft.com/cs-cz/evalcenter/dn434042.aspx. (You can eventually use also older versions e.g. 2008) SQL Server has a lot more SQL features and data types than SQL CE, so watch that you use only stuff that is compatible with SQL CE.
In your app.config have you can have two connection strings:
<add name="CompactDBConnection" connectionString="data source=|DataDirectory|\CE.sdf; password=xxxxxx; SSCE:Max Buffer Size=16384; temp file max size=256; ssce:autoshrink threshold=100; ssce:max database size=4091" providerName="System.Data.SqlServerCe.4.0" />
<add name="ExpressDBConnection" connectionString="Server=myServerName\myInstanceName;Database=myDataBase;User Id=myUsername; Password=myPassword;" providerName="System.Data.SqlClient" />
You can chose then which one to use at the app startup
For creating DbConnection check this C# Retrieving correct DbConnection object by connection string.
Here is a small example of calling stored procedure using DbCommand instead of SqlCeCommand:
DbConnection dbConn = GetConnection(connStr);
DbProviderFactory sqlF = DbProviderFactories.GetFactory(dbConn);
using (DbCommand b2bcmd = sqlF.CreateCommand())
{
DbParameter msg = sqlF.CreateParameter();
msg.ParameterName = "#errorMessage";
msg.Direction = ParameterDirection.Output;
msg.DbType = DbType.String;
msg.Value = string.Empty;
msg.Size = 2048;
b2bcmd.Connection = dbConn;
b2bcmd.CommandType = CommandType.StoredProcedure;
b2bcmd.CommandText = "PB2BImport";
b2bcmd.Parameters.Add(msg);
b2bcmd.ExecuteNonQuery();
result = Convert.IsDBNull(msg.Value) ? "N/A" : (string)msg.Value;
}
I presume you do not use Entity framework - but it would be much easier with it.

slow sql oledb connection

Can someone tell me why the code below performs very slow?
The last sentence takes more than 6 seconds.
I am trying to read data from a SQL server with C++.
std::string connectString("Provider=SQLOLEDB; Data Source=XXX;Initial Catalog=YYY;Integrated Security=SSPI;");
_ConnectionPtr Connection;
CoInitialize(NULL);
pConnection.CreateInstance(__uuidof(Connection));
HRESULT hr=Connection->Open(connectString.c_str(),"","",adConnectUnspecified);
Adding the portnumber did the trick!
std::string connectString("Provider=SQLOLEDB; Data Source=XXX,1430;Initial Catalog=YYY;Integrated Security=SSPI;");
Here are some points to check:
Between your datasource and your application lies a network connection, e.g. a SMB share. These tend to be slow.
Try to find out if some registry settings work against you, forcing too small net packets or other kinds of throttles. These things depend on the framework version.
A virus scanner wants to be your friend.
Here is an example how the firewall can disturb: Very slow connection to SQL Server 2005 only if using ADO.NET with SqlClient
As the firewall blocks the requests, the system chooses some pipe streaming after a timeout.
I hope one of those will help you :-)
For me the answer was to enable TCP/IP using Sql Server Configuration Manager (I'm not sure how it managed to connect before; only Shared Memory was enabled ¯\_ (ツ)_/¯ )

Resources