无法从Java调用存储过程,该过程接受Postgres复杂类型为输入

问题描述 投票:0回答:1

是我的类型

CREATE TYPE integration.mycustom_type AS (
    beam float8,
    call_sign varchar(255),
    draft float8,
    dwt int4,
    vessel_type varchar(255),
    engine_builder varchar(255),
    engine_design varchar(255),
    engine_hp float8,
    engine_kwt float8,
    engine_model varchar(255),
    engines_number int4,
    flag varchar(255),
    speed_laden float8,
    geared varchar(255),
    grt float8,
    beneficial_owner_capital varchar(255),
    hull_number varchar(255),
    ice_level varchar(255),
    imo int4
    );

贝洛是我的Java代码

private static PGobject convertVesselToPGObject(Vessel vessel) {
        try {
            PGobject pgObject = new PGobject();
            pgObject.setType("integration.alphaliner_vessel_type");

            // Correct null handling
            String value = String.format(
                    "(%f, '%s', %f, %d, '%s', '%s', '%s', %f, %f, '%s', %d, '%s', %f, '%s', %f, '%s', '%s', '%s', %d )",
                    vessel.vesselBeam != null ? vessel.vesselBeam : 0.0,
                    vessel.vesselCallSign != null && !vessel.vesselCallSign.isEmpty()
                            ? vessel.vesselCallSign : "NULL",
                    vessel.vesselDraft != null ? vessel.vesselDraft : 0.0,
                    vessel.vesselDwt != null ? vessel.vesselDwt : 0,

                    vessel.vesselType != null && !vessel.vesselType.isEmpty()
                            ? vessel.vesselType : "NULL",
                    vessel.engineBuilder != null && !vessel.engineBuilder.isEmpty()
                            ? vessel.engineBuilder : "NULL",
                    vessel.engineDesign != null && !vessel.engineDesign.isEmpty()
                            ? vessel.engineDesign : "NULL",
                    Objects.requireNonNullElse(vessel.engineHp, 0.0),
                    Objects.requireNonNullElse(vessel.engineKwt, 0.0),

                    vessel.engineModel != null && !vessel.engineModel.isEmpty()
                            ? vessel.engineModel : "NULL",
                    Objects.requireNonNullElse(vessel.enginesNumber, 0),
                    Objects.requireNonNullElse(vessel.vesselFlag, ""),
                    Objects.requireNonNullElse(vessel.vesselSpeedLaden, 0.0),
                    vessel.vesselGeared != null && !vessel.vesselGeared.isEmpty()
                            ? vessel.vesselGeared : "NULL",

                    Objects.requireNonNullElse(vessel.vesselGrt, 0.0),
                    vessel.vesselBeneficialOwnerCapital != null && !vessel.vesselBeneficialOwnerCapital.isEmpty()
                            ? vessel.vesselBeneficialOwnerCapital : "NULL",
                    vessel.vesselHullNumber != null && !vessel.vesselHullNumber.isEmpty()
                            ? vessel.vesselHullNumber : "NULL", // Handle empty string as NULL
                    vessel.vesselIceLevel != null && !vessel.vesselIceLevel.isEmpty()
                            ? vessel.vesselIceLevel : "NULL",
                    Objects.requireNonNullElse(vessel.vesselImo, 0)
            );
            System.out.println("Generated PGObject value: " + value);
            pgObject.setValue(value);
            return pgObject;
        } catch (Exception e) {
            throw new RuntimeException("Error converting Vessel to PGObject", e);
        }
    }

贝洛是我打电话给sp

