我很想知道是否有比使用游标的方法更好/更优化的解决方案,我知道这并不是很好的性能。
基本上我的要求是检查ID是否存在许多设置,然后相应地更新或插入它们。
为此,我有:
DECLARE @UserId UNIQUEIDENTIFIER = '{PUT-GUID-HERE}'
然后我声明一个表变量,在其中添加设置名称和值,总共大约有15个。
DECLARE @SettingsToCheck TABLE (SettingName varchar(100), SettingValue varchar(100)
INSERT INTO @SettingsToCheck ('Setting1', 'Setting1 Value') --Repeat...
DECLARE @CurrentSettingName varchar(100)
DECLARE @CurrentSettingValue varchar(100)
DECLARE Settings_Cursor CURSOR FOR SELECT SettingName, SettingValue FROM @SettingsToCheck
OPEN Settings_Cursor
FETCH NEXT FROM Settings_Cursor INTO @CurrentSettingName, @CurrentSettingValue
WHILE @@FETCH_STATUS = 0
BEGIN
IF EXISTS (SELECT * FROM MyActualTable WHERE UserID = @UserId AND SettingName = @CurrentSettingName)
BEGIN
UPDATE MyActualTable SET SettingValue = @CurrentSettingValue WHERE UserID = @UserId AND SettingName = @CurrentSettingName
END
ELSE
BEGIN
INSERT INTO MyActualTableVALUES (NEWID(), @UserId, GETDATE(), @CurrentSettingName, @CurrentSettingValue)
END
FETCH NEXT FROM Settings_Cursor INTO @CurrentSettingName, @CurrentSettingValue
END
CLOSE Settings_Cursor
DEALLOCATE Settings_Cursor
我知道这个问题尚待商定,但我不知道有其他选择。
编辑:
在某些情况下,某些/所有或所有设置都已经存在。但这是一个例子。
之前:
SettingName | SettingValue
____________________________
Setting1 | Setting1Value
之后:
SettingName | SettingValue
____________________________
Setting1 | Setting1ValueUPDATED
Setting2 | NewSetting
答案 0 :(得分:1)
您可以按以下方式使用合并
DECLARE @SettingsToCheck TABLE
(
SettingName varchar(100)
,SettingValue varchar(100)
)
DECLARE @ActualTable TABLE
(
SettingName varchar(100)
,SettingValue varchar(100)
)
INSERT INTO @SettingsToCheck
VALUES
('Setting1', 'Setting1 Value') --Repeat...
,('Setting2', 'Setting2 Value')
,('Setting3', 'Setting3 Value')
,('Setting4', 'Setting45 Value')
,('Setting5', 'Setting5 Value')
,('Setting6', 'Setting6 Value')
,('Setting7', 'Setting7 Value')
INSERT INTO @ActualTable
VALUES
('Setting4', 'Setting4 Value')
MERGE INTO @ActualTable AS target
USING @SettingsToCheck AS source
ON target.SettingName = source.SettingName
WHEN MATCHED THEN
UPDATE SET target.SettingValue = source.SettingValue
WHEN NOT MATCHED BY TARGET THEN
INSERT (SettingName, SettingValue)
VALUES (source.SettingName, source.SettingValue);
Select * from @ActualTable
答案 1 :(得分:0)
我知道人们喜欢使用MERGE,但我更喜欢将他们与自己的任务分开。亚伦·伯特兰(Aaron Bertrand)在此处记录了MERGE的一些问题:https://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/, 但我不确定其中有多少仍然存在。
无论如何,这是一种选择:
CREATE TABLE #SettingsToCheck
(
SettingName varchar(100)
,SettingValue varchar(100)
)
CREATE TABLE #ActualTable
(
SettingName varchar(100)
,SettingValue varchar(100)
)
INSERT INTO #SettingsToCheck
VALUES
('Setting1', 'Setting1 Value') --Repeat...
,('Setting2', 'Setting2 Value')
,('Setting3', 'Setting3 Value')
,('Setting4', 'Setting45 Value')
,('Setting5', 'Setting5 Value')
,('Setting6', 'Setting6 Value')
,('Setting7', 'Setting7 Value')
INSERT INTO #ActualTable
VALUES
('Setting4', 'Setting4 Value')
UPDATE #ActualTable
SET SettingValue = t2.SettingValue
FROM #ActualTable t1
INNER JOIN #SettingsToCheck t2 on t1.SettingName = t2.SettingName
INSERT INTO #ActualTable(SettingName,SettingValue)
SELECT t1.SettingName,t1.SettingValue
FROM #SettingsToCheck t1
LEFT JOIN #ActualTable t2 on t1.SettingName = t2.SettingName
WHERE t2.SettingName IS NULL
select * from #ActualTable