java.sql错误。SQLException: near " - ":语法错误。

时间:2022-05-24 01:24:59

I am developing a Java tools to convert StarDict database to SQLite database for use with an Android Dictionary app. But I get the following error:

我正在开发一种Java工具,将StarDict数据库转换为SQLite数据库,以便使用Android字典应用程序。

java.sql.SQLException: near "-": syntax error at
org.sqlite.DB.throwex(DB.java:288) at
org.sqlite.NativeDB.prepare(Native Method) at
org.sqlite.DB.prepare(DB.java:114) at
org.sqlite.Stmt.executeUpdate(Stmt.java:102) at
com.trivisionsc.ConvertData.createData(ConvertData.java:353) at
com.trivisionsc.ConvertData.excuteConvert(ConvertData.java:314) at
com.trivisionsc.ConvertData$1.actionPerformed(ConvertData.java:116) at
javax.swing.AbstractButton.fireActionPerformed(Unknown Source) at
javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source) at
javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source) at
javax.swing.DefaultButtonModel.setPressed(Unknown Source) at
javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source) at
java.awt.Component.processMouseEvent(Unknown Source) at
javax.swing.JComponent.processMouseEvent(Unknown Source) at
java.awt.Component.processEvent(Unknown Source) at
java.awt.Container.processEvent(Unknown Source) at
java.awt.Component.dispatchEventImpl(Unknown Source) at
java.awt.Container.dispatchEventImpl(Unknown Source) at
java.awt.Component.dispatchEvent(Unknown Source) at
java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source) at
java.awt.LightweightDispatcher.processMouseEvent(Unknown Source) at
java.awt.LightweightDispatcher.dispatchEvent(Unknown Source) at
java.awt.Container.dispatchEventImpl(Unknown Source) at
java.awt.Window.dispatchEventImpl(Unknown Source) at
java.awt.Component.dispatchEvent(Unknown Source) at
java.awt.EventQueue.dispatchEvent(Unknown Source) at
java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at
java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at
java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at
java.awt.EventDispatchThread.pumpEvents(Unknown Source) at
java.awt.EventDispatchThread.pumpEvents(Unknown Source) at
java.awt.EventDispatchThread.run(Unknown Source)

And here is the source:

来源如下:

package com.trivisionsc;

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.WindowConstants;


public class ConvertData extends JFrame

{
  // Variables declaration
  int count=0;
  private static final long serialVersionUID = 1L;
  private JLabel lblIndexFilePath;
  private JLabel lblDictFilePath;
  private JLabel lblDisplayProcess;
  private JTextField txtSourceFilePath;
  private JTextField txtDbFilePath;
  private JButton btnPerform;
  private JButton btnStop;
  private JButton btnIndexFileSelect;
  private JButton btnDictFileSelect;
  private JPanel contentPane;
  private JFileChooser fc;
  private String messageResult;
  private int start;
  private int countWord;
  private int numberWord;
  int result;
  boolean stop;

  // End of variables declaration

  public ConvertData()

  {
    super();
    createLayout();
    this.setVisible(true);

  }


  private void createLayout()

