SQLite查询在Java中无法运行

huangapple go评论75阅读模式
英文:

SQLite Query Not Running in Java

问题

我使用了DB Browser for SQLite创建了一个数据库。现在我正在尝试运行查询以从数据库中检索数据,但遇到了问题。当我在DB Browser中运行查询时,查询顺利运行。但当我尝试在Java中运行相同的查询时,我收到一个错误消息。我三次检查了查询字符串。我确认没有错误使用SQLite关键字。为什么我在Java中运行这个查询时会出错?

SELECT
	subject.id, main.name, main.link, subject.name, main_subject.weight
FROM 
	main_subject
LEFT JOIN 
	main ON main_subject.mainId = main.id
LEFT JOIN 
	subject ON main_subject.subjectId = subject.id

查询在DB Browser中运行正确。

MCVE:

Main

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Main
{
    public static void main(String[] args)
    {
        try (DatabaseHandler databaseHandler = new DatabaseHandler()) {
            List<BySubjectItemTwo> bySubjectItemTwos = databaseHandler.getBySubjectItems();
            bySubjectItemTwos.forEach(System.out::println);
        }
        catch (Exception ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

DatabaseHandler

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

public class DatabaseHandler implements AutoCloseable
{
    String dbString = "jdbc:sqlite:qDatabase.sqlite3";
    private Connection conn;

    public DatabaseHandler()
    {
        try {
            conn = DriverManager.getConnection(dbString);
            System.out.println("Connected to qDatabase!");
        }
        catch (SQLException ex) {
            Logger.getLogger(DatabaseHandler.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void close() throws Exception
    {
        conn.close();
    }

    public List<BySubjectItemTwo> getBySubjectItems()
    {
        List<BySubjectItemTwo> returnList = new ArrayList();

        String sqlString = "SELECT subject.id, main.name, main.link, subject.name, main_subject.weight FROM main_subject LEFT JOIN main ON main_subject.mainId = main.id LEFT JOIN subject ON main_subject.subjectId = subject.id";
        try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sqlString)) {
            while (rs.next()) {
                System.out.println(rs.getInt("subject.id") + " - " + rs.getString("main.name") + " - " + rs.getString("main.link") + " - " + rs.getString("subject.name") + " - " + rs.getInt("main_subject.weight"));
            }
        }
        catch (SQLException e) {
            System.out.println(e.getMessage());
        }

        return returnList;
    }  
}

BySubjectItemTwo

public class BySubjectItemTwo
{
    private int subjectId;
    private String mainName;
    private String mainLink;
    private String subjectName;
    private int mainSubjectWeight;

    public BySubjectItemTwo(int subjectId, String mainName, String mainLink, String subjectName, int mainSubjectWeight)
    {
        this.subjectId = subjectId;
        this.mainName = mainName;
        this.mainLink = mainLink;
        this.subjectName = subjectName;
        this.mainSubjectWeight = mainSubjectWeight;
    }

    public int getSubjectWeight()
    {
        return mainSubjectWeight;
    }

    public void setSubjectWeight(int mainSubjectWeight)
    {
        this.mainSubjectWeight = mainSubjectWeight;
    }

    public int getSubjectId()
    {
        return subjectId;
    }

    public void setSubjectId(int subjectId)
    {
        this.subjectId = subjectId;
    }

    public String getMainName()
    {
        return mainName;
    }

    public void setMainName(String mainName)
    {
        this.mainName = mainName;
    }

    public String getMainLink()
    {
        return mainLink;
    }

    public void setMainLink(String mainLink)
    {
        this.mainLink = mainLink;
    }

    public String getSubjectName()
    {
        return subjectName;
    }

    public void setSubjectName(String subjectName)
    {
        this.subjectName = subjectName;
    }

    @Override
    public String toString()
    {
        StringBuilder sb = new StringBuilder();
        sb.append("BySubjectItemTwo{subjectId=").append(subjectId);
        sb.append(", mainName=").append(mainName);
        sb.append(", mainLink=").append(mainLink);
        sb.append(", subjectName=").append(subjectName);
        sb.append(", subjectWeight=").append(mainSubjectWeight);
        sb.append('}');
        return sb.toString();
    }
}

错误

----------< sed.work:CreateDatabaseByTitleAndSubjectDatabase >----------
构建 CreateDatabaseByTitleAndSubjectDatabase 1.0-SNAPSHOT
-------------------------------[ jar ]---------------------------------
--- exec-maven-plugin:1.5.0:exec (default-cli) @ CreateDatabaseByTitleAndSubjectDatabase ---
Connected to qDatabase!
[SQLITE_ERROR] SQL error or missing database (ambiguous column name: subject.id)
------------------------------------------------------------------------
构建成功
------------------------------------------------------------------------
总时间: 1.484 s
完成于: 2020-10-16T12:42:35-05:00
------------------------------------------------------------------------

Netbean's 信息

产品版本: Apache NetBeans IDE 12.1
Java: 15; Java HotSpot(TM) 64-Bit Server VM 15+36-1562
运行时: Java(TM) SE Runtime Environment 15+36-1562
系统: Windows 10 version 10.0 running on amd64; Cp1252; en_US (nb)
Maven 项目
英文:

I created a database using DB Browser for SQLite. Now I am trying to run queries to retrieve data from the database, and I have run into an issue. When I run the query in DB Browser, the query runs smoothly. When I attempt to run the same query in Java, I get an error message. I triple-checked the query string. I looked to make sure I was not using SQLite keywords incorrectly. Why am I getting an error when I run this query Java?

SELECT
subject.id, main.name, main.link, subject.name, main_subject.weight
FROM 
main_subject
LEFT JOIN 
main ON main_subject.mainId = main.id
LEFT JOIN 
subject ON main_subject.subjectId = subject.id

The query running correctly in DB Browser.
SQLite查询在Java中无法运行

MCVE:

Main

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* @author sedrick
*/
public class Main
{
public static void main(String[] args)
{
try (DatabaseHandler databaseHandler = new DatabaseHandler()) {
List&lt;BySubjectItemTwo&gt; bySubjectItemTwos = databaseHandler.getBySubjectItems();
bySubjectItemTwos.forEach(System.out::println);
//databaseHandler.getByTitleItems().forEach(System.out::println);
}
catch (Exception ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

DatabaseHandler

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author sedrick
*/
public class DatabaseHandler implements AutoCloseable
{
String dbString = &quot;jdbc:sqlite:qDatabase.sqlite3&quot;;
private Connection conn;
public DatabaseHandler()
{
try {
conn = DriverManager.getConnection(dbString);
System.out.println(&quot;Connected to qDatabase!&quot;);
}
catch (SQLException ex) {
Logger.getLogger(DatabaseHandler.class.getName()).log(Level.SEVERE, null, ex);
}
}
@Override
public void close() throws Exception
{
conn.close();
}
public List&lt;BySubjectItemTwo&gt; getBySubjectItems()
{
List&lt;BySubjectItemTwo&gt; returnList = new ArrayList();
String sqlString = &quot;SELECT subject.id, main.name, main.link, subject.name, main_subject.weight FROM main_subject LEFT JOIN main ON main_subject.mainId = main.id LEFT JOIN subject ON main_subject.subjectId = subject.id&quot;;
try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sqlString)) {
while (rs.next()) {
System.out.println(rs.getInt(&quot;subject.id&quot;) + &quot; - &quot; + rs.getString(&quot;main.name&quot;) + &quot; - &quot; + rs.getString(&quot;main.link&quot;) + &quot; - &quot; + rs.getString(&quot;subject.name&quot;) + &quot; - &quot; + rs.getInt(&quot;main_subject.weight&quot;));
//returnList.add(new BySubjectItemTwo(rs.getInt(&quot;subject.id&quot;), rs.getString(&quot;main.name&quot;), rs.getString(&quot;main.link&quot;), rs.getString(&quot;subject.name&quot;), rs.getInt(&quot;main_subject.weight&quot;)));
}
}
catch (SQLException e) {
System.out.println(e.getMessage());
}
return returnList;
}  
}

BySubjectItemTwo

/**
*
* @author sedrick
*/
public class BySubjectItemTwo
{
private int subjectId;
private String mainName;
private String mainLink;
private String subjectName;
private int mainSubjectWeight;
public BySubjectItemTwo(int subjectId, String mainName, String mainLink, String subjectName, int mainSubjectWeight)
{
this.subjectId = subjectId;
this.mainName = mainName;
this.mainLink = mainLink;
this.subjectName = subjectName;
this.mainSubjectWeight = mainSubjectWeight;
}
public int getSubjectWeight()
{
return mainSubjectWeight;
}
public void setSubjectWeight(int mainSubjectWeight)
{
this.mainSubjectWeight = mainSubjectWeight;
}
public int getSubjectId()
{
return subjectId;
}
public void setSubjectId(int subjectId)
{
this.subjectId = subjectId;
}
public String getMainName()
{
return mainName;
}
public void setMainName(String mainName)
{
this.mainName = mainName;
}
public String getMainLink()
{
return mainLink;
}
public void setMainLink(String mainLink)
{
this.mainLink = mainLink;
}
public String getSubjectName()
{
return subjectName;
}
public void setSubjectName(String subjectName)
{
this.subjectName = subjectName;
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append(&quot;BySubjectItemTwo{subjectId=&quot;).append(subjectId);
sb.append(&quot;, mainName=&quot;).append(mainName);
sb.append(&quot;, mainLink=&quot;).append(mainLink);
sb.append(&quot;, subjectName=&quot;).append(subjectName);
sb.append(&quot;, subjectWeight=&quot;).append(mainSubjectWeight);
sb.append(&#39;}&#39;);
return sb.toString();
}
}

Error

----------&lt; sed.work:CreateDatabaseByTitleAndSubjectDatabase &gt;----------
Building CreateDatabaseByTitleAndSubjectDatabase 1.0-SNAPSHOT
--------------------------------[ jar ]---------------------------------
--- exec-maven-plugin:1.5.0:exec (default-cli) @ CreateDatabaseByTitleAndSubjectDatabase ---
Connected to qDatabase!
[SQLITE_ERROR] SQL error or missing database (ambiguous column name: subject.id)
------------------------------------------------------------------------
BUILD SUCCESS
------------------------------------------------------------------------
Total time:  1.484 s
Finished at: 2020-10-16T12:42:35-05:00
------------------------------------------------------------------------

Netbean's Info

Product Version: Apache NetBeans IDE 12.1
Java: 15; Java HotSpot(TM) 64-Bit Server VM 15+36-1562
Runtime: Java(TM) SE Runtime Environment 15+36-1562
System: Windows 10 version 10.0 running on amd64; Cp1252; en_US (nb)
Maven Project

答案1

得分: 1

这是你查询的问题:

FROM main_subject, main, subject

从你的语句中移除“,main, subject”。

表格mainsubjectLEFT连接之后已经正确连接。

当你在FROM子句中也使用它们时,这会创建额外的引用并导致与相同表格的CROSS连接。

另外,虽然SQLite允许查询返回多个相同名称的列,但最好的做法是给列取别名,以便在结果集中所有列名都是不同的。

所以给main.namesubject.name取别名,就像这样:

SELECT subject.id, main.name AS main_name, ..., subject.name AS subject_name, ...

当检索列值时不要使用表格前缀:

System.out.println(rs.getInt("id") + " - " + rs.getString("main_name") + " - " + rs.getString("link") + " - " + rs.getString("subject_name") + " - " + rs.getInt("weight"));
英文:

This:

FROM main_subject, main, subject

is the problem with your query.<br/>

Remove , main, subject from your statement.<br/>
The tables main and subject are correctly joined after the LEFT joins.<br/>
When you use them also in the FROM clause this creates additional references and CROSS joins to the same tables.<br/>

Also, although SQLite allows a query to return more than 1 columns with the same name, it is a good practice to alias columns so that in the resultset all column names are different.<br/>
So give aliases to main.name and subject.name, something like this:

SELECT subject.id, main.name AS main_name, ..., subject.name AS subject_name, ...

and when you retrieve the column values don't use the table prefixes:

System.out.println(rs.getInt(&quot;id&quot;) + &quot; - &quot; + rs.getString(&quot;main_name&quot;) + &quot; - &quot; + rs.getString(&quot;link&quot;) + &quot; - &quot; + rs.getString(&quot;subject_name&quot;) + &quot; - &quot; + rs.getInt(&quot;weight&quot;));

huangapple
  • 本文由 发表于 2020年10月17日 04:19:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/64395900.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定