在 HSQLDB 中插入字符串
Insert String in HSQLDB
我尝试将一个字符串插入到 hsqldb 中,但它给我这个错误:
> java.sql.SQLSyntaxErrorException: user lacks privilege or object not
found: S
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCStatement.fetchResult(Unknown Source)
at org.hsqldb.jdbc.JDBCStatement.executeUpdate(Unknown Source)
列设置为 VARCHAR(50)
并且 sqlstring 是这样构建的:
String sql = "INSERT INTO Emergency Values(" + Counter.emergencyID + ","+
emergency.status +"," + "\""+ emergency.typeD +"\"" + "," + "\""+
emergency.typeB +"\"" + ","+ emergency.floorID + ")";
这就是我执行查询的方式:
Statement st = null;
st = con.createStatement(); // statements
int i = st.executeUpdate(sql); // run the query
PS:我知道我对这样的 sqlInjection 持开放态度。
编辑:值为
sql = "INSERT INTO Emergency Values(0,1,"S","IB",1)"
如果我将字符串更改为 ;
String sql = "INSERT INTO Emergency Values(" + Counter.emergencyID + ","+
emergency.status +","+ emergency.typeD +","+ emergency.typeB +","+
emergency.floorID +")";
出现同样的错误
使用 PreparedStatement
不会有问题:
String sql =
"INSERT INTO Emergency (emergency_id, status, type_d, type_b, floor_id) " +
" Values (?, ?, ?, ?, ?)";
请注意,我在 insert
语句中明确列出了列名。不这样做被认为是糟糕的编码风格。
我不得不 猜测 那些名字,因为你没有向我们展示你的 table 的定义。您 有 替换为 table 的正确列名。
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setInt(1, Counter.emergencyID);
pstmt.setInt(2, emergency.status);
pstmt.setString(3, emergency.typeD);
pstmt.setInt(4, emergency.typeB);
pstmt.setInt(5, emergency.floorID);
int i = pstmt.executeUpdate(sql); // run the query
问题的根本原因是双引号的使用不正确:"
。在 SQL 中,字符串常量必须放在单引号中。 'foobar'
是一个字符串值。双引号用于标识符 "foobar"
例如列名。
无关,但是:Counter.emergencyID
的使用让我认为您正在您的应用程序中生成(或试图生成)唯一 ID。不要那样做。使用数据库中的序列或标识列。从一开始就正确地做。对于单个用户应用程序,这可能没有什么不同,但是您无法在多个用户同时使用的应用程序中正确地实现 和 可扩展性,并发事务插入相同的 table。
我在@a_horse_with_no_name 的代码中发现了错误
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setInt(1, Counter.emergencyID);
pstmt.setInt(2, emergency.status);
pstmt.setString(3, emergency.typeD);
pstmt.setInt(4, emergency.typeB);
pstmt.setInt(5, emergency.floorID);
int i = pstmt.executeUpdate(sql); // run the query
注意最后一行,应该是
int i = pstmt.executeUpdate(); // run the query
请参考HSQLDB cryptic exception message: "feature not supported"
我知道这个问题很老了,但我 运行 遇到了同样的问题并找到了不使用 PreparedStatements 的解决方案。
INSERT INTO TypeA (id) VALUES ("Hello");
失败(用户缺乏权限或找不到对象:你好),但是
INSERT INTO TYPEA (id) VALUES ('Hello');
成功了。所以似乎不接受双引号(另见 http://www.hsqldb.org/doc/1.8/guide/ch09.html#expression-section )
我尝试将一个字符串插入到 hsqldb 中,但它给我这个错误:
> java.sql.SQLSyntaxErrorException: user lacks privilege or object not
found: S
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCStatement.fetchResult(Unknown Source)
at org.hsqldb.jdbc.JDBCStatement.executeUpdate(Unknown Source)
列设置为 VARCHAR(50)
并且 sqlstring 是这样构建的:
String sql = "INSERT INTO Emergency Values(" + Counter.emergencyID + ","+
emergency.status +"," + "\""+ emergency.typeD +"\"" + "," + "\""+
emergency.typeB +"\"" + ","+ emergency.floorID + ")";
这就是我执行查询的方式:
Statement st = null;
st = con.createStatement(); // statements
int i = st.executeUpdate(sql); // run the query
PS:我知道我对这样的 sqlInjection 持开放态度。
编辑:值为
sql = "INSERT INTO Emergency Values(0,1,"S","IB",1)"
如果我将字符串更改为 ;
String sql = "INSERT INTO Emergency Values(" + Counter.emergencyID + ","+
emergency.status +","+ emergency.typeD +","+ emergency.typeB +","+
emergency.floorID +")";
出现同样的错误
使用 PreparedStatement
不会有问题:
String sql =
"INSERT INTO Emergency (emergency_id, status, type_d, type_b, floor_id) " +
" Values (?, ?, ?, ?, ?)";
请注意,我在 insert
语句中明确列出了列名。不这样做被认为是糟糕的编码风格。
我不得不 猜测 那些名字,因为你没有向我们展示你的 table 的定义。您 有 替换为 table 的正确列名。
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setInt(1, Counter.emergencyID);
pstmt.setInt(2, emergency.status);
pstmt.setString(3, emergency.typeD);
pstmt.setInt(4, emergency.typeB);
pstmt.setInt(5, emergency.floorID);
int i = pstmt.executeUpdate(sql); // run the query
问题的根本原因是双引号的使用不正确:"
。在 SQL 中,字符串常量必须放在单引号中。 'foobar'
是一个字符串值。双引号用于标识符 "foobar"
例如列名。
无关,但是:Counter.emergencyID
的使用让我认为您正在您的应用程序中生成(或试图生成)唯一 ID。不要那样做。使用数据库中的序列或标识列。从一开始就正确地做。对于单个用户应用程序,这可能没有什么不同,但是您无法在多个用户同时使用的应用程序中正确地实现 和 可扩展性,并发事务插入相同的 table。
我在@a_horse_with_no_name 的代码中发现了错误
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setInt(1, Counter.emergencyID);
pstmt.setInt(2, emergency.status);
pstmt.setString(3, emergency.typeD);
pstmt.setInt(4, emergency.typeB);
pstmt.setInt(5, emergency.floorID);
int i = pstmt.executeUpdate(sql); // run the query
注意最后一行,应该是
int i = pstmt.executeUpdate(); // run the query
请参考HSQLDB cryptic exception message: "feature not supported"
我知道这个问题很老了,但我 运行 遇到了同样的问题并找到了不使用 PreparedStatements 的解决方案。
INSERT INTO TypeA (id) VALUES ("Hello");
失败(用户缺乏权限或找不到对象:你好),但是
INSERT INTO TYPEA (id) VALUES ('Hello');
成功了。所以似乎不接受双引号(另见 http://www.hsqldb.org/doc/1.8/guide/ch09.html#expression-section )