  {

    // Initialize
    lblIndexFilePath = new JLabel();
    lblDictFilePath = new JLabel();
    lblDisplayProcess= new JLabel();
    txtSourceFilePath = new JTextField();
    txtDbFilePath = new JTextField();
    btnPerform = new JButton();
    btnStop=new JButton();
    btnIndexFileSelect=new JButton();
    btnDictFileSelect=new JButton();
       contentPane = (JPanel)this.getContentPane();
      fc = new JFileChooser();
      fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
       //lblDisplayProcess
      lblDisplayProcess.setForeground(new Color(255, 0, 0));
    lblDisplayProcess.setHorizontalAlignment(SwingConstants.LEFT);

    //lblIndexFilePath
    lblDictFilePath.setHorizontalAlignment(SwingConstants.LEFT);
    lblIndexFilePath.setText(" Path store source dict");

    //lblDictFilePath
    lblDictFilePath.setHorizontalAlignment(SwingConstants.LEFT);
    lblDictFilePath.setText(" Path store database");

    // txtSourceFilePath
    txtSourceFilePath.setForeground(new Color(0, 0, 255));
    txtSourceFilePath.setToolTipText("Enter path store source dict");

    // txtDbFilePath
    txtDbFilePath.setForeground(new Color(0, 0, 255));
    txtDbFilePath.setToolTipText("Enter path store database");

    // btnPerform
    btnPerform.setText("Convert");
    btnPerform.addActionListener(new ActionListener(){
      public void actionPerformed(ActionEvent e)

      {
         //insert database
         excuteConvert();
      }

      });
    // btnStop
    btnStop.setText("Stop");
    btnStop.setEnabled(false);
    btnStop.addActionListener(new ActionListener(){
      public void actionPerformed(ActionEvent e)

      {
        stop=true;
      }

      });

    // btnIndexFileSelect
    btnIndexFileSelect.setText("Browser...");
    btnIndexFileSelect.addActionListener(new ActionListener(){
      public void actionPerformed(ActionEvent e)

      {
        int returnVal = fc.showOpenDialog(ConvertData.this);


              if (returnVal == JFileChooser.APPROVE_OPTION)
              {
                  File file = fc.getSelectedFile();
                  txtSourceFilePath.setText(file.getAbsolutePath());

              }
      }

      });
    // btnDictFileSelect
    btnDictFileSelect.setText("Browser...");
    btnDictFileSelect.addActionListener(new ActionListener(){
      public void actionPerformed(ActionEvent e)

      {
        int returnVal = fc.showOpenDialog(ConvertData.this);

              if (returnVal == JFileChooser.APPROVE_OPTION)
              {
                  File file = fc.getSelectedFile();
                  txtDbFilePath.setText(file.getAbsolutePath());
              }
      }

      });  

    // contentPane
    contentPane.setLayout(null);
    contentPane.setBorder(BorderFactory.createEtchedBorder());
    // add component for Frame
    addComponent(contentPane, lblIndexFilePath, 35,10,126,18);
    addComponent(contentPane, lblDictFilePath, 35,47,126,18);
    addComponent(contentPane, txtSourceFilePath, 160,10,203,22);
    addComponent(contentPane, btnIndexFileSelect, 365,9,80,25);
    addComponent(contentPane, txtDbFilePath, 160,45,203,22);
    addComponent(contentPane, btnDictFileSelect, 365,44,80,25);
    addComponent(contentPane, btnPerform, 160,75,90,30);
    addComponent(contentPane, btnStop, 250,75,90,30);
    addComponent(contentPane, lblDisplayProcess, 35,110,250,18);

    //set title for program
    this.setTitle("Convert data for TDict");
    // set icon for program
    ImageIcon receivedIcon = new ImageIcon("resource\\images\\tri.png");
    Image logoImg=receivedIcon.getImage();
    this.setIconImage(logoImg);
    //set position display
    this.setLocation(new Point(400, 300));
    //set size display
    this.setSize(new Dimension(500, 200));
    //set event close window
    this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    //set disable resize
    this.setResizable(false);

  }


  /** Add Component Without a Layout Manager (Absolute Positioning) */

  private void addComponent(Container container,Component c,int x,int y,int width,int height)

