我似乎无法正确地从存储函数中读取UDT
postgres JDBC驱动程序。这是一些示例代码:

CREATE TYPE u_country AS ENUM ('Brazil', 'England', 'Germany')

CREATE TYPE u_street_type AS (
  street VARCHAR(100),
  no VARCHAR(30)
)

CREATE TYPE u_address_type AS (
  street u_street_type,
  zip VARCHAR(50),
  city VARCHAR(50),
  country u_country,
  since DATE,
  code INTEGER
)

CREATE TABLE t_author (
  id INTEGER NOT NULL PRIMARY KEY,
  first_name VARCHAR(50),
  last_name VARCHAR(50) NOT NULL,
  date_of_birth DATE,
  year_of_birth INTEGER,
  address u_address_type
)

INSERT INTO t_author VALUES (1, 'George', 'Orwell',
TO_DATE('1903-06-25', 'YYYY-MM-DD'), 1903, ROW(ROW('Parliament Hill',
'77'), 'NW31A9', 'Hampstead', 'England', '1980-01-01', null))
INSERT INTO t_author VALUES (2, 'Paulo', 'Coelho',
TO_DATE('1947-08-24', 'YYYY-MM-DD'), 1947, ROW(ROW('Caixa Postal',
'43.003'), null, 'Rio de Janeiro', 'Brazil', '1940-01-01', 2))

CREATE FUNCTION p_enhance_address2 (address OUT u_address_type)
AS $$
BEGIN
        SELECT t_author.address
        INTO address
        FROM t_author
        WHERE first_name = 'George';
END;
$$ LANGUAGE plpgsql;

现在上面的方法在postgres中非常有效。我也可以选择UDT
列t_author.address,直接使用SQL SELECT语句。但是当
我通过JDBC从存储函数p_enhance_address2中选择,得到一个
奇怪的行为。我尝试了以下两种调用方案:
connection.prepareStatement("select * from p_enhance_address2()");
connection.prepareCall("{ call p_enhance_address2(?) }");
// the latter with an output parameter registered

两个调用方案都会导致相同的行为(实际上
CallableStatement就是从函数中选择。
似乎有两个非常明显的问题:
嵌套的UDT结构完全搞砸了获取结果。这个
我从JDBC得到的是:
PreparedStatement stmt = connection.prepareStatement(
  "select * from p_enhance_address2()");
ResultSet rs = stmt.executeQuery();

while (rs.next()) {
  System.out.println("# of columns: " +
    rs.getMetaData().getColumnCount());
  System.out.println(rs.getObject(1));
}

输出:
柱数:6根
(“议会山”,77“,NW31A9)
为什么有6列?为什么UDT取错了(很多
字段丢失)
当嵌套的UDT
uústreet戋type被“夷为平地”为varchar,这将导致
假设JDBC驱动程序不支持嵌套UDT:
CREATE TYPE u_address_type AS (
  street VARCHAR(80),
  zip VARCHAR(50),
  city VARCHAR(50),
  country u_country,
  since DATE,
  code INTEGER
)

INSERT INTO t_author VALUES (1, 'George', 'Orwell',
TO_DATE('1903-06-25', 'YYYY-MM-DD'), 1903, ROW('Parliament Hill 77',
'NW31A9', 'Hampstead', 'England', '1980-01-01', null))
INSERT INTO t_author VALUES (2, 'Paulo', 'Coelho',
TO_DATE('1947-08-24', 'YYYY-MM-DD'), 1947, ROW('Caixa Postal 43.003',
null, 'Rio de Janeiro', 'Brazil', '1940-01-01', 2))

结果会是这样的:
柱数:6根
(“议会山77”,NW31A9,汉普斯特德,英格兰,1980-01-01,)
UDT记录现在看起来是正确的(从
位置1)。但结果集中仍有6列。
一些事实:
我在pgAdmin III中没有遇到这些问题
我使用PostgreSQL 90.1,用Visual C++编译生成1500, 64位
我使用postgresql-9.0-801.jdbc4.jar
有人知道怎么了吗?

最佳答案

我可以复制这个,看起来这是一个虫子。
我建议您将此发布到PostgreSQL JDBC邮件列表中,以便开发人员可以修复此问题。

关于postgresql - 如何从Postgres存储函数读取UDT,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4652651/

10-11 09:25