C# und SQLite



  • Ich habe ein kleines Büroprojekt mit einer Access-Datenbank. Access quasi aus "historischen Gründen", denn ich persönlich kann das überhaupt nicht leiden und möchte deshalb mittelfristig eine andere DB dahinter packen.

    Nun habe ich - hier 😉 - von SQLite gelesen, allerdings in Zusammenhang mit C++. Hat das schon mal jemand mit C# kombiniert? Ist es überhaupt möglich und wenn ja, gibt es was Essentielles zu beachten?



  • Ich merk schon - keiner redet mit mir. Muß man ja auch noch selbst nachdenken 😉

    Mittlerweile bin ich so weit gekommen:

    using System;
    using System.Runtime.InteropServices;
    
    namespace SQLite
    {
    unsafe public delegate int CallBack(void *NotUsed, int Count, char **ColVal, char **ColName);
    
    unsafe public class App
    {
    	[DllImport("sqlite.dll")]
    	static extern System.IntPtr sqlite_open(string str_DB,int flag,char **ch_ErrMsg);
    
    	[DllImport("sqlite.dll")]
    	static extern int sqlite_exec(System.IntPtr my_DB,string str_SQL, CallBack CallBackFnc,int flag,char **ch_ErrMsg);
    
    	[DllImport("sqlite.dll")]
    	static extern void sqlite_close(System.IntPtr my_DB);
    
    	static int Fnc_Callback(void *NotUsed, int Count, char **ColVal, char **ColName)
    	{
    		int i;
    		string str_Result = "";
    
    		for (i = 0; i < Count; i++)
    		{
    			str_Result += *ColName[i] + ":" + (char)9 + *ColVal[i];
    		}
    
    		Console.WriteLine(str_Result);
    
    		return 0;
    	}
    
    	static void Main()
    	{
    		System.IntPtr my_DB;
    		char *ch_ErrMsg;
    		int i_Result;
    
    		CallBack myCallBack = new CallBack(App.Fnc_Callback);
    
    		my_DB = sqlite_open("test.db",0,&ch_ErrMsg);
    
    		i_Result = sqlite_exec(my_DB,"select col1 from tab1", myCallBack, 0, &ch_ErrMsg);
    
    		sqlite_close(my_DB);
    	}
    }
    }
    

    Die Callback-Funktion wird so oft aufgerufen, wie das Statement Zeilen zurückgibt. So weit so gut.

    Da gibt es aber zwei klitzekleine Problemchen:

    1. Ich weiß nicht, wie man innerhalb der Callback-Funktion an die Werte rankommt. Also an **ColVal und **ColName.

    2. sqlite_exec bricht mit einer "System.NullReferenceException" ab. Was könnte das sein?

    Vielleicht hat ja doch jemand Muße, sich den obigen Quellcode als Projekt zu erstellen und kann mir dann einen Tipp geben. Die sqlite-DB hat eine Tabelle tab1 mit einer Spalte col1 und drei Zeilen (varchar2).

    So, gute Nacht erst mal.



  • Ich habe deine Dll leider nicht, sonst würde ich einfach mal ausprobieren. Aber ich frage mich wieso du dies alles Unsafe machst, eigentlich benötigst du dies nicht. Statt char** kannst auch den StringBuilder benutzen, evtl ref benutzen.

    zu 2. breakpoint bei sqlite_exec setzen und nachschauen ob alle Parameter richtig gesetzt sind, z.B.: my_DB.



  • Hm, das ist nicht "meine" DLL, sondern die von SQLite. Die Doku bezieht sich nur auf C. Und wie man SQLite mit C# benutzt, versuche ich ja grad rauszufinden.
    Hab z.B. noch keine Ahnung, wie man einen **-Parameter von C# aus übergibt und ob das auch anders als mit unsafe geht. Mit ref und string habe ich auch schon rumprobiert, das war nicht besser.

    my_db scheint korrekt geöffnet zu werden, die Callback-Funktion wird ja auch dreimal ausgeführt - so oft, wie Zeilen von dem Statement zurückgegeben werden.



  • Bei Mono gibt es einen OleDB-provider für SQL Lite (weiß aber nicht ob der portierbar ist), und du kannst über den ODBC-Treiber für SQL Lite den OleDB-Provider für ODBC ankoppeln. Damit könntest du die ganze schönen ADO.NET-Funktionalität nutzen. Die ganzen treiber sind aber wahrscheinlich gegen die Idee von SQL Lite. 🤡

    Oder du nimmst MSDE



  • peterchen schrieb:

    Damit könntest du die ganze schönen ADO.NET-Funktionalität nutzen...Oder du nimmst MSDE

    Och, Peterchen, ich will doch grade WEG von MS, zumindest in meinen privaten Projekten 😉 Und wenn ich auf das ganze ADO/Ole/ODBC verzichten kann, wäre ich sehr erfreut. Eine KLEINE Datenbank genügt.

    Leider breche ich immer noch mit der System.NullReferenceException ab - und zwar NACHDEM das SQL-Statement korrekt ausgeführt wurde... Ich habe keinen blaßen Schimmer, was dort fälschlicherweise null sein könnte. my_DB ist ordentlich offen, sonst könnte ich wohl kaum was auslesen, i_Result ist jetzt mit 0 initialisiert, ch_ErrMsg durch einen StringBuilder ersetzt - ich kann einfach nix finden... Und ich komme auch nicht an die Stelle beim Debuggen, bis zur letzten Zeile der Callback-Funktion ist alles Ok und dann - wupps, weg.

    😞 😡 😞 😡 😞


Anmelden zum Antworten