繁体   English   中英

从Java在PostgreSQL中调用存储过程

[英]Calling a stored procedure in PostgreSQL from Java

我已经编写了一个要在Java中调用的存储过程。 但是我认为它不能对我传递的查询执行任何操作。 以下是我的Java代码:

String QUERY_LOCATION = "select (license_plate) as test from carInst( (select     category_name from reservation where rid = ?) , (select lname from reservation where rid =  ?))";  
        //PreparedStatement check_location = null;
        PreparedStatement check_location = connection.prepareStatement(QUERY_LOCATION);
        check_location.setInt(1, rid);
        check_location.setInt(2, rid);
        rs = check_location.executeQuery();
        if (rs.next()) {
            System.out.print("Car found: "+rs.getString("test")+"\n");
            license_plate = rs.getString("test");
            update_reservation.setString(5, license_plate);

            bool = false;
        } else {
            System.out
                    .print("There is no car available\n");
        }

以下是我用PL / pgSQL(PostgreSQL)编写的存储过程:

CREATE OR REPLACE FUNCTION carInst(cname varchar(20), loc varchar(20) ) 
RETURNS TABLE (license_plate varchar(6) ) AS $$
BEGIN 
    DECLARE cur CURSOR 
        FOR SELECT carinstance.license_plate, carmodel.category_name, carinstance.lname FROM carinstance,carmodel 
            WHERE carinstance.mid = carmodel.mid ;                  
BEGIN 
    FOR rec IN cur LOOP
        RETURN QUERY SELECT distinct carinstance.license_plate FROM Carinstance 
            WHERE rec.category_name  = cname
                AND rec.lname = loc
                AND rec.license_plate=carinstance.license_plate;
        END LOOP;
    END; 
END;
$$ LANGUAGE plpgsql;

当我用Java运行代码时,print语句为找到的Car打印一个空值。 我非常感谢您的帮助。

问题

  • 最重要的是, LOOP的查询是胡说八道。 您可以选择从行carinstance ,但各方面条件都在rec 多次选择所有行。

  • 一个END太多。 FOR没有END ,只有LOOP有。

  • 每当您想使用plpgsql中的显式游标的诱惑时,请就此停下来。 可能是,您做错了。 无论如何, FOR循环都有一个隐式游标。

  • 不要弄混没有双引号的大小写混合的标识符 我将所有标识符都转换为小写。

  • 您使用一个简单的查询,分布在游标上,另一个查询。 这一切都可能更加简单。

请尝试使用以下简单的SQL函数:

CREATE OR REPLACE FUNCTION car_inst(_cname text, _loc text) 
  RETURNS TABLE (license_plate text) AS
$func$
   SELECT DISTINCT ci.license_plate
   FROM   carmodel    cm
   JOIN   carinstance ci USING (mid)
   WHERE  cm.category_name  = $1
   AND    ci.lname = $2
$func$ LANGUAGE sql;

呼叫:

"SELECT license_plate AS test FROM car_inst(
         (SELECT category_name FROM reservation WHERE rid = ?)
        ,(SELECT lname FROM reservation WHERE rid = ?))";  

或将其全部构建到您的函数中:

CREATE OR REPLACE FUNCTION car_inst(_cname text, _loc text) 
  RETURNS TABLE (license_plate text) AS
$func$
   SELECT DISTINCT ci.license_plate
   FROM   carmodel    cm
   JOIN   carinstance ci USING (mid)
   JOIN   reservation r1 ON r1.category_name = cm.category_name
   JOIN   reservation r2 ON r2.lname = ci.lname
   WHERE  r1.rid = $1
   AND    r2.rid = $2;
$func$ LANGUAGE sql;

呼叫:

"SELECT license_plate AS test FROM car_inst(? , ?)";  

切记: OUT参数license_plate在函数主体中的任何位置都可见。 因此,您必须始终对具有相同名称的列进行表限定,以防止命名冲突。

DISTINCT可能是冗余,也可能不是冗余。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM