SQLite3 AttachDatabase command won't work - c#

I'm attempting to connect two SQLite databases in a Unity3d project and I am running into some trouble.
My database paths and file names are correct (checked and confirmed), and I am able to query/insert/etc... from each of the databases individually. However, when I run the ATTACH command, it returns an error stating that my SQL logic is invalid. I have looked at many references and examples, all of which indicate that my command should run as anticipated.
Here is some relevant code:
//open TEMP database
DBAccess.OpenOrCreateDB("/Resources/Data/SaveGames/" + GameController.user.username +
"/", GameController.user.username + "_TEMP");
//attach SAVEGAME database and transfer data from TEMP database
DBAccess.NonQuery("ATTACH DATABASE '" + Application.dataPath + "/Resources/GameData/"
+ GameController.user.username + "/" + GameController.user.username + DBAccess.DBEXT
+ "' AS LOAD_DB;");
//copy records from TEMP database to save game database
//(omitted because not relevant to issue)
//detach SAVEGAME database
DBAccess.NonQuery("PRAGMA LOAD_DB.journal_mode=delete; DETACH DATABASE LOAD_DB;");
//close database
DBAccess.CloseDB();
The goal with this is to copy the in-game changes database to the player's save game database file.
My error debugging prints out the following:
DBAccess -- Cannot perform command with statement: <ATTACH '/Users/scottwindsor/ADITL/
Assets/Resources/GameData/New User/New User.db' AS LOAD_DB;>
It would seem that my SQL command should work... Any help would be appreciated.
Tech Specs:
Platform: OSX (Lepoard, I think)
Compiler: Unity3D (game engine)
Language: C#
SQL: SQLite3.dll
Using IDBCommand.ExecuteNonQuery() to send non-query commands to the database.
Using IDBCommand.ExecuteReader() to send all other commands/queries to the database.

Related

How to edit/delete access database record in c#

So i have a problem updating record in my database. My code runs without error, but the record is not updated. Here is the code:
private void button3_Click(object sender, EventArgs e)
{
try
{
if (con.State == ConnectionState.Closed)
{
con.Open();
}
string sql = string.Format("update Alternatif set No ='" + textBox1.Text + "',Kecamatan='" + textBox2.Text + "',Kelurahan='" + textBox3.Text + "',Nama='" + textBox4.Text + "'where No ='" + textBox1.Text + "'");
OleDbCommand perintah = new OleDbCommand(sql, con);
perintah.ExecuteNonQuery();
MessageBox.Show("Data edited successfully");
perintah.Dispose();
con.Close();
}
catch (Exception)
{
MessageBox.Show("Data failed to edit");
}
}
I'm assuming you have proven that the query works to update the record in access - you should consider capturing the int that is returned from ExecuteNonQuery and if it is 0, no records were updated
You should also consider having a good read of http://bobby-tables.com and promise yourself never to write an SQL again like you have there. It is prone to sql injection attack and is a massive security issue
Access is a file based database and typically when added to a visual studio there is a dev version of the file (the file as it was when selected for addition to the project) that is copied to the build directory every time a build is run. The app typically updates the build copy in the bin directory, not the dev copy outside the bin directory.
Developers then go looking in the dev copy and are surprised that no change was made- they're looking in the wrong file.
Or they go looking in the build copy, but after another build has been run and the edited db has been overwritten with a fresh, empty copy of the dev db. Search your project folder for all db and ensure you're inspecting the right one
You can stop the build process replacing the bin folder version of the file every time by finding the db in the solution explorer, getting properties on it and setting the Copy To Output Directory to something other than Copy Always. I personally use Copy If Newer

Change schema, execute query and write output to file

I want to connect to a database with sys user. Change the schema to a differnt user. Execute a query and write the result into a file.
I am using oralce managed data access .https://www.nuget.org/packages/Oracle.ManagedDataAccess/
I have tried three different ways already.
1.) spool-> does not work since I am not executing sqlplus but connect with managedDataAccess
2.) begin execute immediate'changeschema' execute immediate 'query' end -> no output on the reader because of begin/end
3.) try to change the connection conn.ChangeDatabase(user); does not work with managedDataAccess
This is my connection string:
string oradb = "Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=" + host + ")(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=" + instance + ")));User Id = " + oracleUser + "; Password =" + oraclePassword;
Can I change the schema within the connection string
If you connect as SYS you don't need to change the schema, you can just reference the schema in your from clause, e.g.
select *
from my_user.my_tab
;