  {
    c.setBounds(x,y,width,height);
    container.add(c);
  }
  public void excuteConvert()
  {
    //set empty for display result run
    lblDisplayProcess.setText("");  
       //name dictionary
       String dictName=null;
       // path to file
       String sourceStorePath=txtSourceFilePath.getText();
    String dbStorePath=txtDbFilePath.getText();
    // path file source dictionary don't exits
    File directorySource = new File(sourceStorePath);  

    // path file source dictionary don't exits
    if (sourceStorePath==null || sourceStorePath.equals("")||!directorySource.exists())
    {
      JOptionPane.showMessageDialog(ConvertData.this,"Path is invalid!","Error",JOptionPane.ERROR_MESSAGE,null);
      txtSourceFilePath.requestFocus();
      return;
    }

    // path file database don't exits
    File directoryDb = new File(dbStorePath);  
    if (dbStorePath==null || dbStorePath.equals("")||!directoryDb.exists())
    {
      JOptionPane.showMessageDialog(ConvertData.this,"Path is invalid!","Error",JOptionPane.ERROR_MESSAGE,null);
      txtDbFilePath.requestFocus();
      return;
    }  

    // check in source directory include: file index,dictionary and information?
    File[] files = directorySource.listFiles();  
    int check=0;
    if (files.length>0)
    {
      for (int i = 0; i < files.length; i++)  
      {  
        if(files[i].getName().endsWith(".idx"))
        {
          check++;
          dictName=files[i].getName().replaceAll(".idx", "");
        }
        if(files[i].getName().endsWith(".dict"))
          check++;
        if(files[i].getName().endsWith(".ifo"))
          check++;
      }
    }
    else
    {
      // Folder don't include any file
      JOptionPane.showMessageDialog(ConvertData.this,"Source directory have to include files: .idx,.dict and .ifo","Error",JOptionPane.ERROR_MESSAGE,null);
      txtSourceFilePath.requestFocus();
      return;
    }
    if(check<3)
    {
      // Folder don't include full file
      JOptionPane.showMessageDialog(ConvertData.this,"Source directory have to include files: .idx,.dict and .ifo","Error",JOptionPane.ERROR_MESSAGE,null);
      txtSourceFilePath.requestFocus();
      return;
    }

        // path file information
       String infoFilePath=sourceStorePath+"\\"+dictName+".ifo";
    // path file index
       String indexFilePath=sourceStorePath+"\\"+dictName+".idx";
       //path file content
       String dataFilePath=sourceStorePath+"\\"+dictName+".dict";
       // read file information to get max size file index
       int idxFileSize=0;
       try
       {
         // open stream read file
         FileInputStream fstream=new FileInputStream(infoFilePath);
         DataInputStream in = new DataInputStream(fstream);
         BufferedReader  input = new BufferedReader (new InputStreamReader(in));
         String strLine;
         int k=0;
           //Read File Line By Line
           while ((strLine = input.readLine()) != null)   {
             if (strLine.contains("idxfilesize="))
             {
               String valueStr=strLine.replaceAll("idxfilesize=", "");
               idxFileSize = Integer.parseInt(valueStr.trim());
               k++;
                }
             if (strLine.contains("wordcount="))
             {
               String valueStr=strLine.replaceAll("wordcount=", "");
               numberWord = Integer.parseInt(valueStr.trim());
               k++;
                }
             if(k>1) break;

           }
           //Close the input stream
           input.close();
       }
       catch(Exception e)
       {
         JOptionPane.showMessageDialog(ConvertData.this,"System error!Please try again","Error",JOptionPane.ERROR_MESSAGE,null);
      setActive();
         return;  
       }
       // perform convert
       this.createData(dbStorePath,indexFilePath,dataFilePath,idxFileSize,dictName);

   }

