1

将变量绑定到本机查询时出错。EclipseLink(JPA 2.1)

 String sql = "ALTER ROLE ?1 WITH ENCRYPTED PASSWORD 'xxx'"; //(not working)
 //String sql = "ALTER ROLE ? WITH ENCRYPTED PASSWORD 'xxx'"; (not working)

 Query query = em.createNativeQuery(sql);

 String text = txtUsername.getText();


 query.setParameter(1, text);

 em.getTransaction().begin();


 int executeUpdate = query.executeUpdate();
 em.getTransaction().commit();

内部异常:org.postgresql.util.PSQLException:错误:“$1”位置或附近的语法错误:12 错误代码:0 线程“AWT-EventQueue-0”中的异常 javax.persistence.PersistenceException:异常 [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd):org.eclipse.persistence.exceptions.DatabaseException 调用:ALTER ROLE?WITH ENCRYPTED PASSWORD 'xxx' bind => [1 parameter bound] 查询:DataModifyQuery(sql="ALTER ROLE ? WITH ENCRYPTED PASSWORD 'xxx'") 内部异常:org.postgresql.util.PSQLException:错误:在或附近出现语法错误"$1" 位置:12 错误代码:0 调用:ALTER ROLE ? 使用加密密码“xxx”

4

1 回答 1

0

用户名和密码不能在此查询中参数化。另一种方法是编写一个存储的函数并调用该函数。我在网上找到的可以修改以满足您需求的商店功能是:

CREATE OR REPLACE FUNCTION save_user(
in_username text,
in_password TEXT) returns bool
SET datestyle = 'ISO, YMD' -- needed due to legacy code regarding datestyles
AS $$
DECLARE

    stmt text;
    t_is_role bool;
BEGIN
    -- WARNING TO PROGRAMMERS:  This function runs as the definer and runs
    -- utility statements via EXECUTE.
    -- PLEASE BE VERY CAREFUL ABOUT SQL-INJECTION INSIDE THIS FUNCTION.

   PERFORM rolname FROM pg_roles WHERE rolname = in_username;
   t_is_role := found;

   IF t_is_role is true and t_is_user is false and in_pls_import is false THEN
      RAISE EXCEPTION 'Duplicate user';
    END IF;

    if t_is_role and in_password is not null then
            execute 'ALTER USER ' || quote_ident( in_username ) ||
                 ' WITH ENCRYPTED PASSWORD ' || quote_literal (in_password)
                 || $e$ valid until $e$ ||
                  quote_literal(now() + '1 day'::interval);
    elsif  t_is_role is false THEN
        -- create an actual user
            execute 'CREATE USER ' || quote_ident( in_username ) ||
                 ' WITH ENCRYPTED PASSWORD ' || quote_literal (in_password)
                 || $e$ valid until $e$ || quote_literal(now() + '1 day'::interval);
   END IF;

   return true;

END;
$$ language 'plpgsql' SECURITY DEFINER;
于 2018-08-07T14:59:38.403 回答