Failed to attach Sqlite database with special charactesrs in the path

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!

MS SQL Server 2008 restoring DBs with SMO corrupts resourceDB

I am currently facing a very strange issue with one of my database instances.
I wrote a small application to backup a set of databases from one MS SQL Server 2008 instance and restore the same set on top of existing DBs on a second instance. Both instances are running on top of Windows Server 2008R2 machines. Backups and restores are done using MS SQL Server Management Objects (SMOs), built into a simple C# Windows Form.
After I restore the DBs on the second instance, I encounter a few issues:
Right-clicking on a database and select Properties gives me the following error message
|-> Cannot show requested dialog (SqlMgmt)
|-> An exception occurred while executing a Transact-SQL statement or batch
|-> Could not continue scan with NOLOCK due to data movement. (Microsoft SQL Server, Error: 601)
I cannot open Activity Monitor (same error message)
SQL Error log reports the Resource DB is corrupted ("SQL Server detected a logical consistency-based i/O error: invalid protection option. It occurred during a read of page ... in database ID ... at offset ... in file ...")
the SELECT SERVERPROPERTY('ResourceVersion') command gives out a version number
copying the mdf and ldf files for the resource DB from another SQL Server (and restarting the services) solved the issues
Now I know the resource DB is supposed to be read-only and outside of HW issues there's no way it can get corrupted, which really has me wondering, where did I mess up? And why does replacing the resource DB fix my issue?
Has anyone ever encountered the same issue?
Update:
Backups are performed with the following commands:
Backup backup = new Backup();
backup.Action = BackupActionType.Database;
backup.Database = databaseName;
backup.CopyOnly = true;
backup.Checksum = true;
backup.BackupSetDescription = "Full backup of " + databaseName;
backup.BackupSetName = databaseName + " Backup";
backup.Initialize = true;
string backupFilePath = backupLocation + "\\" + databaseName + ".bak";
backup.Devices.AddDevice(backupFilePath, DeviceType.File);
Microsoft.SqlServer.Management.Smo.Server smoServer = new Server(connectionString);
smoServer.ConnectionContext.StatementTimeout = 0;
smoServer.ConnectionContext.AutoDisconnectMode = AutoDisconnectMode.NoAutoDisconnect;
smoServer.ConnectionContext.Connect();
backup.SqlBackup(smoServer);
smoServer.ConnectionContext.Disconnect();
..and verified as follows:
Restore restore = new Restore();
string backupFilePath = backupLocation + "\\" + databaseName + ".bak";
Microsoft.SqlServer.Management.Smo.Server smoServer = new Server(connectionString);
BackupDeviceItem deviceItem = new BackupDeviceItem(backupFilePath, DeviceType.File);
restore.Devices.Add(deviceItem);
bool verified = restore.SqlVerify(smoServer);
Restores are performed with:
Microsoft.SqlServer.Management.Smo.Server smoServer = new Server(connectionString);
smoServer.ConnectionContext.StatementTimeout = 0;
smoServer.ConnectionContext.AutoDisconnectMode = AutoDisconnectMode.NoAutoDisconnect;
smoServer.ConnectionContext.Connect();
Database db = smoServer.Databases[databaseName];
Restore restore = new Restore();
string backupFilePath = backupLocation + "\\" + databaseName + ".bak";
BackupDeviceItem deviceItem = new BackupDeviceItem(backupFilePath, DeviceType.File);
restore.Devices.Add(deviceItem);
restore.Database = databaseName;
restore.Action = RestoreActionType.Database;
restore.ReplaceDatabase = true;
restore.SqlRestore(smoServer);
db = smoServer.Databases[databaseName];
db.SetOnline();
smoServer.Refresh();
db.Refresh();
Restore rest = new Restore();
rest.Devices.AddDevice(backupFilePath, DeviceType.File);
bool verifySuccessful = rest.SqlVerify(smoServer);
smoServer.ConnectionContext.Disconnect();
I know the connection should actually disconnect itself once the backup or restore is complete, and that does actually connect and disconnect correctly, this latest version with manual connect and disconnect was an experiment to check if there was any difference in the end result. There wasn't.
Both backups and restores are executed in a background worker, inside try...catch loops, and no exceptions are raised.
I believe the params are self-explanatory, but if something is unclear I'd be happy to clarify.
Update 2:
After a more thorough round of testing, I was unable to reproduce the resource DB corruption issue. Ergo I am blaming this on planetary alignment when I first tried out the restores.
Thanks Jeroen for the help and the hints!
There's no reason to assume your backup/restore had anything to do with the database failing. Do the usual dance when you encounter corruption: run DBCC CHECKDB, check your hardware for errors, see if there are cumulative updates applying to your version that might resolve corruption issues. If you can consistently reproduce the error by restoring your databases, even on another machine with the exact same version of SQL Server, you may have found a bug MS is interested in. Otherwise, I'd take a long, hard look at the hardware.
The fact that replacing the resource database fixed it does not in any way imply you've found and fixed the underlying problem, just that it's not corrupted anymore. This still tells you nothing about the cause of the corruption.
And just for completeness: nothing you do short of manually editing database files (through DBCC PAGE or just by writing to it outside SQL Server) is a legitimate reason for database corruption, so you definitely didn't "mess up".

