SQL 或在 Oracle 数据库中有条件地插入或更新的过程
SQL or procedure to conditionally insert or update in Oracle database
我在 SQL 和程序方面没有太多动手实践。我需要一个迁移脚本,其中我需要根据其他两个 table 中的数据更新或插入一个 table。
Organization:
id name pid
1 org1 null
2
org2 null
3
org3 1
4
org4 2
Org_Channel:
org_id channel
1 CH_100
2
CH_101
Organization table 具有父子自引用关系。 (如果是父级,则为 pid null)。 Org_Channel 是仅 父级 组织的映射 table。
现在我有第三个tableOrg_Settings,我需要在上面两个table的基础上迁移数据。这里的每条记录都表示一个组织 ID、一个以频道名称为前缀的设置名称(对于子 org.this 将是父 org.channel)和一个标志。我需要一个迁移 SQL 脚本/程序来启用设置 Sign_On 作为 'Y' 每个组织
现在的table是这样的:
Org_Settings:
org_id s_name enabled
1 CH_100_Sign_On N
1 CH_100_X_O Y
4 CH_101_Sign_On Y
现在 Org_Settings 可能包含也可能不包含每个组织的条目。我还需要迁移,如果 Sign_On 存在条目,则需要更新 enabled = Y。结果将是:
Org_Settings:
org_id s_name enabled
1 CH_100_Sign_On Y
2 CH_101_Sign_On Y
3 CH_100_Sign_On Y
4 CH_101_Sign_On Y
我可以想到像这样的伪代码:
for i in each org
var pid = getPid(i)
var id = (null == pid) ? i : pid
var channel = getChannel(id);
var sname = channel + "_Sign_On"
if(settingsEntryExists(i, sname))
updateSettingsEnable(i, sname, 'Y')
else
insertSettings(i, sname, 'Y')
试试这个 MERGE INTO
语句。我不明白如果条目存在则更新为 'Y' 以及如果条目不存在则插入 'Y' 背后的逻辑。是不是和简单的插入一样?还是我错过了什么? .如果缺少一些信息来澄清我上面的问题,您可以稍微调整此查询。
MERGE
INTO Org_Settings d
USING ( select
org.id org_id,
ch.channel||
'_Sign_On' s_name ,
'Y' enabled
FROM
Organization org
JOIN Org_Channel ch ON NVL(org.pid,id) = ch.org_id
)s
ON ( d.org_id = s.org_id
AND d.s_name = s.s_name )
WHEN MATCHED THEN
UPDATE SET d.enabled = 'Y'
WHEN NOT MATCHED THEN
INSERT
(org_id,s_name,enabled
) VALUES
(s.org_id,s.s_name,s.enabled
);
我在 SQL 和程序方面没有太多动手实践。我需要一个迁移脚本,其中我需要根据其他两个 table 中的数据更新或插入一个 table。
Organization:
id name pid
1 org1 null
2 org2 null
3 org3 1
4 org4 2Org_Channel:
org_id channel
1 CH_100
2 CH_101
Organization table 具有父子自引用关系。 (如果是父级,则为 pid null)。 Org_Channel 是仅 父级 组织的映射 table。
现在我有第三个tableOrg_Settings,我需要在上面两个table的基础上迁移数据。这里的每条记录都表示一个组织 ID、一个以频道名称为前缀的设置名称(对于子 org.this 将是父 org.channel)和一个标志。我需要一个迁移 SQL 脚本/程序来启用设置 Sign_On 作为 'Y' 每个组织
现在的table是这样的:
Org_Settings:
org_id s_name enabled
1 CH_100_Sign_On N
1 CH_100_X_O Y
4 CH_101_Sign_On Y
现在 Org_Settings 可能包含也可能不包含每个组织的条目。我还需要迁移,如果 Sign_On 存在条目,则需要更新 enabled = Y。结果将是:
Org_Settings:
org_id s_name enabled
1 CH_100_Sign_On Y
2 CH_101_Sign_On Y
3 CH_100_Sign_On Y
4 CH_101_Sign_On Y
我可以想到像这样的伪代码:
for i in each org
var pid = getPid(i)
var id = (null == pid) ? i : pid
var channel = getChannel(id);
var sname = channel + "_Sign_On"
if(settingsEntryExists(i, sname))
updateSettingsEnable(i, sname, 'Y')
else
insertSettings(i, sname, 'Y')
试试这个 MERGE INTO
语句。我不明白如果条目存在则更新为 'Y' 以及如果条目不存在则插入 'Y' 背后的逻辑。是不是和简单的插入一样?还是我错过了什么? .如果缺少一些信息来澄清我上面的问题,您可以稍微调整此查询。
MERGE
INTO Org_Settings d
USING ( select
org.id org_id,
ch.channel||
'_Sign_On' s_name ,
'Y' enabled
FROM
Organization org
JOIN Org_Channel ch ON NVL(org.pid,id) = ch.org_id
)s
ON ( d.org_id = s.org_id
AND d.s_name = s.s_name )
WHEN MATCHED THEN
UPDATE SET d.enabled = 'Y'
WHEN NOT MATCHED THEN
INSERT
(org_id,s_name,enabled
) VALUES
(s.org_id,s.s_name,s.enabled
);