file share error if Sql Compact 4 in windows application - sql-server

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.

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.

ADODB Command Parameters Refresh doesn't retrieve parameters

I have an old web application, built with VBScript on an IIS6 Server with a SQL Server 2008 database. It is in the processed of being moved to a new server, on IIS8.
Every queries in the app work with stored procedures, with which we never had a problem. But on the new server, it doesn't seem to work. I found it it's because the Command.Parameters.Refresh doesn't return the parameters properly.
Consider this code:
Set cmd = Server.CreateObject("ADODB.Command")
cmd.ActiveConnection = conn
cmd.CommandType = 4
cmd.CommandText = v_strSpName
cmd.CommandTimeout = 0
cmd.Parameters.Refresh
For i = LBound(v_arrParameters) To UBound(v_arrParameters)
If m_bReplaceEmptyToNull Then
v_arrParameters(i)(1) = ReplaceEmpty(v_arrParameters(i)(1))
End If
cmd.Parameters(v_arrParameters(i)(0)).value = v_arrParameters(i)(1)
Next
Everything in v_arrParameters exists, but I tried iterating in Parameters.name after the refresh, the parameters are not returned (but they are on the production server).
Also worth noting, the SQL Profiler does receive the query and return the parameters:
exec [Database]..sp_procedure_params_rowset N'get_company',1,N'dbo',NULL
According to this page, it is a known issue, I just want to make sure it doesn't come from this problem, and find a solution or an alternative that doesn't imply a full rewriting of the application.
Also, no I can not update the SQL Server version, switch to VB.NET, there is always the issue that there is a client that won't pay for this problem.
So we managed to make it work this way:
Opening the Applications Pools section in IIS Manager.
Going in the Advanced Settings of the Default App Pool (its name here, maybe not for everyone, I don't know)
Setting Enable 32-bits apps to True
This is on a 64-bit Windows Server 2012 R2, with Microsoft SQL Server 2008 (SP4) - 10.0.6241.0 (X64) .

Qt: Low speed when transferring data from remote database

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.

Querying for SQL Servers in an Inno-setup project

I'm creating a setup using Inno-setup.
During the setup process, a SQL Server database has to be created. I want to give the user the ability to select an existing SQL Server instance (if one exists), where the database has to be created.
So, what I want to do in the setup, is to query the network (and the local machine) for SQL Server instances.Furthermore, when the user has selected an instance, I want to verify if there exists a database on that instance which has a specific name.
Anybody who knows how I can do this ? Or maybe someone could give me some pointers in the good direction?
Inno Setup supports the call of external DLL functions, so you should write a suitable helper DLL. Managed .net DLLs can only be used via a COM interface, otherwise you need an unmanaged DLL.
Valid calling conventions are: 'stdcall' (the default), 'cdecl', 'pascal' and 'register'.
Try the following native .Net library call:
using System.Data.Sql;
var instance = SqlDataSourceEnumerator.Instance;
DataTable dataTable = instance.GetDataSources();
The resultant datatable contains the following columns:
ServerName
Name of the server.
InstanceName
Name of the server instance. Blank if the server is running as the default instance.
IsClustered
Indicates whether the server is part of a cluster.
Version
Version of the server (8.00.x for SQL Server 2000, and 9.00.x for SQL Server 2005).

How to read SQL Server Report history programatically?

a SQL Reporting Services Question - for SQL Server 2008.
Given that SQL Server Reporting Services features a Scheduler which can be used to schedule the running of SQL Reports, does anyone know a way to programatically (via C#) read a report's history from the Report Server (and then perhaps retrieve the results of the report)?
So after some more digging, it looks like I need to generate a WSDL for the Report Server and then access information by using the ReportingService object - has anyone done this before (with 2008) and can provide some pointers?
Note: looks like (according to SQL 2008 books online) the WSDL address for SQL 2008 is:
http://server/reportserver/ReportService2005.asmx?wsdl
If I can get this working, I'll post an answer up with the basic steps to implementing it :) It's a little confusing as the documentation is a mixture of SQL 2000 and SQL 2005 references!
OK, so I've actually figured out how to accomplish this seemigly impossible task.
Before I begin, let me just say that if you are working with SQL Server Reporting Services 2008 (SSRS 08) and have (i.e. you have no choice) to use something like Basic auth, you'll only find a world of hurt with the WCF based Service Stubs & IIS. I'm going to blog about the configuration later.
The short answer is as follows:
Connect (e.g. new ReportingService2005() or ReportingService2005SoapClient())
Note: It's easier to use the old (pre-WCF) ASMX service, but not impossible to use the new CF version. The Authentication takes some configuring. There are also some slight syntactic changes between versions.
Find the report history you are looking for, e.g. ReportHistorySnapshot[] history = reportServer.ListReportHistory(#"/Reports/MyHandyReport");
Get the HistoryID from whichever snapshot you want (returned from the ListHistoryReport)
Now, use a ReportViewer to render the historic report, much like you would any other report, e.g.:
ReportViewer rv = new ReportViewer();
rv.ProcessingMode = ProcessingMode.Remote;
rv.ServerReport.ReportServerUrl = new Uri(#"http://localhost/reportserver");
rv.ServerReport.ReportPath = #"/Reports/MyHandyReport";
rv.ServerReport.HistoryId = historyId;
//...snip
byte[] bytes = rv.ServerReport.Render("Excel", null, out mimeType, out encoding, out extension, out streamids, out warnings);
Note: you can also use the second WCF Web Service (ReportExecution2005.asmx?wsdl) as well for Report Execution
Well it has soap and extensibility API, perhaps they can be used?

Resources