我们的开发数据库每周重置一次。我发现自己在周一早上花了一个小时左右的时间(比如今天)将所有测试数据插入到各个脚本的各种表格和数据库中。
首先,当然,我必须验证这些表没有我的数据:
SELECT Count(*) FROM Table1 WHERE INVLINK LIKE '190701050630%'
如果没有返回任何行,我可以插入我的记录:
INSERT INTO Table1
( UPC, CATALOG, VENDOR, ADD_DATE, INVLINK, WHO_ADDED, TYPE, VENDOR_ID)
VALUES
('011010017760', 'LOVE', 'TES', '20150609', '19070105063041', 9388, 'P', '1013'),
('011010017760', 'HATE', 'TES', '20150609', '19070105063042', 9388, 'P', '1013'),
('011010017760', 'FEAR', 'TES', '20150609', '19070105063043', 9388, 'P', '1013')
我想知道的是,如果有一种语法允许我在计数为零时调用insert命令。
以下是我尝试的内容,但这不会通过SQL调用执行。
SELECT CASE WHEN SELECT Count(*) = 0
THEN
INSERT INTO TBLBARTRANS
( UPC, CATALOG, VENDOR, ADD_DATE, INVLINK, WHO_ADDED, TYPE, VENDOR_ID)
VALUES
('011010017760', 'LOVE', 'TES', '20150609', '19070105063041', 9388, 'P', '1013'),
('011010017760', 'HATE', 'TES', '20150609', '19070105063042', 9388, 'P', '1013'),
('011010017760', 'FEAR', 'TES', '20150609', '19070105063043', 9388, 'P', '1013')
END
FROM Table1
WHERE INVLINK LIKE '190701050630%'
我可以调用INSERT,SELECT和UPDATE命令,但我不是数据库管理员。因此,创建一个存储过程来运行这些15到20个脚本对我来说不是一个选择。
答案 0 :(得分:3)
您需要更改它,以便您只“选择”那些不存在的值:
INSERT INTO TBLBARTRANS
(UPC, CATALOG, VENDOR, ADD_DATE, INVLINK, WHO_ADDED, TYPE, VENDOR_ID)
select *
from (
values
('011010017760', 'LOVE', 'TES', '20150609', '19070105063041', 9388, 'P', '1013'),
('011010017760', 'HATE', 'TES', '20150609', '19070105063042', 9388, 'P', '1013'),
('011010017760', 'FEAR', 'TES', '20150609', '19070105063043', 9388, 'P', '1013')
) as t (UPC, CATALOG, VENDOR, ADD_DATE, INVLINK, WHO_ADDED, TYPE, VENDOR_ID)
where not exists (select 1
from TBLBARTRANS tbl
where tbl.invlink = t.invlink);
最内部选择会创建一个“虚拟”表,其中包含您要插入的值:
select *
from (
values
('011010017760', 'LOVE', 'TES', '20150609', '19070105063041', 9388, 'P', '1013'),
('011010017760', 'HATE', 'TES', '20150609', '19070105063042', 9388, 'P', '1013'),
('011010017760', 'FEAR', 'TES', '20150609', '19070105063043', 9388, 'P', '1013')
) as t(UPC, CATALOG, VENDOR, ADD_DATE, INVLINK, WHO_ADDED, TYPE, VENDOR_ID)
上面简单地“模拟”了要插入的值的源表。条件
where not exists (select 1
from TBLBARTRANS tbl
where tbl.invlink = t.invlink);
然后,将仅从“虚拟”表中返回表TBLBARTRANS
中尚不存在的那些行。然后将该select语句的结果插入到目标表中。
我在DB2 LUW上对此进行了测试 - 不确定所有 DB2版本是否支持我使用它的values()
子句。
Henrik建议的DB2 MERGE
是另一种选择:
merge into TBLBARTRANS tg
using table (
values
('011010017760', 'LOVE', 'TES', '20150609', '19070105063041', 9388, 'P', '1013'),
('011010017760', 'HATE', 'TES', '20150609', '19070105063042', 9388, 'P', '1013'),
('011010017760', 'FEAR', 'TES', '20150609', '19070105063043', 9388, 'P', '1013')
) t (UPC, CATALOG, VENDOR, ADD_DATE, INVLINK, WHO_ADDED, TYPE, VENDOR_ID) on (t.INVLINK = tg.invlink)
when not matched then
insert (UPC, CATALOG, VENDOR, ADD_DATE, INVLINK, WHO_ADDED, TYPE, VENDOR_ID)
values (t.UPC, t.CATALOG, t.VENDOR, t.ADD_DATE, t.INVLINK, t.WHO_ADDED, t.TYPE, t.VENDOR_ID);
无关,但是:
add_date
是date
还是varchar
列?如果它是varchar
列,那么您应该更改它。将日期存储为字符串几乎总是一个非常糟糕的主意。
VENDOR_ID
也是如此:您为该列提供的字符串值非常类似于数字。在varchar列中存储数字也几乎总是一个坏主意。
答案 1 :(得分:2)
您没有说出您所使用的DB2版本和平台,但很可能MERGE
语句可能就是您要查找的内容。 MERGE is documented here
您可以根据结果指定搜索条件并插入/更新。根据您的要求,您只需要插入,更新,选择...
的权限答案 2 :(得分:2)
除了其他人所说的,您可以考虑将数据移动到csv文件并加载/获取它们,而不是将它们插入到sql语句中。
加载将拒绝那些违反主键的行,并加载其余行。 Ingest为您提供更多控制,您甚至可以使用如上所述的合并语句。
即使您不想使用这些实用程序中的任何一个,您也可以考虑将数据与实际命令分开。例如,您可以创建一个循环遍历多个表的实用程序脚本,读取该表的数据文件并动态构造insert语句。所需的所有信息都在目录中。
编辑:
另一个想法是创建包含要添加到实际表的数据的备份表。我假设通过重置你的意思是恢复备份。如果备份包含备份表,则可以在每个星期一插入,合并,从这些表中加载游标。缺点是,当数据发生变化时,您必须进行新的备份。