=== modified file 'src/com/goldencode/p2j/convert/db/ConversionData.java'
--- old/src/com/goldencode/p2j/convert/db/ConversionData.java	2021-10-12 08:35:45 +0000
+++ new/src/com/goldencode/p2j/convert/db/ConversionData.java	2022-10-25 08:24:00 +0000
@@ -147,11 +147,12 @@
       {
          // check if the table exists
          boolean[] found = { false };
+         Object[] args = new Object[] {table.toUpperCase() + "__WORK"};
          helper.executeQuery("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES " +
-                             "WHERE TABLE_SCHEMA = SCHEMA() AND TABLE_NAME LIKE '" + table.toUpperCase() + "__WORK'", (rs) ->
+                             "WHERE TABLE_SCHEMA = SCHEMA() AND TABLE_NAME LIKE ?", (rs) ->
          {
             found[0] = true;
-         });
+         }, args);
          
          if (!found[0])
          {

=== modified file 'src/com/goldencode/p2j/persist/AbstractTempTable.java'
--- old/src/com/goldencode/p2j/persist/AbstractTempTable.java	2022-10-06 08:18:44 +0000
+++ new/src/com/goldencode/p2j/persist/AbstractTempTable.java	2022-10-25 08:24:17 +0000
@@ -2442,11 +2442,11 @@
       sb.append(defBuffer.getTable());
       sb.append(" where ");
       sb.append(TemporaryBuffer.MULTIPLEX_FIELD_NAME);
-      sb.append(" = ");
-      sb.append(defBuffer.getMultiplexID());
+      sb.append(" = ?");
+      Object[] args = new Object[] {defBuffer.getMultiplexID()};
       try
       {
-         Object res = persistence.getSingleSQLResult(sb.toString(), null);
+         Object res = persistence.getSingleSQLResult(sb.toString(), args);
          if (res != null)
          {
             return true;

=== modified file 'src/com/goldencode/p2j/persist/BufferImpl.java'
--- old/src/com/goldencode/p2j/persist/BufferImpl.java	2022-10-10 09:11:45 +0000
+++ new/src/com/goldencode/p2j/persist/BufferImpl.java	2022-10-25 08:24:36 +0000
@@ -8732,12 +8732,13 @@
          .append(Buffer.ORIGIN_ROWID_FIELD).append("=NULL, ")
          .append(Buffer.AFTER_ROWID_FIELD).append("=NULL")
          .append(" where ")
-         .append(TemporaryBuffer.MULTIPLEX_FIELD_NAME).append(" = ").append(afterBuf.getMultiplexID());
+         .append(TemporaryBuffer.MULTIPLEX_FIELD_NAME).append(" = ?");
       
+      Object[] args = new Object[] {afterBuf.getMultiplexID()};
       try
       {
          boolean noUndo = !beforeBuf.isUndoable();
-         int cnt = persistence.executeSQL(buf.toString(), null, noUndo);
+         int cnt = persistence.executeSQL(buf.toString(), args, noUndo);
          afterBuf.pruneSessionCache();
          if (log.isLoggable(Level.FINE))
          {

=== modified file 'src/com/goldencode/p2j/persist/FastCopyHelper.java'
--- old/src/com/goldencode/p2j/persist/FastCopyHelper.java	2022-10-08 21:58:19 +0000
+++ new/src/com/goldencode/p2j/persist/FastCopyHelper.java	2022-10-25 08:24:56 +0000
@@ -811,7 +811,9 @@
    private static void restartSequence(Persistence persistence, String sequenceName, Long start) 
    throws PersistenceException
    {
-      persistence.executeSQL("alter sequence " + sequenceName + " restart with " + start);
+      Object[] args = new Object[] {start};
+      String stmt = persistence.getDialect().getSequenceSetValString(sequenceName);
+      persistence.executeSQL(stmt, args);
    }
    
    /**

=== modified file 'src/com/goldencode/p2j/persist/TemporaryBuffer.java'
--- old/src/com/goldencode/p2j/persist/TemporaryBuffer.java	2022-10-20 00:31:48 +0000
+++ new/src/com/goldencode/p2j/persist/TemporaryBuffer.java	2022-10-25 08:25:39 +0000
@@ -4566,11 +4566,11 @@
          // then update the flag for the after buffer:
          hql = new HQLExpression("update ");
          hql.append(getDMOImplementationName());
-         hql.append(" set _rowState = ").append(Integer.toString(Buffer.ROW_CREATED));
-         hql.append(" where ").append(MULTIPLEX_FIELD_NAME).append(" = ");
-         hql.append(Integer.toString(getMultiplexID()));
+         hql.append(" set _rowState = ?");
+         hql.append(" where ").append(MULTIPLEX_FIELD_NAME).append(" = ?");
          hql.append(" and (_rowState is null or _rowState = 0)");
-         persistence.deleteOrUpdate(hql.toFinalExpression(), null, getEntityName(), !isUndoable());
+         Object[] args = new Object[] {Integer.toString(Buffer.ROW_CREATED), Integer.toString(getMultiplexID())};
+         persistence.deleteOrUpdate(hql.toFinalExpression(), args, getEntityName(), !isUndoable());
       }
       catch (PersistenceException exc)
       {
@@ -5429,9 +5429,10 @@
       
       try
       {
+         Object[] args = new Object[] {getMultiplexID()};
          String sql = "select count(*) from " + getTable() + 
-                      " where " + MULTIPLEX_FIELD_NAME + " = " + getMultiplexID();
-         Long res = getPersistence().getSingleSQLResult(sql, null);
+                      " where " + MULTIPLEX_FIELD_NAME + " = ?";
+         Long res = getPersistence().getSingleSQLResult(sql, args);
          return res.intValue();
       
       }
@@ -7526,11 +7527,12 @@
       {
          if (!full)
          {
+            Object[] multiplexArgs = new Object[] {multiplexID};
             // execute a simple query to determine if there is any record in this virtual table
             String checkStmt = 
                   "select tt." + Session.PK + " from " + table + " tt " +
-                  "where tt." + MULTIPLEX_FIELD_NAME + " = " + multiplexID + " limit 1";
-            Long id = persistence.getSingleSQLResult(checkStmt, null);
+                  "where tt." + MULTIPLEX_FIELD_NAME + " = ?" + " limit 1";
+            Long id = persistence.getSingleSQLResult(checkStmt, multiplexArgs);
             full = (id == null);
          }
          

=== modified file 'src/com/goldencode/p2j/persist/dialect/Dialect.java'
--- old/src/com/goldencode/p2j/persist/dialect/Dialect.java	2022-08-17 00:05:18 +0000
+++ new/src/com/goldencode/p2j/persist/dialect/Dialect.java	2022-10-26 07:25:16 +0000
@@ -718,6 +718,25 @@
    public abstract String getSequenceSetValString(String sequenceName, long newVal);
    
    /**
+    * Generate the appropriate select statement to reset the value of a sequence.
+    * 
+    * @param   sequenceName
+    *          The name of the sequence.
+    *
+    * @return  Dialect-specific string to set the current value of the sequence, or {@code null}
+    *          if not supported.
+    */
+   public abstract String getSequenceSetValString(String sequenceName);
+   
+   /**
+    * Generate the appropriate select statement to reset the value of a sequence.
+    * 
+    * @return  Dialect-specific string to set the current value of the sequence, or {@code null}
+    *          if not supported.
+    */
+   public abstract String getSequenceSetValString();
+   
+   /**
     * Generate the appropriate select statement to retrieve the next value of a sequence.
     * 
     * @param   sequenceName
@@ -738,6 +757,17 @@
    public abstract String getSequenceCurrValString(String sequenceName);
    
    /**
+    * Generate the appropriate select statement to retrieve the current value of a sequence.
+    *
+    * @return  Dialect-specific string to query the sequence, or {@code null} if not supported.
+    */
+   public String getSequenceCurrValString()
+   {
+      throw new IllegalStateException(
+               "Current value of a sequence cannot be retrieved using prepared statements.");
+   }
+   
+   /**
     * Returns {@code true} if this dialect fully support the sequences as 4GL language (most important:
     * bounded values, cycle). If not fully supported, additional code is needed in P2J sequence class
     * implementation to fix this.

=== modified file 'src/com/goldencode/p2j/persist/dialect/MariaDbDialect.java'
--- old/src/com/goldencode/p2j/persist/dialect/MariaDbDialect.java	2022-09-12 10:01:50 +0000
+++ new/src/com/goldencode/p2j/persist/dialect/MariaDbDialect.java	2022-10-26 07:25:22 +0000
@@ -879,6 +879,37 @@
    }
    
    /**
+    * Generate the appropriate select statement to reset the value of a sequence.
+    *
+    * @param   sequenceName
+    *          The name of the sequence.
+    *
+    * @return  Dialect-specific string to set the current value of the sequence, or {@code null}
+    *          if not supported.
+    *
+    * @see  <a href="https://mariadb.com/kb/en/setval/">SETVAL() Function</a>
+    */
+   @Override
+   public String getSequenceSetValString(String sequenceName)
+   {
+      return "select setval(" + sequenceName + ", ?)";
+   }
+   
+   /**
+    * Generate the appropriate select statement to reset the value of a sequence.
+    *
+    * @return  Dialect-specific string to set the current value of the sequence, or {@code null}
+    *          if not supported.
+    *
+    * @see  <a href="https://mariadb.com/kb/en/setval/">SETVAL() Function</a>
+    */
+   @Override
+   public String getSequenceSetValString()
+   {
+      return "select setval(?, ?)";
+   }
+   
+   /**
     * Generate the appropriate select statement to retrieve the next value of a sequence.
     *
     * @param   sequenceName

=== modified file 'src/com/goldencode/p2j/persist/dialect/P2JH2Dialect.java'
--- old/src/com/goldencode/p2j/persist/dialect/P2JH2Dialect.java	2022-08-23 08:40:08 +0000
+++ new/src/com/goldencode/p2j/persist/dialect/P2JH2Dialect.java	2022-10-26 07:25:29 +0000
@@ -761,6 +761,35 @@
    }
    
    /**
+    * Generate the appropriate select statement to reset the value of a 
+    * sequence.
+    * 
+    * @param   sequenceName
+    *          The name of the sequence.
+    *
+    * @return  Dialect-specific string to query the sequence, or
+    *          <code>null</code> if not supported.
+    */
+   @Override
+   public String getSequenceSetValString(String sequenceName)
+   {
+      return "alter sequence " + sequenceName + " restart with ?";
+   }
+   
+   /**
+    * Generate the appropriate select statement to reset the value of a 
+    * sequence.
+    *
+    * @return  Dialect-specific string to query the sequence, or
+    *          <code>null</code> if not supported.
+    */
+   @Override
+   public String getSequenceSetValString()
+   {
+      throw new IllegalStateException("Can't reset value of a sequence with prepared statement in H2");
+   }
+   
+   /**
     * Generate the appropriate select statement to retrieve the current 
     * value of a sequence.
     * 
@@ -777,6 +806,21 @@
       return "select current_value from information_schema.sequences " +
              "where upper(sequence_name) = '" + sequenceName.toUpperCase() + "'";
    }
+   
+   /**
+    * Generate the appropriate select statement to retrieve the current 
+    * value of a sequence.
+    *
+    * @return  Dialect-specific string to query the sequence, or
+    *          <code>null</code> if not supported.
+    */
+   @Override
+   public String getSequenceCurrValString()
+   {
+      // this feature is not supported by H2 directly, use a workaround
+      return "select current_value from information_schema.sequences " +
+             "where upper(sequence_name) = ?";
+   }
 
    /**
     * Returns <code>true</code> if this dialect fully support the sequences as

=== modified file 'src/com/goldencode/p2j/persist/dialect/P2JPostgreSQLDialect.java'
--- old/src/com/goldencode/p2j/persist/dialect/P2JPostgreSQLDialect.java	2022-08-17 00:05:18 +0000
+++ new/src/com/goldencode/p2j/persist/dialect/P2JPostgreSQLDialect.java	2022-10-26 07:25:36 +0000
@@ -1103,6 +1103,33 @@
    
    /**
     * Generate the appropriate select statement to retrieve the next value of a sequence.
+    * 
+    * @param   sequenceName
+    *          The name of the sequence.
+    *
+    * @return  Dialect-specific string to query the sequence, or
+    *          <code>null</code> if not supported.
+    */
+   @Override
+   public String getSequenceSetValString(String sequenceName)
+   {
+      return "select setval('" + sequenceName + "', ?)";
+   }
+   
+   /**
+    * Generate the appropriate select statement to retrieve the next value of a sequence.
+    *
+    * @return  Dialect-specific string to query the sequence, or
+    *          <code>null</code> if not supported.
+    */
+   @Override
+   public String getSequenceSetValString()
+   {
+      return "select setval(?, ?)";
+   }
+   
+   /**
+    * Generate the appropriate select statement to retrieve the next value of a sequence.
     *
     * @param   sequenceName
     *          The name of the sequence to be queried.

=== modified file 'src/com/goldencode/p2j/persist/dialect/P2JSQLServer2008Dialect.java'
--- old/src/com/goldencode/p2j/persist/dialect/P2JSQLServer2008Dialect.java	2022-08-20 00:45:13 +0000
+++ new/src/com/goldencode/p2j/persist/dialect/P2JSQLServer2008Dialect.java	2022-10-26 07:25:42 +0000
@@ -958,6 +958,31 @@
    }
    
    /**
+    * Generate the appropriate select statement to reset the value of a sequence.
+    *
+    * @param   sequenceName
+    *          The name of the sequence.
+    *
+    * @return  Returning {@code null} since this dialect does not support sequences.
+    */
+   @Override
+   public String getSequenceSetValString(String sequenceName)
+   {
+      return null;
+   }
+   
+   /**
+    * Generate the appropriate select statement to reset the value of a sequence.
+    *
+    * @return  Returning {@code null} since this dialect does not support sequences.
+    */
+   @Override
+   public String getSequenceSetValString()
+   {
+      return null;
+   }
+   
+   /**
     * Generate the appropriate select statement to retrieve the next value of a sequence.
     *
     * @param   sequenceName

=== modified file 'src/com/goldencode/p2j/persist/dialect/P2JSQLServer2012Dialect.java'
--- old/src/com/goldencode/p2j/persist/dialect/P2JSQLServer2012Dialect.java	2021-03-18 11:47:13 +0000
+++ new/src/com/goldencode/p2j/persist/dialect/P2JSQLServer2012Dialect.java	2022-10-25 09:17:53 +0000
@@ -457,6 +457,21 @@
    }
    
    /**
+    * Generate the appropriate select statement to retrieve the current value of a sequence.
+    *
+    * @return  Dialect-specific string to query the sequence.
+    */
+   @Override
+   public String getSequenceCurrValString()
+   {
+      // the cast is needed because the column is of 'variant' datatype.
+      // the sql driver does not handle it and reports the following error: 
+      // 08S01 The "variant" data type is not supported.
+      return "select cast(current_value as bigint) " +
+             "from sys.sequences where name = ?";
+   }
+   
+   /**
     * Generate the appropriate select statement to retrieve the next value of a sequence.
     *
     * @param   sequenceName

=== modified file 'src/com/goldencode/p2j/persist/dirty/DefaultDirtyShareManager.java'
--- old/src/com/goldencode/p2j/persist/dirty/DefaultDirtyShareManager.java	2020-10-14 21:06:19 +0000
+++ new/src/com/goldencode/p2j/persist/dirty/DefaultDirtyShareManager.java	2022-10-25 08:26:44 +0000
@@ -784,7 +784,7 @@
             }
             
             String hql = "delete from " + entity + 
-                         " where " + DatabaseManager.PRIMARY_KEY + " = " + id;
+                         " where " + DatabaseManager.PRIMARY_KEY + " = ?";
             Session session = null;
             boolean inTx = false;
             
@@ -792,8 +792,11 @@
             {
                session = new Session(dirtyDatabase);
                inTx = session.beginTransaction();
+               
                Query query = Session.createQuery(hql);
+               query.setParameter(0, id);
                query.executeUpdate(session);
+               
                session.commit();
             }
             catch (PersistenceException exc)

=== modified file 'src/com/goldencode/p2j/persist/meta/TransactionTableUpdater.java'
--- old/src/com/goldencode/p2j/persist/meta/TransactionTableUpdater.java	2022-06-30 16:56:06 +0000
+++ new/src/com/goldencode/p2j/persist/meta/TransactionTableUpdater.java	2022-10-25 08:26:57 +0000
@@ -197,6 +197,7 @@
          // drop all records that are no more valid
          StringBuilder buf = new StringBuilder(
                "delete from " + TRANS_TABLE + " where not trans_num in (");
+         List<Object> args = new ArrayList<>();
          Iterator<Integer> it = transactions.values().iterator();
          for (int i = 0; it.hasNext(); i++)
          {
@@ -205,10 +206,11 @@
                buf.append(',');
             }
             
-            buf.append(it.next());
+            args.add(it.next());
+            buf.append('?');
          }
          buf.append(')');
-         int delCounter = p.executeSQL(buf.toString());
+         int delCounter = p.executeSQL(buf.toString(), args.toArray());
          if (LOG.isLoggable(Level.FINE))
          {
             LOG.log(Level.FINE, "Dropped " + delCounter + " old _trans records from " + dbName);

=== modified file 'src/com/goldencode/p2j/persist/sequence/H2SequenceHandler.java'
--- old/src/com/goldencode/p2j/persist/sequence/H2SequenceHandler.java	2020-09-06 23:15:41 +0000
+++ new/src/com/goldencode/p2j/persist/sequence/H2SequenceHandler.java	2022-10-25 08:27:18 +0000
@@ -140,12 +140,13 @@
       
       Persistence persistence = ConnectionManager.getPersistence(ldbName);
       Dialect dialect = persistence.getDialect();
-      String strQuery = dialect.getSequenceCurrValString(seqName);
+      Object[] args = new Object[] {seqName};
+      String strQuery = dialect.getSequenceCurrValString();
       int64 ret;
       
       try
       {
-         ret = getResultValue(persistence.getSingleSQLResult(strQuery, null));
+         ret = getResultValue(persistence.getSingleSQLResult(strQuery, args));
       }
       catch (PersistenceException pe)
       {
@@ -365,11 +366,12 @@
       
       Persistence persistence = ConnectionManager.getPersistence(ldbName);
       Dialect dialect = persistence.getDialect();
-      String strQuery = dialect.getSequenceSetValString(seqName, newValFixed);
+      Object[] args = new Object[] {newValFixed};
+      String strQuery = dialect.getSequenceSetValString(seqName);
       
       try
       {
-         persistence.executeSQL(strQuery);
+         persistence.executeSQL(strQuery, args);
       }
       catch (PersistenceException pe)
       {

=== modified file 'src/com/goldencode/p2j/persist/sequence/MariaDbSequenceHandler.java'
--- old/src/com/goldencode/p2j/persist/sequence/MariaDbSequenceHandler.java	2022-08-20 00:45:13 +0000
+++ new/src/com/goldencode/p2j/persist/sequence/MariaDbSequenceHandler.java	2022-10-26 07:26:33 +0000
@@ -270,11 +270,12 @@
       
       Persistence persistence = ConnectionManager.getPersistence(ldbName);
       Dialect dialect = persistence.getDialect();
-      String setCrtValQuery = dialect.getSequenceSetValString(seqName, newVal);
+      Object[] args = new Object[] {seqName, newVal};
+      String setCrtValQuery = dialect.getSequenceSetValString();
       
       try
       {
-         persistence.getSingleSQLResult(setCrtValQuery, null);
+         persistence.getSingleSQLResult(setCrtValQuery, args);
       }
       catch (PersistenceException pe)
       {

=== modified file 'src/com/goldencode/p2j/persist/sequence/PostgreSQLSequenceHandler.java'
--- old/src/com/goldencode/p2j/persist/sequence/PostgreSQLSequenceHandler.java	2020-09-06 23:15:41 +0000
+++ new/src/com/goldencode/p2j/persist/sequence/PostgreSQLSequenceHandler.java	2022-10-26 07:26:46 +0000
@@ -281,11 +281,12 @@
       
       Persistence persistence = ConnectionManager.getPersistence(ldbName);
       Dialect dialect = persistence.getDialect();
-      String setCrtValQuery = dialect.getSequenceSetValString(seqName, newVal);
+      Object[] args = new Object[] {seqName, newVal};
+      String setCrtValQuery = dialect.getSequenceSetValString();
       
       try
       {
-         persistence.getSingleSQLResult(setCrtValQuery, null);
+         persistence.getSingleSQLResult(setCrtValQuery, args);
       }
       catch (PersistenceException pe)
       {

=== modified file 'src/com/goldencode/p2j/report/ReportWorker.java'
--- old/src/com/goldencode/p2j/report/ReportWorker.java	2021-12-14 16:48:41 +0000
+++ new/src/com/goldencode/p2j/report/ReportWorker.java	2022-10-25 08:28:44 +0000
@@ -453,29 +453,37 @@
          
          // read back the id that was autogenerated
          ResultSet rs = stmtReportInsert.getGeneratedKeys();
+         PreparedStatement stmt = null;
          rs.next();
          rpt.id = rs.getLong(1);
+         List<Object> args = new ArrayList<>();
          
          if (processTags && rpt.tags != null && !rpt.tags.isEmpty())
          {
-            StringBuilder buf = new StringBuilder("select id, name from tag where name in('");
+            StringBuilder buf = new StringBuilder("select id, name from tag where name in(");
             Iterator<String> iter = rpt.tags.iterator();
             for (int i = 0; iter.hasNext(); i++)
             {
                if (i > 0)
                {
-                  buf.append("', '");
+                  buf.append(", ");
                }
                String tag = iter.next();
                tag.replaceAll("\'", "\\\'");
-               buf.append(tag);
+               buf.append("?");
+               args.add(tag);
             }
-            buf.append("')");
+            buf.append(")");
             String sql = buf.toString();
             
             Map<String, Long> tagMap = new HashMap<>();
-            Statement stmt = connection.createStatement();
-            rs = stmt.executeQuery(sql);
+            stmt = connection.prepareStatement(sql);
+            for (int i = 0; i < args.size(); i++)
+            {
+               stmt.setObject(i + 1, args.get(i));
+            }
+            
+            rs = stmt.executeQuery();
             while (rs.next())
             {
                long tid = rs.getLong(1);
@@ -509,6 +517,16 @@
                stmtRptTagInsert.clearParameters();
             }
          }
+         
+         if (rs != null && !rs.isClosed())
+         {
+            rs.close();
+         }
+         
+         if (stmt != null && !stmt.isClosed())
+         {
+            stmt.close();
+         }
       }
       
       return rpt.id;

=== modified file 'src/com/goldencode/p2j/report/server/ReportApi.java'
--- old/src/com/goldencode/p2j/report/server/ReportApi.java	2022-08-23 08:40:08 +0000
+++ new/src/com/goldencode/p2j/report/server/ReportApi.java	2022-10-26 07:29:25 +0000
@@ -745,17 +745,20 @@
     */
    private static void applyFileFilter(Connection conn, Long profileId, long sessionId)
    {
-      try (Statement stmt = conn.createStatement())
+      PreparedStatement stmt = null;
+      ResultSet rs = null;
+      try
       {
          String sql;
-         ResultSet rs;
          
          if (profileId != null)
          {
             // if profileId is null, the active_file was just created and is already empty;
             // otherwise, delete all its records in preparation for re-population with the new
             // filter profile's data
-            stmt.execute("delete from active_file where sid = " + sessionId);
+            stmt = conn.prepareStatement("delete from active_file where sid = ?");
+            stmt.setObject(1, sessionId);
+            stmt.executeUpdate();
          }
          
          // Query file specs and types for the provided file filter profile; we will compose a
@@ -763,7 +766,7 @@
          // If provided profile id was null, get the default profile.
          
          int i;
-         
+         int type = 0;
          // wildcard path specs first
          
          if (profileId == null)
@@ -776,10 +779,25 @@
          {
             sql = "select f.spec from file_filter f " +
                   "join filter_profile p on p.id = f.pid " +
-                  "where p.id = " + profileId + " and f.wild = true";
-         }
-         rs = stmt.executeQuery(sql);
-         
+                  "where p.id = ?" + " and f.wild = true";
+            type = 1;
+         }
+         
+         if (stmt != null && !stmt.isClosed())
+         {
+            stmt.close();
+         }
+         
+         stmt = conn.prepareStatement(sql);
+         if (type == 1)
+         {
+            stmt.setObject(1, profileId);
+         }
+         
+         type = 0;
+         rs = stmt.executeQuery();
+
+         List<Object> args = new ArrayList<>();
          StringBuilder buf = new StringBuilder("insert into active_file (fid, sid) ");
          for (i = 0; rs.next(); i++)
          {
@@ -792,10 +810,10 @@
             
             buf.append("select distinct(f.id), ");
             buf.append(sessionId);
-            buf.append(" from file f join ast_map a on a.fid = f.id where f.name like '");
-            buf.append(dbs.escapeLikeRValue(spec));
-            buf.setCharAt(buf.length() - 1, '%');
-            buf.append("'");
+            buf.append(" from file f join ast_map a on a.fid = f.id where f.name like ?");
+            String arg1 = dbs.escapeLikeRValue(spec);
+            arg1 = arg1.substring(0, arg1.length() - 1) + '%';
+            args.add(arg1);
          }
          
          if (profileId == null)
@@ -808,9 +826,28 @@
          {
             sql = "select f.spec from file_filter f " +
                   "join filter_profile p on p.id = f.pid " +
-                  "where p.id = " + profileId + " and f.wild = false";
-         }
-         rs = stmt.executeQuery(sql);
+                  "where p.id = ?" + " and f.wild = false";
+            type = 1;
+         }
+         
+         if (rs != null && !rs.isClosed())
+         {
+            rs.close();
+         }
+         
+         if (stmt != null && !stmt.isClosed())
+         {
+            stmt.close();
+         }
+         
+         stmt = conn.prepareStatement(sql);
+         if (type == 1)
+         {
+            stmt.setObject(1, profileId);
+         }
+         
+         type = 0;
+         rs = stmt.executeQuery();
          
          int j = 0;
          for (; rs.next(); i++)
@@ -833,9 +870,7 @@
                buf.append(", ");
             }
             
-            buf.append("'");
-            buf.append(spec);
-            buf.append("'");
+            args.add(spec);
             
             if (++j == 100)
             {
@@ -850,8 +885,23 @@
          }
          
          sql = buf.toString();
-         
-         stmt.execute(sql);
+         if (rs != null && !rs.isClosed())
+         {
+            rs.close();
+         }
+         
+         if (stmt != null && !stmt.isClosed())
+         {
+            stmt.close();
+         }
+         
+         stmt = conn.prepareStatement(sql);
+         for (int k = 0; k < args.size();k++)
+         {
+            stmt.setObject(k + 1, args.get(k));
+         }
+         
+         stmt.execute();
          int uc = stmt.getUpdateCount();
          System.out.println("applyActiveFile update count: " + uc);
          
@@ -873,6 +923,25 @@
          
          throw new RuntimeException(exc);
       }
+      finally
+      {
+         try
+         {
+            if (rs != null && !rs.isClosed())
+            {
+               rs.close();
+            }
+            
+            if (stmt != null && !stmt.isClosed())
+            {
+               stmt.close();
+            }
+         }
+         catch (SQLException e)
+         {
+            e.printStackTrace();
+         }
+      }
    }
    
    /**
@@ -2513,28 +2582,32 @@
       buf.append("insert into search_history ");
       buf.append("select * from (select next value for seq_search_history_pk, '");
       buf.append(criteria);
-      buf.append("' ) x where not exists (select 1 from search_history where criteria = '");
-      buf.append(criteria);
-      buf.append("')");
+      buf.append("' ) x where not exists (select 1 from search_history where criteria = ?)");
+      Object histArg = criteria;
       String sqlInsSrchHist = buf.toString();
       
       // compose sql to insert into user_search table, if not already present
       buf.setLength(0);
       buf.append("insert into user_search select * from (select ");
       buf.append(user.getId());
-      buf.append(" as u, select id from search_history where criteria = '");
-      buf.append(criteria);
-      buf.append("' as s) x where exists (select 1 from search_history where criteria = '");
-      buf.append(criteria);
-      buf.append("') and not exists (select 1 from user_search where uid = x.u and sid = x.s)");
+      buf.append(" as u, select id from search_history where criteria = ?");
+      buf.append(" as s) x where exists (select 1 from search_history where criteria = ?");
+      buf.append(") and not exists (select 1 from user_search where uid = x.u and sid = x.s)");
+      Object usrArg = criteria;
       String sqlInsUsrSrch = buf.toString();
       
-      try (Statement stmt = conn.createStatement())
-      {
-         // we use Statement instead of PreparedStatement here because we need a substitution
-         // parameter in the select clauses of each statement, which H2 does not allow
-         stmt.execute(sqlInsSrchHist);
-         stmt.execute(sqlInsUsrSrch);
+      //tested with H2 1.4.200 and prepared statements now work with subselects
+      try (PreparedStatement stmt = conn.prepareStatement(sqlInsSrchHist))
+      {
+         stmt.setObject(1, histArg);
+         stmt.execute();
+      }
+      
+      try (PreparedStatement stmt = conn.prepareStatement(sqlInsUsrSrch))
+      {
+         stmt.setObject(1, usrArg);
+         stmt.setObject(2, usrArg);
+         stmt.execute();
       }
    }
    

