我有一种情况需要删除字符'。'来自VARCHAR在特定表中具有唯一性约束。我更喜欢在SQL上通过自定义应用程序代码执行此操作。我有改变的逻辑,但我正在努力克服如何克服VARCHAR的唯一性约束。
这是我的测试表:
CREATE TABLE [dbo].[TableName] (
[TableNameID] INT IDENTITY (1, 1) NOT NULL,
[TableInfo] VARCHAR (128) NOT NULL,
CONSTRAINT [unq_TableName] UNIQUE NONCLUSTERED ([TableInfo] ASC)
)
这是执行替换的逻辑(不处理唯一性约束):
UPDATE TableName
SET TableInfo = REPLACE(TableInfo, '.', '_')
WHERE TableInfo LIKE '%.%'
我正在尝试克服使用以下数据集创建的测试:
TableNameID | TableInfo
-------------------------
1 | Test
2 | Test.
3 | Test_
4 | Test__
对此的任何帮助将不胜感激。
答案 0 :(得分:1)
应该是独一无二的吗?如果答案是“是”,那么你必须以某种方式弄清楚如何去除数据的重复数据。在您的示例中,您如何处理ID 3?您将使用TableInfo ='Test_'创建两个记录。你必须开发一些组合或消除其中一种的方法。
如果答案为“否”,则只需删除约束。
答案 1 :(得分:0)
你可以这样做:
您可以使用多个计数创建另一个查询以查找重复项,并根据需要使用它们。
这是一个例子:
UPDATE TableToUpdate
SET columnToUpdate = REPLACE(columnToUpdate, '.', '')
FROM ( SELECT COUNT(*) AS Count ,
ID
FROM TableToUpdate
GROUP BY columnToUpdate
HAVING ( COUNT(*) < 2 )
) AS QueryData
WHERE tableToUpdate.ID = QueryData.ID
答案 2 :(得分:0)
如果您知道要更新的行的PK,则此代码有效: -
declare @unique varchar(50)
set @unique = ''
while 1=1 begin
set @unique+='_'
update t set
t.TableInfo = replace(t.TableInfo, '.', @unique)
from dbo.tablename t
where t.TableNameID=2 --t.tableinfo like '%.%'
and not exists(
select *
from dbo.TableName csq
where csq.TableInfo = replace(t.TableInfo, '.', @unique)
)
if @@rowcount=1
break
end
代码很脆弱,如果例如TableInfo列的宽度不足以通过附加多个下划线来创建唯一键,则会失败。
将光标枚举到需要更新的行的记录集上 - 然后为每个PK调用此代码应该是微不足道的(或将其转换为UDF并使用cross apply
调用它)。
我必须更加努力地思考如何使其基于工作集。我睡觉时可能会回答不同的答案。
答案 3 :(得分:0)
谢谢胡安。你的帖子激励了我,让我思考计数。
我想出了以下内容(不像你的那样紧凑,但它有效)。我仍然需要处理“可能”长度问题,但我可以解决这个问题。
WHILE EXISTS (SELECT 1 FROM TableName WHERE TableInfo LIKE '%.%')
BEGIN
DECLARE @oldInfo VARCHAR(128)
SET @oldInfo = (SELECT TOP 1 TableInfo FROM TableName WHERE TableInfo LIKE '%.%')
DECLARE @newInfo VARCHAR(128)
SET @newInfo = REPLACE(@oldInfo, '.', '_')
DECLARE @count VARCHAR(128)
SET @count = (SELECT COUNT(*) FROM TableName WHERE TableInfo LIKE @newInfo + '%')
IF @count > 0
BEGIN
IF (LENGTH(@newInfo) + LENGTH(@count) <= 128)
BEGIN
UPDATE TableName
SET TableInfo = @newInfo + @count
WHERE TableInfo = @oldInfo
END
END
ELSE
BEGIN
UPDATE TableName
SET TableInfo = @newInfo
WHERE TableInfo = @oldInfo
END
END