【问题标题】:Calling a stored procedure in PostgreSQL from Java从 Java 调用 PostgreSQL 中的存储过程
【发布时间】:2013-03-07 04:00:25
【问题描述】:

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

【问题讨论】:

    标签: java sql postgresql stored-procedures plpgsql


    【解决方案1】:

    问题

    • 最重要的是,LOOP 中的查询是无稽之谈。您从carinstance 中选择行,但所有条件都在rec 上。这会多次选择所有行。

    • 一个END 太多了。 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 可能是冗余的,也可能不是冗余的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-05
      • 2013-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-11
      • 2023-03-05
      相关资源
      最近更新 更多