有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

sql从Java调用PostgreSQL中的存储过程

我已经编写了一个我想用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 found打印一个空值。我真的很想在这里得到一些帮助


共 (1) 个答案

  1. # 1 楼答案

    问题

    • 最重要的是,LOOP中的查询毫无意义。您可以从carinstance中选择行,但所有条件都在rec上。多次选择所有

    • 太多了FOR没有END,只有LOOP

    • 每当你想在plpgsql中使用显式游标时,就到此为止。很可能你做错了。FOR循环仍然有一个隐式游标

    • 别惹mixed case identifiers without double quotes。我将所有标识符转换为小写

    • 您可以使用一个简单的查询,分散在一个光标和另一个查询上。这一切都可以简单得多

    解决方案

    请尝试以下简单的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可能是多余的,也可能不是多余的