Failed to attach Sqlite database with special charactesrs in the path - c#

I use SQLite for Windows Runtime (Windows 8.1) and SQLite.Net-PCL extension.
I work with databases in user local folder. Path to this folder contains username. So, sometimes it may contain special characters (e.g. 'ลก').
It works correctly when I create connection and open a database. However, the problem occurred when trying to attach another database. I always got exception "CannotOpen".
I suppose the problem is based on different encoding (UTF-8 in SQLite, UTF-16 in .Net) but I haven't managed to resolve it.
Sqlite contains methods for opening database in UTF 16 (sqlite3_open16). But there is no such a method for SQL statements.
string dbPath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "sqlite1.db");
string dbPath2 = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "sqlite2.db");
using (SQLite.Net.SQLiteConnection conn = new SQLite.Net.SQLiteConnection(new SQLitePlatformWinRT(), dbPath))
{
var cmd = conn.CreateCommand("ATTACH '" + dbPath2 + "' AS second;");
cmd.ExecuteNonQuery(); // -> it throws "CannotOpen" exception if dbPath2 contains special characters
}
Thanks for your help!

Related

Cannot add sqlite db file to Word adding deployment

I developed C# Word add-in which populates some data from database file. It is working fine while I am running through Visual studio running. But if I publish it cannot connect to database.
Here is how I get data from database:
SQLiteConnection con = new SQLiteConnection(ThisAddIn.connectionString);
con.Open();
var command = con.CreateCommand();
command.CommandText =
#"
SELECT *
FROM JK
WHERE article_number = $article_number
";
command.Parameters.AddWithValue("$article_number", textFromDoc);
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
var title = reader.GetString(2);
var article = reader.GetString(3);
ResultForm resultForm = new ResultForm();
resultForm.setArticle(title, article);
resultForm.ShowDialog();
}
}
public static string connectionString = #"Data Source=E:\projects\c#\TBPWordAddin\WordAddIn1\codexes.db";
Am I doing something wrong or do I need to include file in another way? Any help will be appreciated.
Also I tried publishing using Visual studio installer and it connected to database but the add in didnot lounched on other computers.
The connection string contains an absolute path which can be changed after publishing an application. I'd suggest using a relative path instead - in that case you will be able to find the Db easily. You may check out the following threads for more information on such kind of issues:
Connection string with relative path to the database file
How to give relative path of connection string or data source in windows form application
But if I publish it cannot connect to database.
Make sure the Db path (see the connection string) corresponds to the hardcoded value in the application used.

Unable to load database from local server location in C# Connection String (windows application)

I'm trying to do application to access the database from local file server, but the connection string does not recognize the server location. This is a windows form application, using sqlite. Kindly help me on this one.
File server location will be like this:
\\fileserver\Testdb\maindb.db
Code used:
string server_database_path = #"\\fileserver\Testdb\maindb.db";
string connection_data = "Data Source=" + server_database_path ;
using (var conn = new SQLiteConnection(connection_data))
{
conn.Open();
SQLiteCommand insert_Rec = new SQLiteCommand(query_text, conn);
insert_Rec.ExecuteNonQuery();
conn.Close();
}
Error:
Unable to open database file
I may be wrong but I dont think that directly specifying the .db is correct. When using a normal SQL Server I would specify the instance (or just the server hosting it if it was the default instance).
So, your connection string should look something like
string connectionString = "Data Source=192.168.0.1; User ID=administrator; Password=YOURPASSWORD"
or if you are connecting the machine you are on it should be
string connectionString = "Data Source=127.0.0.1; User ID=administrator; Password=YOURPASSWORD"
You could substitute the 127.0.0.1 for \\localhost
I was confused in doing this, but by changing the slash "\" to "/" it really worked.
When i changed the slash in the path string it started to work fine and everything goes well.
Example: #"//fileserver/Testdb/maindb.db"

Backup localDB database in ClickOnce

