簡體   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