SQL Server DB に「オブジェクト」というテーブルがあります。オブジェクトの名前 (文字列) が含まれています。「Objects」テーブルの別のテーブル「NewObjects」に挿入する必要がある新しいオブジェクトの名前のリストがあります。以降、この操作を「インポート」と呼びます。
レコード名が「オブジェクト」に既に存在する場合、「NewObjects」から「オブジェクト」にインポートする各レコードに一意の名前を生成する必要があります。この新しい名前は、古い名前に対して「NewObjects」テーブルに保存されます。
DECLARE @NewObjects TABLE
(
...
Name varchar(20),
newName nvarchar(20)
)
「NewObjects」からインポートするレコードごとに一意の名前を生成するストアド プロシージャを実装しました。ただし、1000 レコード (「NewObjects」内) のパフォーマンスには満足できません。コードを最適化するための支援が必要です。以下は実装です。
PROCEDURE [dbo].[importWithNewNames] @args varchar(MAX)
-- Sample of @args is like 'A,B,C,D' (a CSV string)
...
DECLARE @NewObjects TABLE
(
_index int identity PRIMARY KEY,
Name varchar(20),
newName nvarchar(20)
)
-- 'SplitString' function: this is a working implementation which is right now not concern of performance
INSERT INTO @NewObjects (Name)
SELECT * from SplitString(@args, ',')
declare @beg int = 1
declare @end int
DECLARE @oldName varchar(10)
-- get the count of the rows
select @end = MAX(_index) from @NewObjects
while @beg <= @end
BEGIN
select @oldName = Name from @NewObjects where @beg = _index
Declare @nameExists int = 0
-- this is our constant. We cannot change
DECLARE @MAX_NAME_WIDTH int = 5
DECLARE @counter int = 1
DECLARE @newName varchar(10)
DECLARE @z varchar(10)
select @nameExists = count(name) from Objects where name = @oldName
...
IF @nameExists > 0
BEGIN
-- create name based on pattern 'Fxxxxx'. Example: 'F00001', 'F00002'.
select @newName = 'F' + REPLACE(STR(@counter, @MAX_NAME_WIDTH, 0), ' ', '0')
while EXISTS (select top 1 1 from Objects where name = @newName)
OR EXISTS (select top 1 1 from @NewObjects where newName = @newName)
BEGIN
select @counter = @counter + 1
select @newName = 'F' + REPLACE(STR(@counter, @MAX_NAME_WIDTH, 0), ' ', '0')
END
select top 1 @z = @newName from Objects
update @NewObjects
set newName = @z where @beg = _index
END
select @beg = @beg + 1
END
-- finally, show the new names generated
select * from @NewObjects