  @SuppressWarnings("deprecation")
  public void createData(String dbStorePath,String indexFilePath,String dataFilePath,int idxFileSize,String dictName){
     // Open connect database SQLite
     try
     {

        File checkFile = new File(dbStorePath+"\\"+dictName+".db");
         if (checkFile.exists())
         {

           result =JOptionPane.showConfirmDialog((ConvertData.this), "Are you sure to overwrite?", "File existed!", JOptionPane.YES_NO_OPTION);
           if (result==1)
           {
             setActive();
             return;  
           }
           else
           {
             boolean isDeleteSuccess=checkFile.delete();
             if (!isDeleteSuccess)
               {
                 JOptionPane.showMessageDialog(ConvertData.this,"Delete file unsuccessfully. Please restart program. ","Error",JOptionPane.ERROR_MESSAGE,null);
                 setActive();
                 return;  
               }


           }
         }

        //Disable controls before insert database
      setUnActive();
        Class.forName("org.sqlite.JDBC");
        Connection conn = DriverManager.getConnection("jdbc:sqlite:"+dbStorePath+"\\"+dictName+".db");
        final Statement st = conn.createStatement();
        // Create table and index
        st.executeUpdate("CREATE TABLE IF NOT EXISTS "+dictName+"(Word TEXT NOT NULL PRIMARY KEY, Content TEXT,Id INTEGER NOT NULL);");
        st.executeUpdate("CREATE INDEX wrod_idx ON "+dictName+"(Id);");
        // Read file
        FileInputStream fileIndex=new FileInputStream(indexFilePath);
        final BufferedInputStream input = new BufferedInputStream(fileIndex);
          // File content
          FileInputStream fileDict=new FileInputStream(dataFilePath);
          final BufferedInputStream dictInput = new BufferedInputStream(fileDict);
          // Array store data read form File index
          final byte[] data = new byte[idxFileSize];
          input.read(data);

          final String dictionName=dictName;
          countWord=0;
      // Read data
          new Thread(new Runnable() {
             public void run() {
                for (int i=0; i < data.length; i++)
                {
                  if (data[i] == '\0')
                  {
                      try
                      {
                        //Read data form index
                            int lengthOfData = i - start;
                            byte[] tmp = new byte[lengthOfData];
                            System.arraycopy(data, start, tmp, 0, lengthOfData);
                            int length = byteArrayToInt(data, i+5);
                            //Word
                            String word = new String(tmp, "UTF-8");
                            //Read content from file data
                            byte[] value = new byte[length];
                            dictInput.read(value);
                            //Content
                            String content = new String(value,"UTF-8");
                            i += 9;
                            start = i;
                             // insert into database
                             st.executeUpdate("INSERT INTO "+dictionName+"(Word,Content,Id) VALUES ('"+Utility.encodeContent(word)+"','"+Utility.encodeContent(content)+"',"+countWord+")");
                             messageResult="Executing .... Insert element "+countWord+"/"+numberWord;
                             countWord++;
                             if (stop)
                             {
                               setActive();
                               messageResult="Cancel";
                          i=data.length;
                          st.close();
                           }

                      }
                      catch(Exception e)
                      {
                        ;
                       }

                      SwingUtilities.invokeLater(
                         new Runnable()
                         {
                           public void run()
                           {
                             lblDisplayProcess.setText(messageResult);
                           }
                         }
                      );
                      try
                      {
                       Thread.sleep(1);

                      } catch(Exception e)
                      {
                        JOptionPane.showMessageDialog(ConvertData.this,"System error!Please try again","Error",JOptionPane.ERROR_MESSAGE,null);
                      setActive();
                       return;
                      }
                  }

                }
                try
                {
                  if(!stop&&countWord==numberWord)
                  {
                    setActive();
                      lblDisplayProcess.setText("Completed! ");
                      st.close();
                  }
                }
                catch(Exception e)
                  {
                  JOptionPane.showMessageDialog(ConvertData.this,"System error!Please try again","Error",JOptionPane.ERROR_MESSAGE,null);
                  setActive();
                   return;
                }
                ///
              }
          }).start();


     }catch(Exception e)
     {
       JOptionPane.showMessageDialog(ConvertData.this,"System error!Please try again","Error",JOptionPane.ERROR_MESSAGE,null);
       setActive();
         return;
     }

    }

