![](/img/trans.png)
[英]SQLITE_ERROR SQL error or missing database (near “(”: syntax error)
[英]SQLITE_ERROR SQL error or missing database (near “Statements”: syntax error)
我正在嘗試通過使用准備好的語句來應用注入攻擊預防。 設置代碼的方式是,我有一個DBManager類,它通過存儲負責執行sqlite語句的java方法來充當Java和sqlite之間的催化劑。 然后,我有了表類,它們自己存儲sqlite語句。 基本上,我想存儲一個執行INSERT語句的准備好的語句,並在調用open()方法時與其建立連接。 這是有問題的兩個類的摘錄,我在其中試圖為IncomeStatementTable類中存儲的常量創建准備好的表調:
package com.anniemals.database;
//the database package is meant to be the API package which
// takes all queried values from a database and sets them to values
// in each respective class
//MAKE SURE TO ADD METHODS TO ACCESS DB METADATA, FUNCTIONS, AND VIEWS LATER!
import com.anniemals.clients.ClientInfoIncomeStatement;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class DBManager {
public static final String DB_NAME = "clients.db";
public static final String DB_PATH = "jdbc:sqlite:C:/Users/Steven/Documents/ProjectAnnieMalsRemote/Databases/" + DB_NAME;
//SortOrders for queries
public static final int ORDER_BY_NONE = 1;
public static final int ORDER_BY_ASC = 2;
public static final int ORDER_BY_DESC = 3;
//Sets a connection to access and utilize sqlite expressions, which are assigned to the PreparedStatement variables for later use
private Connection conn;
//Inserts
private PreparedStatement insertIntoIncomeStatementPStatement;
//Composition has-a relationships for Table Classes
private ClientInfoTable clientInfoTable;
private IncomeStatementTable incomeStatementTable;
public DBManager() {
//Composition has-a relationships for Table Classes
this.clientInfoTable = new ClientInfoTable();
this.incomeStatementTable = new IncomeStatementTable();
}
public static DBManager getInstance() {
return instance;
}
//Open and Close DB methods
public boolean open(){
try{
conn = DriverManager.getConnection(DB_PATH);
//STATEMENT WHICH CAUSED THE ERROR!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
insertIntoIncomeStatementPStatement = conn.prepareStatement(incomeStatementTable.getInsertIncomeStatement());
System.out.println("Database Opened");
return true;
} catch (SQLException e){
System.out.println("Couldn't connect to database: " + e.getMessage());
e.printStackTrace();
return false;
}
}
public void close(){
try {
if (insertIntoIncomeStatementPStatement != null){
insertIntoIncomeStatementPStatement.close();
}
if(insertIntoClientInfoPStatement != null){
insertIntoClientInfoPStatement.close();
}
if (conn != null){
conn.close();
System.out.println("Database closed");
}
} catch (SQLException e){
System.out.println("Couldn't close connection: " + e.getMessage());
}
}
public class IncomeStatementTable {
//Column Labels
public static final String TABLE_INCOME = "Income Statements";
public static final String COLUMN_INCOME_ID = "_id";
public static final String COLUMN_CLIENT_ID = "Client ID";
public static final String COLUMN_INCOME_DATE = "Date";
public static final String COLUMN_INCOME_TOTAL_OPER_EXPENSES = "Total Operating Expenses";
public static final String COLUMN_INCOME_GROSS_PROFIT = "Gross Profit";
public static final String COLUMN_INCOME_AMORTIZATION = "Amortization";
public static final String COLUMN_INCOME_EBITDA = "E.B.I.T.D.A.";
public static final String COLUMN_INCOME_PROFIT_BEFORE_TAX = "Profit Before Tax";
public static final String COLUMN_INCOME_TAX = "Tax";
public static final String COLUMN_INCOME_NET_PROFIT = "Net Profit";
public static final String COLUMN_INCOME_EARN_PER_SHARE = "Earnings Per Share";
//Column Indexes
public static final int INDEX_INCOME_ID = 1;
public static final int INDEX_INCOME_CLIENT_ID = 2;
public static final int INDEX_INCOME_DATE = 3;
public static final int INDEX_INCOME_TOTAL_OPER_EXPENSES = 4;
public static final int INDEX_INCOME_GROSS_PROFIT = 5;
public static final int INDEX_INCOME_AMORTIZATION = 6;
public static final int INDEX_INCOME_EBITDA = 7;
public static final int INDEX_INCOME_PROFIT_BEFORE_TAX = 8;
public static final int INDEX_INCOME_TAX = 9;
public static final int INDEX_INCOME_NET_PROFIT = 10;
public static final int INDEX_INCOME_EARN_PER_SHARE = 11;
public static final String INSERT_INCOME_STATEMENT = "INSERT INTO " + TABLE_INCOME + "(" + COLUMN_INCOME_ID +
", " + COLUMN_CLIENT_ID + ", " + COLUMN_INCOME_DATE + ", " + COLUMN_INCOME_TOTAL_OPER_EXPENSES
+ ", " + COLUMN_INCOME_GROSS_PROFIT + ", " + COLUMN_INCOME_AMORTIZATION + ", " + COLUMN_INCOME_EBITDA
+ ", " + COLUMN_INCOME_PROFIT_BEFORE_TAX + ", " + COLUMN_INCOME_TAX + ", " + COLUMN_INCOME_NET_PROFIT
+ ", " + COLUMN_INCOME_EARN_PER_SHARE + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
public static String getInsertIncomeStatement() {
return INSERT_INCOME_STATEMENT;
}
我知道它與open()方法中的變量賦值語句有關,因為當我注釋掉它時,程序運行良好,並且可以連接到數據庫。 我試圖從其他與我的問題類似的問題中尋找答案,但是我對sqlite語句本身的語法所做的任何更改仍然使我面臨相同的錯誤。 我嘗試跟蹤線程堆棧,以查看錯誤中“聲明”所指的內容,但我仍不確定。 有人可以幫助我進一步指出問題所在嗎?
這是跟蹤堆棧:
org.sqlite.SQLiteException: [SQLITE_ERROR] SQL error or missing database (near "Statements": syntax error)
at sqlite.jdbc@3.23.1/org.sqlite.core.DB.newSQLException(DB.java:909)
at sqlite.jdbc@3.23.1/org.sqlite.core.DB.newSQLException(DB.java:921)
at sqlite.jdbc@3.23.1/org.sqlite.core.DB.throwex(DB.java:886)
at sqlite.jdbc@3.23.1/org.sqlite.core.NativeDB.prepare_utf8(Native Method)
at sqlite.jdbc@3.23.1/org.sqlite.core.NativeDB.prepare(NativeDB.java:127)
at sqlite.jdbc@3.23.1/org.sqlite.core.DB.prepare(DB.java:227)
at sqlite.jdbc@3.23.1/org.sqlite.core.CorePreparedStatement.<init>(CorePreparedStatement.java:45)
at sqlite.jdbc@3.23.1/org.sqlite.jdbc3.JDBC3PreparedStatement.<init>(JDBC3PreparedStatement.java:30)
at sqlite.jdbc@3.23.1/org.sqlite.jdbc4.JDBC4PreparedStatement.<init>(JDBC4PreparedStatement.java:19)
at sqlite.jdbc@3.23.1/org.sqlite.jdbc4.JDBC4Connection.prepareStatement(JDBC4Connection.java:48)
at sqlite.jdbc@3.23.1/org.sqlite.jdbc3.JDBC3Connection.prepareStatement(JDBC3Connection.java:263)
at sqlite.jdbc@3.23.1/org.sqlite.jdbc3.JDBC3Connection.prepareStatement(JDBC3Connection.java:235)
at sqlite.jdbc@3.23.1/org.sqlite.jdbc3.JDBC3Connection.prepareStatement(JDBC3Connection.java:242)
at AccountingFinancialModellingAndValuationApplication/com.anniemals.database.DBManager.open(DBManager.java:60)
at AccountingFinancialModellingAndValuationApplication/com.anniemals.Main.main(Main.java:26)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)
在此先感謝可以提供幫助的人。
該行定義的表名:
public static final String TABLE_INCOME = "Income Statements"
包含空格,這是不允許的。
更改為此:
public static final String TABLE_INCOME = "[Income Statements]"
當表或列名稱包含空格時,必須在方括號或反引號(ASCII代碼096)中將空格括起來。
您必須對包含空格或點的列名稱執行相同的操作 :
public static final String TABLE_INCOME = "[Income Statements]";
public static final String COLUMN_INCOME_ID = "_id";
public static final String COLUMN_CLIENT_ID = "[Client ID]";
public static final String COLUMN_INCOME_DATE = "Date";
public static final String COLUMN_INCOME_TOTAL_OPER_EXPENSES = "[Total Operating Expenses]";
public static final String COLUMN_INCOME_GROSS_PROFIT = "[Gross Profit]";
public static final String COLUMN_INCOME_AMORTIZATION = "Amortization";
public static final String COLUMN_INCOME_EBITDA = "[E.B.I.T.D.A.]";
public static final String COLUMN_INCOME_PROFIT_BEFORE_TAX = "[Profit Before Tax]";
public static final String COLUMN_INCOME_TAX = "Tax";
public static final String COLUMN_INCOME_NET_PROFIT = "[Net Profit]";
public static final String COLUMN_INCOME_EARN_PER_SHARE = "[Earnings Per Share]";
似乎很奇怪的是,由於您正在嘗試向表中插入行,這意味着您已經創建了表。
但是如何?
您為CREATE語句中的表和列使用了什么名稱?
我找到了解決問題的方法。 它不是最漂亮的解決方案,但它可以工作。 基本上,我按照forpas的建議向DBManager類添加了一個create方法:
public boolean checkCreateIncomeStatementTable(){
String sql = "CREATE TABLE IF NOT EXISTS Income_Statements(\n" +
" _id INTEGER PRIMARY KEY,\n" +
" Client_ID INTEGER NOT NULL,\n" +
" Date NUMERAL,\n" +
" Total_Operating_Expenses DOUBLE NOT NULL,\n" +
" Gross_Profit DOUBLE NOT NULL,\n" +
" Amortization DOUBLE NOT NULL,\n" +
" EBITDA DOUBLE NOT NULL,\n" +
" Profit_Before_Tax DOUBLE NOT NULL,\n" +
" Tax DOUBLE NOT NULL,\n" +
" Net_Profit DOUBLE NOT NULL,\n" +
" Earnings_Per_Share DOUBLE NOT NULL\n" +
");";
try{
conn = DriverManager.getConnection(DB_PATH);
Statement statement = conn.createStatement();
System.out.println("Database Opened");
statement.executeQuery(sql);
System.out.println("Checked creation of Income Statement Table");
return true;
} catch (SQLException e){
System.out.println("Couldn't connect to database: " + e.getMessage());
e.printStackTrace();
return false;
}
}
然后,對於每個帶有空格的列標簽,我都使用了下划線,因為Main類出於某種原因不想讀取方括號。
public static final String TABLE_INCOME = "Income_Statements";
public static final String COLUMN_INCOME_ID = "_id";
public static final String COLUMN_CLIENT_ID = "Client_ID";
public static final String COLUMN_INCOME_DATE = "Date";
public static final String COLUMN_INCOME_TOTAL_OPER_EXPENSES = "Total_Operating_Expenses";
public static final String COLUMN_INCOME_GROSS_PROFIT = "Gross_Profit";
public static final String COLUMN_INCOME_AMORTIZATION = "Amortization";
public static final String COLUMN_INCOME_EBITDA = "EBITDA";
public static final String COLUMN_INCOME_PROFIT_BEFORE_TAX = "Profit_Before_Tax";
public static final String COLUMN_INCOME_TAX = "Tax";
public static final String COLUMN_INCOME_NET_PROFIT = "Net_Profit";
public static final String COLUMN_INCOME_EARN_PER_SHARE = "Earnings_Per_Share";
現在一切似乎都正常了
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.