I've created a WPF 4.5 .NET application it with a database backup feature. The functions and the backup works fine when debugging but when I publish it in ClickOnce and install it in target machine everything works except the backup won't work because ClickOnce obfuscate the app folder location so it becomes too long for the backup statement to work! Is there a way to make the backup statement shorter? here's my code and the error I get:
code:
SaveFileDialog sfd = new SaveFileDialog();
string stringCon = #"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\whdb.mdf;Integrated Security=True";
string dbPath = Application.StartupPath + #"\whdb.mdf";
if (sfd.ShowDialog() == DialogResult.OK)
{
using (SqlConnection conn = new SqlConnection(stringCon))
{
string backupStmt = string.Format(#"backup database #whdb to disk='{0}' WITH INIT ", sfd.FileName);
using (SqlCommand sqlComm = new SqlCommand(backupStmt, conn))
{
sqlComm.Parameters.AddWithValue("#whdb", dbPath);
conn.Open();
sqlComm.ExecuteNonQuery();
conn.Close();
}
}
)
************** Exception Text **************
System.Data.SqlClient.SqlException (0x80131904): Invalid database name 'C:\Users\Abubaker\AppData\Local\Apps\2.0\52WR4JTO.12O\D6M4D7OQ.Z3D\sa3a..tion_fef19ab42c2b8f22_0001.0000_9fc10c82bbf23ed2\whdb.mdf' specified for backup or restore operation.
BACKUP DATABASE is terminating abnormally.
The whdb.mdf database file is create by another existing application? And your WPF application is only for Backup the existing whdb.mdf database?
I also struggled for days for this kind of situation. I tried |Data Directory| and Application.StartupPath and some other approaches as you've found as well.
However, I finally chose this way and successfully launched(published) my service.
According to my experience, |Data Directory| indicates different places depending on circumstances, in other word, it's not always same..
And I could read (SQL Select command) database with |Data Directory| setting in connectionString but couldn't insert or update the database. You can find some people are having this difficulties by searching on interent. I think when we set |Data Directory| in connectionString, the database plays a role as read-only data file like the nuance of |Data Directory|.
Instead the |Data Directory|, I chose more obvious path which indicates always same place(directory).
#"Data Source=(LocalDB)\v11.0;AttachDbFilename=" + Environment.GetEnvironmentVariable("APPDATA") + #"\whdb.mdf;Integrated Security=True";
Above Environmental variable indicates always C:\Users\Abubaker\AppData\Roaming directory.
For this scenario, you're needed to create the whdb.mdf database file with above path first.
And further, you may create your own additional directory like mybackup with the connectionString as,
#"Data Source=(LocalDB)\v11.0;AttachDbFilename=" + Environment.GetEnvironmentVariable("APPDATA") + #"\mybackup" + #"\whdb.mdf;Integrated Security=True";
I couldn't find the official document from Microsoft how the |Data Directory| works but failed. Understanding |Data Directory| would be your key, otherwise, there's alternative way like my case.
My case is also WPF, ClickOnce, SQL Database (it was localDB but I changed to normal SQL Database because of remote networking)
Solved the problem by adding Initial catalog=whdb in the connection string and then replace the full path Application.StartupPath + #"\whdb.mdf" with just the database name "whdb"!

Create new SQLite database on WinRT?

I want to create a new database from C# code in my WinRT app. I searched the Web and the way to do that appears to be the SQLiteConnection.CreateFile() method. However, that method does not exist in the SQLite namespace, at least in the WinRT version. I installed SQLite using the NuGet packge name "sqlite-net" and included the sqlite3.dll into my project. I do see properly methods like CreateTable(), Query(), etc. but not CreateFile(). Where is it? Or does the WinRT package use a different method for creating database files from code?
var db = new SQLiteConnection(databasePath, SQLiteOpenFlags.Create | SQLiteOpenFlags.ReadWrite);
is how I did it.
One of the times where Microsoft provides a straightforward example:
https://learn.microsoft.com/en-us/windows/uwp/data-access/sqlite-databases
await ApplicationData.Current.LocalFolder.CreateFileAsync("sqliteSample.db", CreationCollisionOption.OpenIfExists);
string dbpath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "sqliteSample.db");
using (SqliteConnection db =
new SqliteConnection($"Filename={dbpath}"))
{
db.Open();
String tableCommand = "CREATE TABLE IF NOT " +
"EXISTS MyTable (Primary_Key INTEGER PRIMARY KEY, " +
"Text_Entry NVARCHAR(2048) NULL)";
SqliteCommand createTable = new SqliteCommand(tableCommand, db);
createTable.ExecuteReader();
Because depending on how you add sqlite to a UWP project, not having createfile() available is still an issue in 2021.

Why do I get "Database already exists" when I'm using "AttachDbFileName" when I move the solution to another directory?

I have an application JigSaw that uses a database TopScores.mdf which it is not included in the project. What I want to do is make the application find the database in application's folder. So for example if I move the .exe file and the database file from debug folder to desktop the application should use the database from desktop and not search for it in debug folder.
If I let them in debug folder there is no problem and the connection to database is established, but when I put them on desktop I get this :
Unhandled exception has occurred in your application. If you click Continue, the application will ignore this error and attempt to continue. Database 'D:\Programing\Projects Visual Studio 2010\JigSaw\JigSaw\bin\Debug\TopScores.mdf' already exists. Choose a different database name. Cannot attach the file 'C:\Users\Addy\Desktop\Jigsaw\TopScores.mdf' as database TopScores.mdf
My connection string is :
string appPath = Path.GetDirectoryName(Application.ExecutablePath);
string connString = #"server =.\sqlexpress; Database=TopScores.mdf; trusted_connection=TRUE; AttachDbFileName= "+#appPath+#"\TopScores.mdf";
conn = new SqlConnection(connString);
Sorry for my bad english :(
This is happening because you don't leverage the User Instance=true; when you connect to it. You literally told SQL Server to attach the database to the running SQL instance from the directory you first loaded it from.
Detach the database by hand from the running SQL instance, change your connection string to use User Instance=true;, run it from the Debug folder, and then run it from the Desktop, and you'll see success.
change setting in your connection string from "Database=TopScores.mdf" to something different, say: "Database=TopScores_brand_new_connection" do not create/delete/rename files in any file/database server. do it in the connection string only. Do not add dots, extensions etc.
just rename ur .mdf file ... eg. from MNGMT.mdf to M_1(something you want). change your contact string...hope so it will help u.. in my case it is executing correctly on other pc as well as in my pc.. just copy your .mdf file into you project ..
string dbPath = Path.GetDirectoryName(Application.ExecutablePath) + "\\M_1.mdf";
string myServer = Environment.MachineName;
DataTable servers = SqlDataSourceEnumerator.Instance.GetDataSources();
for (int i = 0; i < servers.Rows.Count; i++)
{
if (myServer == servers.Rows[i]["ServerName"].ToString()) ///// used to get the servers in the local machine////
{
if ((servers.Rows[i]["InstanceName"] as string) != null)
servername = (servers.Rows[i]["ServerName"] + "\\" + servers.Rows[i]["InstanceName"]);
else
servername = ""+servers.Rows[i]["ServerName"];
}
}
connetionString = "Data Source=" + servername + ";AttachDbFilename=" + dbPath + ";Integrated Security=True;Pooling=False;User Instance=True";

Categories

Resources