   //method to calculate value of byteArray
    public static int byteArrayToInt(byte[] b, int offset) {
        int value = 0;
        for (int i = 0; i < 4; i++) {
            int shift = (4 - 1 - i) * 8;
            value += (b[i + offset] & 0x000000FF) << shift;
        }
        return value;
    }
    public void updateControl() throws Throwable
    {
               for (int i=0; i<100; i++) {
               System.out.println("thread "
                  +Thread.currentThread().getName()+" step "+i);
               Thread.sleep(500);
            }

    }
    public final  void setActive()
    {
       //set for control enable
        txtDbFilePath.setEnabled(true);
       txtSourceFilePath.setEnabled(true);
       btnIndexFileSelect.setEnabled(true);
       btnDictFileSelect.setEnabled(true);
       btnPerform.setEnabled(true);
       btnStop.setEnabled(false);
    }
    public final void setUnActive()
    {
      //set for control disable
        txtDbFilePath.setEnabled(false);
       txtSourceFilePath.setEnabled(false);
       btnIndexFileSelect.setEnabled(false);
       btnDictFileSelect.setEnabled(false);
       btnPerform.setEnabled(false);
       btnStop.setEnabled(true);
    }
  public static void main(String[] args)

  {
    //set Look and Feel
    JFrame.setDefaultLookAndFeelDecorated(true);
    JDialog.setDefaultLookAndFeelDecorated(true);
    try
    {
      UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    }
    catch (Exception ex)
    {
      System.out.println("Failed loading L&F: ");
      System.out.println(ex);
    }
    //perform run program convert data for TDict
    new ConvertData();

    };

}

Any ideas? Thanks a lot.

什么好主意吗?非常感谢。

2 个解决方案

#1


4  

The problem is on the line that says:

问题是这样的:

st.executeUpdate("CREATE TABLE IF NOT EXISTS "+dictName+"(Word TEXT NOT NULL PRIMARY KEY, Content TEXT,Id INTEGER NOT NULL);");

At a guess, dictName contains a - character, which is not a legal part of a bare literal in SQL. Sanitize, or put "double quote" characters around it. They'll need backslash quoting to be part of a Java string. But sanitizing (e.g., by stripping all non-alphabetic characters) is much better.

在一个猜测中,dictName包含一个字符,它不是SQL中一个纯文字的合法部分。对其进行消毒,或在其周围加上“双引号”字符。他们需要反斜杠引用作为Java字符串的一部分。但是消毒(例如,除去所有的非字母字符)要好得多。

#2


2  

This is line 353 of your code:

这是你代码的第353行:

st.executeUpdate("CREATE TABLE IF NOT EXISTS " +dictName+"(Word TEXT NOT NULL PRIMARY KEY, Content TEXT,Id INTEGER NOT NULL);");

The SQL has a syntax error in it. I'm going to guess that dictName has spaces and a - in it. You need to fix that.

SQL中有一个语法错误。我猜这个名字里面有空格和a。你需要解决这个问题。

#1


4  

The problem is on the line that says:

问题是这样的:

st.executeUpdate("CREATE TABLE IF NOT EXISTS "+dictName+"(Word TEXT NOT NULL PRIMARY KEY, Content TEXT,Id INTEGER NOT NULL);");

At a guess, dictName contains a - character, which is not a legal part of a bare literal in SQL. Sanitize, or put "double quote" characters around it. They'll need backslash quoting to be part of a Java string. But sanitizing (e.g., by stripping all non-alphabetic characters) is much better.

在一个猜测中,dictName包含一个字符,它不是SQL中一个纯文字的合法部分。对其进行消毒,或在其周围加上“双引号”字符。他们需要反斜杠引用作为Java字符串的一部分。但是消毒(例如,除去所有的非字母字符)要好得多。

#2


2  

This is line 353 of your code:

这是你代码的第353行:

st.executeUpdate("CREATE TABLE IF NOT EXISTS " +dictName+"(Word TEXT NOT NULL PRIMARY KEY, Content TEXT,Id INTEGER NOT NULL);");

The SQL has a syntax error in it. I'm going to guess that dictName has spaces and a - in it. You need to fix that.

SQL中有一个语法错误。我猜这个名字里面有空格和a。你需要解决这个问题。