我们可以在预准备语句(PostgreSQL)中使用DDL命令吗?

时间:2013-07-15 07:29:07

标签: java postgresql java-ee jdbc ddl

DDL命令如下:

CREATE TABLE - 创建一个包含用户提供的列名的表。

DROP TABLE - 删除所有行并从数据库中删除表定义。

ALTER TABLE - 在表格中添加或删除列。

如果有可能在PostgreSQL和Java中使用这些命令,我​​需要一些例子吗?

public boolean create(Employee employee) {

    try {

        callableStatement = openConnection().prepareCall("{call insert_employee(?,?,?)}");
        callableStatement.setInt(1, employee.getEid());
        callableStatement.setString(2, employee.getEname());
        callableStatement.setInt(3, employee.getSid());     

        i = callableStatement.execute();

        callableStatement.close();

        closeConnection();



    } catch (SQLException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return i;

}

是否有可能在这种类型中使用DDL CREATE命令?使用准备好的陈述?

3 个答案:

答案 0 :(得分:4)

是的,如果您使用EXECUTE并将其包装在FUNCTION中,则可以。函数调用允许您传递参数,在FUNCTION中使用字符串操作来修改DDL语句。最后,在FUNCTION中使用EXECUTE就是这样。以下是参数化CREATE SEQUENCE语句的简单示例...

DROP FUNCTION sf.start_mc(integer);

CREATE FUNCTION sf.start_mc(thefirst integer) RETURNS void AS $$
BEGIN
    EXECUTE format('CREATE SEQUENCE sf.mastercase START %s',thefirst);
END;

$$ LANGUAGE plpgsql;

我们使用字符串函数“format”来操作语句并包含传递给函数的参数。当然,您的SQL看起来很不寻常,特别是如果在调用它之前包含CREATE FUNCTION。这个例子来自我最近做过的数据迁移工作。在创建函数后,我们使用它:

DROP SEQUENCE sf.mastercase;

-- the following uses the above function to set the starting value of a new sequence based on the last used
-- in the widget table
select sf.start_mc((select substring("widgetId",4)::integer + 1 from widgets
where "widgetId" like 'MC-%'
order by "widgetId" desc
limit 1));

请注意,外部SELECT不会选择任何内容,它只是做一个函数调用的地方。作为参数传递的数字来自内部SELECT,它包含在括号中。更简单的电话会是

select sf.start_mc(42);

您可以在CREATEd FUNCTION中包装任何内容。但这确实意味着您陷入了PostgreSQL,并且需要将您的数据库架构和架构更改集成到您的开发过程中作为一等公民。

答案 1 :(得分:3)

你试过吗?

服务器不支持它,所以即使它似乎在客户端JDBC驱动程序中工作,我也不推荐它:

regress=> PREPARE CREATE TABLE test ( id serial primary key );
ERROR:  syntax error at or near "CREATE"
LINE 1: PREPARE CREATE TABLE test ( id serial primary key );
                ^

无论如何这样做是没有优势的,因为你不能参数化它们,所以你不能写:

CREATE TABLE ? ( ? text, ...)

然后将占位符值指定为Statement的查询参数。

在PostgreSQL中,只能准备计划的语句并在服务器端进行参数化。目前,这意味着INSERTUPDATEDELETESELECT

你需要根据PostgreSQL的lexical structure rules进行自己的字符串插值和安全引用 - 这几乎是SQL规范的引用。将"double quotes"中的所有标识符换行,并将任何文字双引号括起来,例如"these are literal ""double quotes"""作为表名these are literal "double quotes"

您想要这样做的事实表明您可能在架构中存在设计问题,并且可能需要重新思考您的工作方式。也许在dba.stackexchange.com上发布一个更详细的问题,解释你想要实现的目标和原因?

答案 2 :(得分:0)

除非您使用外界的用户输入,否则不需要使用准备好的语句。

通常,对于DDL语句,用户不知道,也不应该对内部DB Schema或模型有任何了解。

只要数据是通过安全网络传输的,我真的看不到准备语句的好处