我正在使用HSQLDB 2.3.2,并且在尝试创建存储过程时遇到了一个奇怪的错误。
我的addresses
表:
CREATE TABLE IF NOT EXISTS addresses (
address_id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1) NOT NULL PRIMARY KEY,
address_line_1 NVARCHAR(500) NOT NULL,
address_line_2 NVARCHAR(500),
address_city NVARCHAR(100) NOT NULL,
address_postal_code NVARCHAR(25) NOT NULL,
CONSTRAINT uc_addresses UNIQUE (address_line_1, address_city)
)
填充它的插入内容:
INSERT INTO addresses (
address_line_1,
address_city,
address_postal_code
) VALUES (
'123 Test Blvd.', 'Testville', '11111'
)
我的处理:
CREATE PROCEDURE sp_get_address_by_id(
IN address_id INTEGER,
OUT address_id INTEGER,
OUT address_line_1 NVARCHAR(500),
OUT address_line_2 NVARCHAR(500),
OUT address_city NVARCHAR(100),
OUT address_postal_code NVARCHAR(25))
READS SQL DATA
BEGIN ATOMIC
SELECT
a.address_id,
a.address_line_1,
a.address_line_2,
a.address_city,
a.address_postal_code
INTO
address_id,
address_line_1,
address_line_2,
address_city,
address_postal_code
FROM
addresses a
WHERE
a.address_id = address_id;
END
当我跑步时,我得到:
Error: attempt to assign to non-updatable column
SQLState: 0U000
ErrorCode: -2500
问题:
CREATE IF NOT EXISTS
类型的声明,所以我可以一遍又一遍地运行这个脚本,如果它不存在,程序将只创建一次。会发生这种情况还是我需要更改语法来完成IF NOT EXISTS
?答案 0 :(得分:3)
根据hsqldb文档,尝试以下语法 http://hsqldb.org/doc/2.0/guide/sqlroutines-chapt.html#src_psm_assignment
SET语句用于赋值。它可以灵活使用 行或单个值。
同时将address_id
参数更改为键入INOUT
并删除重复的address_id
参数行。
CREATE PROCEDURE sp_get_address_by_id(
INOUT address_id INTEGER,
OUT address_line_1 NVARCHAR(500),
OUT address_line_2 NVARCHAR(500),
OUT address_city NVARCHAR(100),
OUT address_postal_code NVARCHAR(25))
READS SQL DATA
BEGIN ATOMIC
SET (address_id,
address_line_1,
address_line_2,
address_city,
address_postal_code)
=
(
SELECT
a.address_id,
a.address_line_1,
a.address_line_2,
a.address_city,
a.address_postal_code
FROM
addresses a
WHERE
a.address_id = address_id
);
END
如果要删除已存在的过程,可以尝试将其添加为脚本中的第一个语句,以便可以多次重新运行该脚本。您可以在documentation搜索<specific routine designator>
以获取更多信息。
DROP SPECIFIC PROCEDURE sp_get_address_by_id IF EXISTS;
答案 1 :(得分:1)
在您的程序中,您有两个具有相同名称的参数:
IN address_id INTEGER,
OUT address_id INTEGER,
当您在程序正文中提及address_id
时,可能会出现问题
你应该使用:
INOUT address_id INTEGER,
而不是这两行。
回答你的第二个问题:
为什么要在不重建过程的情况下反复运行此脚本?当某些内容发生变化时,再次运行此脚本是有意义的。
CREATE OR REPLACE PROCEDURE
答案 2 :(得分:0)
对于粉丝,如果您这样做,则会抛出相同的错误消息:
PreparedStatement selectStmt = conn.prepareStatement(query);
ResultSet rs = selectStmt.executeQuery()) {
rs.next();
rs.updateLong("column", value); // boom
一个解决方法是使用这种风格:
PreparedStatement selectStmt =
conn.prepareStatement(query, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);