我尝试在 sybase 16.0 中运行合并查询,但失败并出现错误
SQL 错误 [102] [42000]:“(”附近的语法不正确。
merge into account_balance( id , account_name) as G
using SELECT (?, ?) AS D( id , account_name)
ON D.account_number=G.account_number
when not matched then
insert ( id , account_name) values ( D.id , D.account_name)
when matched then
update set G.id = D.id,G.account_name = D.account_name
这个错误是什么意思? sybase 16.0 版本不支持此命令,但文档另有说明。
假设 OP 使用 Sybase(现为 SAP)ASE ...
tl;dr - 文档是错误的。
Sybase ASE 文档总是有些随意; SAP 收购 Sybase 后,他们 (SAP) 成功地将“蹩脚文档”一词提升到了新的高度;举个例子,merge
声明...
中的
merge
语句的结构,但是,唉,文档存在一些问题。
第一期:into
子句中没有列列表;列引用由其他子句处理:
--------
-- replace this:
merge into account_balance( id , account_name) as G
---------
-- with this:
merge into account_balance as G
第二个问题:文档使用
?
(不太清楚)指定提供实际数据值的位置;这些是将在生成的
insert
或 update
中使用的值:--------
-- replace this:
using SELECT (?, ?)
---------
-- with this:
using SELECT (3, 'name3')
第三个问题:在
using
子句中使用派生表时,需要将派生表(也称为子查询)用括号括起来;此外,数据值不包含在括号中:
--------
-- replace this:
using SELECT (3, 'name3') AS D( id , account_name)
---------
-- with this:
using (SELECT 3, 'name3') AS D( id , account_name)
第四个问题:
on
子句中引用的列必须在
using
子句中定义(本例中为OP的派生表);在这种情况下,我们需要为连接列提供值和列引用account_number
:--------
-- replace this:
using (SELECT 3, 'name3') AS D( id , account_name)
---------
-- with this:
using (SELECT 3, 'name3', 'acct3') AS D( id , account_name, account_number)
我假设 OP 想要填充
account_number
列,因此需要扩展
insert
子句以包含 account_number
列:--------
-- replace this:
insert ( id , account_name) values ( D.id , D.account_name)
---------
-- with this:
insert ( id , account_name, account_number) values ( D.id , D.account_name, D.account_number)
将这些更改放在一起,我们得到以下
merge
声明:
merge into account_balance as G
using (SELECT 3,'name3','acct3') AS D (id,account_name,account_number)
ON D.account_number = G.account_number
when not matched then
insert ( id, account_name, account_number)
values (D.id,D.account_name,D.account_number)
when matched then
update set G.id = D.id,
G.account_name = D.account_name
试驾:创建我们的表:
create table account_balance
(id int
,account_name varchar(100)
,account_number varchar(100)
)
go
select * from account_balance
go
id account_name account_number
-- ------------ --------------
(0 rows affected)
merge
导致
insert
:merge into account_balance as G
using (SELECT 3,'name3','acct3') AS D (id,account_name,account_number)
ON D.account_number = G.account_number
when not matched then
insert ( id, account_name, account_number)
values (D.id,D.account_name,D.account_number)
when matched then
update set G.id = D.id,
G.account_name = D.account_name
go
select * from account_balance
go
id account_name account_number
-- ------------ --------------
3 name3 acct3
(1 row affected)
merge
,结果为
update
(id:3
=> 5
;账户名称:name3
=> name5
):merge into account_balance as G
using (SELECT 5,'name5','acct3') AS D (id,account_name,account_number)
ON D.account_number = G.account_number
when not matched then
insert ( id, account_name, account_number)
values (D.id,D.account_name,D.account_number)
when matched then
update set G.id = D.id,
G.account_name = D.account_name
go
select * from account_balance
go
id account_name account_number
-- ------------ --------------
5 name5 acct3
(1 row affected)
注意: 使用 ASE 16.0 SP04 PL04
进行测试