在准备好的语句中获取列名而不是值

Posted

技术标签:

【中文标题】在准备好的语句中获取列名而不是值【英文标题】:Getting column name instead of values in prepared statement 【发布时间】:2017-01-26 08:25:35 【问题描述】:

我。

这是我的一段代码:

string q="select ? from EMPLOYEE where salary > ?";

Preparedstatement pst = connectionobject.preparedstatement(q);
pst.setstring(1, "FIRST_NAME");
pst.setint(2, 10000);

当我在JTable 中打印出结果时,它会在所有行中显示FIRST_NAME

【问题讨论】:

是的,这就是你的代码正在做的事情select "FIRST_NAME" from .... 所以您的专栏FIRST_NAME 是大写字母,而工资不是?你能在桌子上做一个描述吗 您不能使用PreparedStatement 来构建动态查询,查询本身必须是固定的并且查询变量的参数。我建议编写一个 DAO 层,查询 EMPLOYEE 表中您想要的每个属性。 这可以在Hibernate 中使用setParameter 完成。 【参考方案1】:

这是不可能的,用你的方式来解决你的问题。

像这样更改您的代码:

String att = "FIRST_NAME";

string q="select " + att + " from EMPLOYEE where salary>?";

Preparedstatement pst=connectionobject.preparedstatement(q);
pst.setint(1,10000); 

如果您担心用户可以进行 SQL 注入而不是使用此解决方案

您应该检查您的列是否存在于您的表格中:

SELECT * 
    FROM information_schema.COLUMNS 
    WHERE 
        TABLE_SCHEMA = 'db_name' 
    AND TABLE_NAME = 'table_name' 
    AND COLUMN_NAME = 'column_name'

像这样:

public boolean column_exist(String att) 
    boolean succes = false;
    CreerConnection con = new CreerConnection();
    Connection connection = null;
    PreparedStatement statement = null;
    ResultSet resultat = null;
    try 
        connection = con.getConnection();

        statement = connection.prepareStatement("SELECT * \n"
                + "FROM information_schema.COLUMNS "
                + " WHERE"
                + " TABLE_SCHEMA = 'db_name'"
                + " AND TABLE_NAME = 'table_name'"
                + " AND COLUMN_NAME = ?");
        statement.setString(1, att);
        resultat = statement.executeQuery();

        if (resultat.next()) 
            succes = true;
        

     catch (SQLException e) 
        System.out.println("Exception = " + e);
     finally 
        if (statement != null) 
            try 
                statement.close();
             catch (SQLException ex) 
            
        
        if (connection != null) 
            try 
                connection.close();
             catch (SQLException ex) 
            
        
    
    return succes;

如果该列存在,那么您可以像这样继续:

if(column_exist(att))
   string q="select " + att + " from EMPLOYEE where salary>?";

   Preparedstatement pst=connectionobject.preparedstatement(q);
   pst.setint(1,10000); 

在此处了解更多信息:

mysql, Check if a column exists in a table with SQL

希望对你有帮助。

【讨论】:

【参考方案2】:

您的preparedStatement 必须生成查询:select "FIRST_NAME" from EMPLOYEE where salary > 10000 而不是select FIRST_NAME from EMPLOYEE where salary > 10000

所以它为每一行返回字符串“FIRST_NAME”。

您可以简单地使用 StringBuilder 替换第一个“?”通过您的 column_name。

【讨论】:

如果列不退出怎么办,这会导致 SQL 注入问题吗? @YCF_L :是的,我个人不会参数化选择以避免 SQL 注入,并选择我需要的每一列。但我认为这是完成这个基本 PreparedStatement 的唯一方法。 所以这样也可以String att = "FIRST_NAME"; string q="select " + att + " from EMPLOYEE where salary>?"; Preparedstatement pst=connectionobject.preparedstatement(q); pst.setint(1,10000); 它会工作,但效率不高。尽管您可以写 select FIRSTNAME where ...,但您正在进行 2 次连接 您似乎想要动态化 JTable 的显示。然后,您可以随时选择所有列并在 Java 代码中动态显示。

以上是关于在准备好的语句中获取列名而不是值的主要内容,如果未能解决你的问题,请参考以下文章

Laravel DB 选择语句。查询返回列名作为结果而不是值

如何在asp.net的GridView中按列名而不是按索引获取单元格值

您可以从大查询 SDK 中的 Select 语句中获取列名而不运行它吗

在用户定义的函数中返回列名而不是值 SQL

在 Oracle PL/SQL 中获取具有索引而不是列名的字段

SqlDataReader 按列名获取值(不是序号)