我正试图弄清楚如何实现下面描述的alter脚本。如果insert/select的话,我已经熟悉了基础知识,但这要复杂得多。
我有一个遗留表,需要将其数据移动到一个包含更多列的新表中。新表已经向一些选定用户公开,这些用户可能已经手动移动了公共数据。
因此,对于LegacyTable中的每一行:
- 查看它是否已存在于NewImprovedTable中(通过检查两个表中存在的字符串字段是否匹配)
- 如果没有,请将其复制到NewImprovedTable
- 无论它是刚刚自动复制到NewImprovedTable,还是以前由用户复制。。。
- 自动填充NewImprovedTable中的新名称字段(必须是唯一的,例如"Legacy1"、"Legacy2"等)
- 在NewImprovedTable中设置IsLegacy标志
我需要在MSSQL和Oracle中实现这一点,但一旦我在其中一个上找到了逻辑,我就可以在另一个上找出语法。
我确定的解决方案(在SQL Server中-仍然需要移植到Oracle):
IF NOT EXISTS(SELECT 1
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'NewImprovedTable'
AND COLUMN_NAME = 'legacyFlg')
BEGIN
ALTER TABLE [NewImprovedTable]
ADD legacyFlg TINYINT NULL
ALTER TABLE [LegacyTable]
ADD improvedId INT NULL
END
GO
IF NOT EXISTS(SELECT 1 FROM ImprovedTable WHERE legacyFlg = 1)
BEGIN
MERGE ImprovedTable AS TARGET
USING LegacyTable AS SOURCE
ON (TARGET.stringField = SOURCE.stringField)
WHEN NOT MATCHED THEN
INSERT (name, <other columns>, legacyFlg)
VALUES('Legacy' + SOURCE.stringField, <other column values>, 1)
WHEN MATCHED THEN
UPDATE SET TARGET.legacyFlg = 1;
END
GO
IF NOT EXISTS(SELECT 1 FROM LegacyTable WHERE improvedId <> 0)
BEGIN
MERGE LegacyTable AS TARGET
USING NewImprovedTable AS SOURCE
ON (SOURCE.stringField = TARGET.stringField)
WHEN MATCHED THEN
UPDATE SET TARGET.improvedId = SOURCE.pId;
END
GO
您可以尝试使用它,其中"input"是您试图确认是否已经存在的字符串:
SELECT * FROM`NewImprovedTable` WHERE `Variable`='input'
如果找到任何匹配,这将返回整行,如果没有,它将返回null,你可以使用该
至于唯一ID字段,您需要在启用自动递增选项的表上创建主键,例如
CREATE TABLE Persons
(
P_Id INT NOT NULL AUTO_INCREMENT,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
PRIMARY KEY (P_Id)
)
在最后一个例子中,p_Id被设置为一个自动增量变量,每次您装箱一个新行时,它都会用一个唯一的数字自动填充该列。你应该检查这个页面
http://www.w3schools.com/sql/sql_primarykey.asp