C# system.io.filenotfoundexception

I am creating an app for my work to track behavior management over the course of a school year. To do this, I obviously needed a database. I built the program so that it would, when opened, check to see if the database exists, and if it doesn't, it creates one, and inputs the schema. This works perfectly on my dev computer, but when I switch it to a computer using windows XP it gives an error saying system.io.filenotfoundexception. I can't figure out why it won't create the database.
I am using Visual C# 2010 Express. And the database is made in sql server ce.
if (!File.Exists("chart.sdf"))//Checks if file is already in existance when app is opened
{
dbCreated = createDb();//If there is no database, creates one
}
public bool createDb()//Creates the database if needed
{
bool success = true;
//Holds sql schema for the table
string[] tableCreateArr ={"create table childNameId"
+ "(childId INT IDENTITY PRIMARY KEY, "
+ "childFName nchar(40), "
+ "childLName nchar(40));",
"create table leaderNameId"
+ "(leaderId INT IDENTITY PRIMARY KEY, "
+ "leaderFName nchar(40), "
+ "leaderLName nchar(40));",
"create table TagPulledId"
+ "(tagId INT IDENTITY PRIMARY KEY, "
+ "childId INT, "
+ "leaderId INT, "
+ "day TINYINT, "
+ "month TINYINT, "
+ "year INT);",
"CREATE TABLE tagInfo"
+ "(tagId INT, "
+ "color nchar(10), "
+ "description ntext)"};
SqlCeEngine dbCreate = new SqlCeEngine(connectString()); // creates the database obj
dbCreate.CreateDatabase(); // creates the database file
SqlCeConnection tempConnect = new SqlCeConnection(connectString());//Connects to the new database
SqlCeCommand objCmd = new SqlCeCommand();//Creates an sql command obj
tempConnect.Open(); // opens the connection
objCmd.Connection = tempConnect; //Connects the command obj
foreach (string strCmd in tableCreateArr)//Iterates throught he sql schema to create the tables
{
try
{
objCmd.CommandText = strCmd; //sets the CommandText to the next schema entry in the array
objCmd.ExecuteNonQuery(); //Executes the create query
}
catch (SqlCeException sqlError)
{
MessageBox.Show(sqlError.Message, "SQL Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
success = false;
}
}
tempConnect.Close();
return success;
}
I can't figure out why the app isn't making the database, it seems to work on some computers, while not working on others. Any help would be great! Thank you.
if (!File.Exists("chart.sdf"))
You seem to want to create the database in the same directory as your program. Yes, that will work on your dev machine but that's not going to work on a regular machine. The typical install directory (c:\program files\etc) does not permit write access to files.
You will need to use Environment.GetFolderPath() to get an ApplicationData directory that you can write to.
It is often a lot easier and less error prone to let an installer create the appdata directory and copy the initial .sdf file in there. Albeit that Setup projects are not supported by the Express edition. There does come a point where hacking code to work around the Express edition's restrictions is defeating the price of the product license. You're pretty close here.
Make sure you have deployed all the dll Sql Server Compacts need. I'm not sure you get them when you install .NET framework. The dll needed are :
sqlceca35.dll
sqlcecompact35.dll
sqlceer35EN.dll
sqlceme35.dll
sqlceoledb35.dll
sqlceqp35.dll
sqlcese35.dll
You can find more details on this MSDN page about Sql Compact Deployment for various versions of the database engine.

Categories

Resources