我想知道更换一些数字的最有效和最安全的方法。在我的表中,我有两列:Nummer和Vater。在Nummer专栏中,我存储了文章编号。结尾为.1
的文章是'main'
文章,其余是combinations
(有时主文章不包含组合),所有具体内容都将其作为具有组合的具体产品。数字由 3个部分(由3个点(始终)分隔)组成。对所有人来说,Vater总是主要的文章编号,如下所示:
示例1:
Nummer | Vater
-------------------------------
003.10TT032.1 | 003.10TT032.1
003.10TT032.2L | 003.10TT032.1
003.10TT032.UY | 003.10TT032.1
Nummer column = varchar Vater column = varchar
我希望有可能更改前两部分n.n
例如我想说并通过sql查询发送我要替换为:9.4R53因此根据我们的示例,最终结果应如下所示:
Nummer | Vater
----------------------
9.4R53.1 | 9.4R53.1
9.4R53.2L | 9.4R53.1
9.4R53.UY | 9.4R53.1
示例2:
电流:
Nummer | Vater
-------------------------------
12.90D.1 | 12.90D.1
12.90D.089 | 12.90D.1
12.90D.2 | 12.90D.1
替换为:829.12
结果应该是:
Nummer | Vater
-------------------------------
829.12.1 | 829.12.1
829.12.089 | 829.12.1
829.12.2 | 829.12.1
我的查询如下:
示例1查询:
update temp SET Nummer = replace(Nummer, '003.10TT032.', '9.4R53.'),
Vater = replace(Vater, '003.10TT032.1', '9.4R53.1')
WHERE Vater = '003.10TT032.1'
示例2查询:
update temp SET Nummer = replace(Nummer, '12.90D.', '829.12.'),
Vater = replace(Vater, '12.90D.1', '829.12.1')
WHERE Vater = '12.90D.1 '
在我的数据库中,我有记录,因此我想确保此查询没有问题,并且没有任何可能导致错误结果的内容。请告诉您是否可以这样。
因此问题:
根据我的文章存储方式,此查询是否正常? (希望避免错误的替换,这可能会导致生产数据库数据混乱)
有更好的解决方案吗?
答案 0 :(得分:1)
回答你的问题:是的,你的解决方案是有效的,是的,有一些东西可以使它成为防弹的。使其成为防弹和可逆的是我建议在下面做的。如果你知道的话,你会睡得更好 A.回答任何愤怒的人问你的问题"你对我的产品表做了什么" B.知道你可以撤销你对此表所做的任何更改(无需恢复备份),包括其他人的错误(如错误的指示)。
因此,如果你真的必须对输出有100%的信心,我就不会一次性运行它。我建议在单独的表中准备查询,然后在动态SQL的循环中运行查询。
这有点麻烦,但您可以这样做:创建一个包含所需列的专用表(如batch_id,insert_date等)和一个名为execute_query NVARCHAR(MAX)的列。 然后通过在源表中运行需要替换的部分的select distinct来加载表(使用CHARINDEX找到第二个点 - 使CHARINDEX从第一个点的CHARINDEX开始+ 1获得第二个点)。
换句话说:您逐个准备所有查询(例如示例中的查询)并将它们存储在表格中。
如果您想要完全安全,更新查询可以包括n和n之间的源table_id。 (您在源表上使用GROUP BY构建)。如果您以后必须回答问题,这将确保您可以跟踪已更新的记录。
完成此操作后,您将运行一个循环,逐个执行每一行。 此方法的优点是跟踪您的更改 - 您还可以在准备更新查询的同时准备回滚查询。然后,您知道可以安全地还原您对产品表所做的所有更改。
永远不要截断该表,它是您的审计表。如果有人问你对产品目录做了什么,你可以回答任何问题,即使是5年后。
答案 1 :(得分:0)
这是一个单独的答案,说明如何将产品ID拆分为单独的部分 - 如果您必须更新产品ID的部分,我认为最好将其存储在单独的列中:
DECLARE @ProductRef TABLE
(ID INT IDENTITY(1,1) PRIMARY KEY CLUSTERED,
SrcNummer VARCHAR(255), DisplayNummer VARCHAR(255), SrcVater VARCHAR(255), DisplayVater VARCHAR(255),
NummerSectionA VARCHAR(255), NummerSectionB VARCHAR(255), NummerSectionC VARCHAR(255),
VaterSectionA VARCHAR(255), VaterSectionB VARCHAR(255), VaterSectionC VARCHAR(255) )
INSERT INTO @ProductRef (SrcNummer, SrcVater ) VALUES ('003.10TT032.1','003.10TT032.1')
INSERT INTO @ProductRef (SrcNummer, SrcVater ) VALUES ('003.10TT032.2L','003.10TT032.1')
INSERT INTO @ProductRef (SrcNummer, SrcVater ) VALUES ('003.10TT032.UY','003.10TT032.1')
DECLARE @Separator CHAR(1)
SET @Separator = '.'
;WITH SeparatorPosition (ID, SrcNummer, NumFirstSeparator, NumSecondSeparator, SrcVater, VatFirstSeparator, VatSecondSeparator)
AS ( SELECT
ID,
SrcNummer,
CHARINDEX(@Separator,SrcNummer,0) AS NumFirstSeparator,
CHARINDEX(@Separator,SrcNummer, (CHARINDEX(@Separator,SrcNummer,0))+1 ) AS NumSecondSeparator,
SrcVater,
CHARINDEX(@Separator,SrcVater,0) AS VatFirstSeparator,
CHARINDEX(@Separator,SrcVater, (CHARINDEX(@Separator,SrcVater,0))+1 ) AS VatSecondSeparator
FROM @ProductRef )
UPDATE @ProductRef
SET
NummerSectionA = SUB.NummerSectionA , NummerSectionB = SUB.NummerSectionB , NummerSectionC = SUB.NummerSectionC ,
VaterSectionA = SUB.VaterSectionA , VaterSectionB = SUB.VaterSectionB , VaterSectionC = SUB.VaterSectionC
FROM @ProductRef T
JOIN
(
SELECT
t.ID,
t.SrcNummer,
SUBSTRING (t.SrcNummer,0,s.NumFirstSeparator) AS NummerSectionA,
SUBSTRING (t.SrcNummer,s.NumFirstSeparator+1,(s.NumSecondSeparator-s.NumFirstSeparator-1) ) AS NummerSectionB,
RIGHT (t.SrcNummer,(LEN(t.SrcNummer)-s.NumSecondSeparator)) AS NummerSectionC,
t.SrcVater,
SUBSTRING (t.SrcVater,0,s.NumFirstSeparator) AS VaterSectionA,
SUBSTRING (t.SrcVater,s.NumFirstSeparator+1,(s.NumSecondSeparator-s.NumFirstSeparator-1) ) AS VaterSectionB,
RIGHT (t.SrcVater,(LEN(t.SrcVater)-s.NumSecondSeparator)) AS VaterSectionC
FROM @ProductRef t
JOIN SeparatorPosition s
ON t.ID = s.ID
) SUB
ON T.ID = SUB.ID
然后您只能使用正确的产品ID部分。