的方式
try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
             PreparedStatement stmt = conn.prepareStatement(sql)) {

            // Convert Java List<Vessel> to a PostgreSQL compatible array of composite type
            Array vesselArray = conn.createArrayOf("integration.alphaliner_vessel_type", vessels.stream()
                    .map(VesselDataProcessor::convertVesselToPGObject)
                    .toArray(PGobject[]::new));

            System.out.println(vesselArray);

            // Set the array parameter
            stmt.setArray(1, vesselArray);

            // Execute the stored procedure
            stmt.execute();
            System.out.println("Stored Procedure executed successfully!");

贝洛是我要通过的示例数据

"VesselBeam": 43, "VesselCallSign": "", "VesselDraft": 15, "VesselDwt": 85558, "EngineBuilder": "", "EngineDesign": "", "EngineHp": null, "EngineKwt": null, "EngineModel": "", "EnginesNumber": null, "VesselExNames": [], "VesselFlag": "", "VesselSpeedLaden": 21.9, "VesselGeared": "no", "VesselLiftingGear": [], "VesselGrt": 123, "VesselHullNumber": "", "VesselIceLevel": "", "VesselImo": 123, "VesselType": "cc"
当我尝试执行此操作并尝试击中SP时,我要低于错误

org.postgresql.util.PSQLException: ERROR: malformed record literal: "(43.000000.....) Detail: Too few columns. Where: unnamed portal parameter $1 = '...'
有人可以帮助我解决这个问题吗?任何帮助将不胜感激。谢谢
    

我试图在我的本地重新创建它,而且工作正常。
import java.sql.*;
import org.postgresql.util.PGobject;
import java.util.List;
import java.util.ArrayList;

public class StoredProcedureCaller {

    public static void main(String[] args) {
        Connection conn = null; //
        try {
            // Establish the connection to the database
            // Example connection - make sure to replace with your actual connection details
             conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/my_db", "my_username", "password");

            // Create a list of Vessel objects (fill in with your data)
            List<Vessel> vessels = new ArrayList<>();
            vessels.add(new Vessel(30.5, "CALL123", 12.5, 50000, "Cargo", "MAN", "Diesel", 5000.0, 3700.0,
                    "ModelX", 2, "USA", 16.2, "Yes", 70000.0, "OwnerCorp", "HULL123456", "Polar", 987654321));

            // Create PostgreSQL array of composite types
            Array vesselArray = createVesselArray(conn, vessels);

            // Call the stored procedure
            String sql = "CALL integration.process_(?);";
            try (PreparedStatement stmt = conn.prepareStatement(sql)) {
                // Set the array parameter for the stored procedure
                stmt.setArray(1, vesselArray);

                // Execute the stored procedure
                stmt.executeUpdate();
                System.out.println("Stored procedure executed successfully.");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if (conn != null) {
                    conn.close(); // Close the connection
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    // Helper method to create an array of the composite type
    private static Array createVesselArray(Connection conn, List<Vessel> vessels) throws SQLException {
        Object[] vesselObjects = new Object[vessels.size()];

        for (int i = 0; i < vessels.size(); i++) {
            Vessel vessel = vessels.get(i);

            PGobject vesselPG = new PGobject();
            vesselPG.setType("integration.alphaliner_vessel_type");

            // Ensure numeric values are passed without quotes
            vesselPG.setValue(String.format(
                    "(%f, '%s', %f, %d, '%s', '%s', '%s', %f, %f, '%s', %d, '%s', %f, '%s', %f, '%s', '%s', '%s', %d)",
                    vessel.getBeam(), vessel.getCallSign(), vessel.getDraft(), vessel.getDwt(),
                    vessel.getVesselType(), vessel.getEngineBuilder(), vessel.getEngineDesign(),
                    vessel.getEngineHp(), vessel.getEngineKwt(), vessel.getEngineModel(),
                    vessel.getEnginesNumber(), vessel.getFlag(), vessel.getSpeedLaden(),
                    vessel.getGeared(), vessel.getGrt(), vessel.getBeneficialOwnerCapital(),
                    vessel.getHullNumber(), vessel.getIceLevel(), vessel.getImo()));

            vesselObjects[i] = vesselPG; // Add PGobject to array
        }

        return conn.createArrayOf("integration.alphaliner_vessel_type", vesselObjects);
    }

}
我的船只是我的船只。

public class Vessel { private double beam; private String callSign; private double draft; private int dwt; private String vesselType; private String engineBuilder; private String engineDesign; private double engineHp; private double engineKwt; private String engineModel; private int enginesNumber; private String flag; private double speedLaden; private String geared; private double grt; private String beneficialOwnerCapital; private String hullNumber; private String iceLevel; private int imo; public Vessel(double beam, String callSign, double draft, int dwt, String vesselType, String engineBuilder, String engineDesign, double engineHp, double engineKwt, String engineModel, int enginesNumber, String flag, double speedLaden, String geared, double grt, String beneficialOwnerCapital, String hullNumber, String iceLevel, int imo) { this.beam = beam; this.callSign = callSign; this.draft = draft; this.dwt = dwt; this.vesselType = vesselType; this.engineBuilder = engineBuilder; this.engineDesign = engineDesign; this.engineHp = engineHp; this.engineKwt = engineKwt; this.engineModel = engineModel; this.enginesNumber = enginesNumber; this.flag = flag; this.speedLaden = speedLaden; this.geared = geared; this.grt = grt; this.beneficialOwnerCapital = beneficialOwnerCapital; this.hullNumber = hullNumber; this.iceLevel = iceLevel; this.imo = imo; } public double getBeam() { return beam; } public void setBeam(double beam) { this.beam = beam; } public String getCallSign() { return callSign; } public void setCallSign(String callSign) { this.callSign = callSign; } public double getDraft() { return draft; } public void setDraft(double draft) { this.draft = draft; } public int getDwt() { return dwt; } public void setDwt(int dwt) { this.dwt = dwt; } public String getVesselType() { return vesselType; } public void setVesselType(String vesselType) { this.vesselType = vesselType; } public String getEngineBuilder() { return engineBuilder; } public void setEngineBuilder(String engineBuilder) { this.engineBuilder = engineBuilder; } public String getEngineDesign() { return engineDesign; } public void setEngineDesign(String engineDesign) { this.engineDesign = engineDesign; } public double getEngineHp() { return engineHp; } public void setEngineHp(double engineHp) { this.engineHp = engineHp; } public double getEngineKwt() { return engineKwt; } public void setEngineKwt(double engineKwt) { this.engineKwt = engineKwt; } public String getEngineModel() { return engineModel; } public void setEngineModel(String engineModel) { this.engineModel = engineModel; } public int getEnginesNumber() { return enginesNumber; } public void setEnginesNumber(int enginesNumber) { this.enginesNumber = enginesNumber; } public String getFlag() { return flag; } public void setFlag(String flag) { this.flag = flag; } public double getSpeedLaden() { return speedLaden; } public void setSpeedLaden(double speedLaden) { this.speedLaden = speedLaden; } public String getGeared() { return geared; } public void setGeared(String geared) { this.geared = geared; } public double getGrt() { return grt; } public void setGrt(double grt) { this.grt = grt; } public String getBeneficialOwnerCapital() { return beneficialOwnerCapital; } public void setBeneficialOwnerCapital(String beneficialOwnerCapital) { this.beneficialOwnerCapital = beneficialOwnerCapital; } public String getHullNumber() { return hullNumber; } public void setHullNumber(String hullNumber) { this.hullNumber = hullNumber; } public String getIceLevel() { return iceLevel; } public void setIceLevel(String iceLevel) { this.iceLevel = iceLevel; } public int getImo() { return imo; } public void setImo(int imo) { this.imo = imo; } }

java postgresql spring-jdbc
1个回答
0
投票
CREATE TYPE integration.alphaliner_vessel_type AS ( beam float8, call_sign varchar(255), draft float8, dwt int4, vessel_type varchar(255), engine_builder varchar(255), engine_design varchar(255), engine_hp float8, engine_kwt float8, engine_model varchar(255), engines_number int4, flag varchar(255), speed_laden float8, geared varchar(255), grt float8, beneficial_owner_capital varchar(255), hull_number varchar(255), ice_level varchar(255), imo int4 ); CREATE OR REPLACE PROCEDURE integration.process_(IN p_data integration.alphaliner_vessel_type[]) LANGUAGE plpgsql SECURITY DEFINER AS $procedure$ DECLARE -- Declare variables here if needed BEGIN RAISE NOTICE 'Procedure get called'; END; $procedure$;

我的输出是我的输出。

我在您的实施中发现了多个缺陷。
1)。首先,您尚未提及要运行的SQL查询。我添加了该查询,其中有以下字符串

String sql = "CALL integration.process_(?);";

现在没有单引号(double for double for double值和%d)等数字值等数值等值 格式用于int值)。 enter image description here弦值,例如呼号,船只类似等,仍然以单引号('%s'格式)封闭。

第二,您的所有数字字段都应该为


最新问题
© www.soinside.com 2019 - 2025. All rights reserved.