简体   繁体   English

如何从Sqlite请求中获取一个字段值?

[英]How to get one field value from Sqlite request?

I use this function to make query: 我使用此函数进行查询:

public SQLiteDataReader returnDataReader(string txtQuery)
        {
            SQLiteCommand cmd = new SQLiteCommand();
            try
            {
                cmd.Connection = Openconn();
                cmd.CommandText = txtQuery;
                SQLiteDataReader rd;
                rd = cmd.ExecuteReader();
                return rd;
            }
            catch (Exception Ex)
            {
                throw Ex;
            }
            finally
            {
                cmd = null;
            }
        }

And this is my query: 这是我的查询:

 SQLiteDataReader data = db.returnDataReader("SELECT created_at FROM Transactions ORDER BY created_at DESC LIMIT 1");

I tried to get value of created_at field from query like as: 我试图从查询中获取created_at字段的值,如下所示:

string res = data["created_at"].ToString();

It returns me error. 它返回我错误。 Also I have checked this query directly in Sqlite manager. 我也直接在Sqlite管理器中检查了此查询。 It works and return one row. 它可以工作并返回一行。

Error is: 错误是:

System.InvalidOperationException occurred HResult=0x80131509 发生System.InvalidOperationException HResult = 0x80131509
Message=No current row Source=System.Data.SQLite StackTrace: at System.Data.SQLite.SQLiteDataReader.CheckValidRow() at System.Data.SQLite.SQLiteDataReader.GetValue(Int32 i) at System.Data.SQLite.SQLiteDataReader.get_Item(String name) at Ukraine.StatisticService.lastsync() in D:\\Projects\\c-tests-ukraine\\Ukraine\\Library\\StatisticService.cs:line 25 at Ukraine.Main.Form1_Load(Object sender, EventArgs e) in D:\\Projects\\c-tests-ukraine\\Ukraine\\Main.cs:line 81 at System.Windows.Forms.Form.OnLoad(EventArgs e) at System.Windows.Forms.Form.OnCreateControl() at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible) 消息=当前没有行Source = System.Data.SQLite StackTrace:位于System.Data.SQLite.SQLite.SQLiteDataReader.GetValue(Int32 i)处是System.Data.SQLite.SQLiteDataReader.CheckValidRow() (字符串名称)位于D:\\ Projects \\ c-tests-ukraine \\ Ukraine \\ Library \\ StatisticService.cs:第25行位于Ukraine.StatisticService.lastsync(),位于D:\\ Ukraine.Main.Form1_Load(Object sender,EventArgs e): \\ Projects \\ c-tests-ukraine \\ Ukraine \\ Main.cs:line 81位于System.Windows.Forms.Form.OnLoad(EventArgs e)位于System.Windows.Forms.Form.OnCreateControl(),位于System.Windows.Forms。 Control.CreateControl(布尔值fIgnoreVisible)
at System.Windows.Forms.Control.CreateControl() at System.Windows.Forms.Control.WmShowWindow(Message& m) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.ScrollableControl.WndProc(Message& m) at System.Windows.Forms.Form.WmShowWindow(Message& m) at System.Windows.Forms.Form.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 在System.Windows.Forms.Control.WmShowWindow(Message&m)在System.Windows.Forms.Control.WndProc(System.Windows.Forms.ScrollableControl.WndProc) System的System.Windows.Forms.Form.WmShowWindow(Message&m)(Message&m)的System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&m)的System.Windows.Forms.Form.WndProc(Message&m)的系统System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam)上的.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&m)

Just calling ExecuteReader is not enough. 仅调用ExecuteReader是不够的。 Initially any kind of DataReader is positioned before any row retrieved. 最初,任何类型的DataReader都位于检索到的任何行之前。 You need to call Read on the reader to position it on the first row returned 您需要在阅读器上调用“阅读”以将其放置在返回的第一行上

SQLiteDataReader data = db.returnDataReader(.....);
if(data.Read())
{
    string res = data["created_at"].ToString();
    ....
}

or add a loop 或添加一个循环

SQLiteDataReader data = db.returnDataReader(.....);
while(data.Read())
{
     ..get data from your rows here
}

However I don't consider your approach to return a SqlLiteDataReader a good practice. 但是,我不认为您返回SqlLiteDataReader的方法是一种好习惯。 The reader depends on the connection being open and the connections are objects that you should really close as fast as possible to avoid dangerous resources leaks. 读取器取决于打开的连接,并且这些连接是您应该尽快关闭的对象,以避免危险的资源泄漏。

I suggest to use another approach to read you data 我建议使用另一种方法来读取您的数据

public void ReadData(string txtQuery, Action<SQLiteDataReader> loader)
{
    using(SQLiteConnection con = Openconn())
    using(SQLiteCommand cmd = new SQLiteCommand(txtQuery, con))
    using(SQLiteDataReader rd = cmd.ExecuteReader())
    {
        while(rd.Read())
            loader(rd);
    }
}

Then you call this method passing the delegate to the method that reads your data 然后调用此方法,将委托传递给读取数据的方法

ReadData(...querytext..., readCreatedData);

and then write the method readCreatedData that will be called by the code where you open the connection and the other disposable objects. 然后编写方法readCreatedData ,该方法将在您打开连接和其他一次性对象的代码中调用。

void readCreatedData(SQLiteDataReader data)
{
     string res = data["created_at"].ToString();
     .....
}

Finally as Rufo pointed in its comment you are really just reading a single value from a single column and this is better done using a simple ExecuteScalar 最后,正如Rufo在其注释中指出的那样,您实际上只是从单个列中读取单个值,最好使用简单的ExecuteScalar来完成此操作

public string ReadString(string txtQuery)
{
    using(SQLiteConnection con = Openconn())
    using(SQLiteCommand cmd = new SQLiteCommand(txtQuery, con))
    {
        object result = cmd.ExecuteScalar();
        return (result == null ? "" : result.ToString());
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM