我在java代码里面 编写了如下sql语句!
 
public class StorageDaoImpl extends BaseDao implements StorageDao {
private Connection con=null;
private PreparedStatement pstmt=null;
private ResultSet rs=null;
private String sql=null;
private String[] str={"name","price","number","makeTime","电器","食品","服装","日用品"};
private List<StorageBean> list=new ArrayList<StorageBean>();
private StorageBean sBean=null; public List<StorageBean> getStorage(int id) throws Exception {

con=this.getConnection();
if(id<5){
                 //sql语句是我如此构建的   如果直接sql="select * from storage order by name";运行能成功,
                        //但是下面这样就不可以?这是为什么?
sql="select * from storage order by ?";
pstmt=con.prepareStatement(sql);
pstmt.setString(1, str[id-1]);
}else {
sql="select * from storage where type like ?";
pstmt=con.prepareStatement(sql);
pstmt.setString(1, str[id-1]);
}

rs=pstmt.executeQuery();
while(rs.next()){
sBean=new StorageBean();
sBean.setId(rs.getInt(1));
sBean.setName(rs.getString(2));
sBean.setPrice(rs.getFloat(3));
sBean.setType(rs.getString(4));
sBean.setNumber(rs.getInt(5));
sBean.setMakeTime(rs.getString(6));
sBean.setUseDay(rs.getInt(7));
list.add(sBean);
}

return list;
}软件报的错误如下----"com.microsoft.sqlserver.jdbc.SQLServerException: 由 ORDER BY 编号 1 标识的 SELECT 项包含一个变量,作为标识列位置的表达式的一部分。按照引用列名的表达式排序时,只允许使用变量。"希望达人点化下!

解决方案 »

  1.   

    sql="select * from storage order by ?";
    如果要用PreparedStatement的话,上面的写法明显是错误的
    一个正确的写法例子如下:
    select * from storage where 字段=?
    然后设置该字段的参数值
    pstmt.setString(1, str[id-1]);
      

  2.   

    答:
    1)select * from storage order by 语句中by之后只能是变量.而你用prepareStatement的setString()实际上生成的是:select * from storage order by "name" --这是一个
    2)因此:你只好用SQL语句的拼接了,如:
     sql="select * from storage order by "+ str[id-1]);
      

  3.   


    sql="select * from storage order by ?";
                pstmt=con.prepareStatement(sql);
                pstmt.setString(1, str[id-1]);
    这里的str[id-1]是常量name,而sql要求order by接的是变量,自然报错,
    而你用sql="select * from storage order by name";时,这里的name是一个列的名字,不是常量,所以是正确的
      

  4.   

    我这里还是有一点不懂。希望能更加清晰的解释下。
    《---select * from storage order by 语句中by之后只能是变量.而你用prepareStatement的setString()实际上生成的是:select * from storage order by "name" --这是一个值 ----》 如是说需要接的是个变量 那我代码做如下改动  //这里的a  应该算变量吧  因为它的值是没有固定下来的,是根据 Str[id-1];来确定的
      //那下面 order by 后面接的就应该是个变量啊, 可是还是报错。                      
      String a=str[id-1];
      sql="select * from storage order by ?";
      //sql="select * from storage order by"+str[id-1];
      pstmt=con.prepareStatement(sql);  pstmt.setString(1,a);
    所以我想明确的是, 是不是  类似于 order by 的后面不能使用 占位符 ?
    而不是说 这后面接的应该是变量 
    我就是在这里有点糊涂了!
      

  5.   

    另外问题我解决,先感谢各位的帮助! 
    改成的确实是平凑出来的 sql语句   sql="select * from storage order by "+ str[id-1]); 
    不过还是很希望能搞清楚 到底是为什么不能那样写
      

  6.   

    select * from storage order by 语句中by之后只能是变量,这里所谓的变量是指这个量是通过参数传进来的,是不确定的,而你用String a=str[id-1];这里的a虽然是变量,但它被赋值为str[id-1]即“name",这个name是常量,是确定了的,所以不行
      

  7.   

    order by后面当然可以用占位符?
    如果你写成:public List<StorageBean> getStorage(int id) throws Exception {
            
            con=this.getConnection();
            if(id<5){
                                sql="select * from storage order by ?";
                pstmt=con.prepareStatement(sql);
                pstmt.setString(1, id);
            }else {
    就没问题,这个id就是变量