2016-12-02 21 views
1

我有如下(注意一個SQL表:使用報價,使其更易於閱讀更換多個字符的短語與縮寫列表SQL

Table1.Description 
"HOUSING,WRAP RECESSED" 
"HOUSING,ASSEMBLY 2-FEED" 
"LENS,FLUSH SUS" 

Table2.Abbreviations 
ASSY = ASSEMBLY 
FD = FEED 
FLUSH = FL 
HSG = HOUSING 
LENS = LNS  
RECESSED = REC 

我想更新,或沿着線的東西代替,並創建新表(無論是好的),Table1.Description與Table2.Abbreviations它應該是這樣的:

Table1.Description 
"HSG,WRAP REC" 
"HSG,ASSY 2-FD" 
"LNS,FL SUS" 

我這個要求,第一次海報的形式道歉,但使用該網站很多次!

+0

一種方法(不一定是最好的一個)是使用光標去通過表1的每一行,並且應用需要執行的程序執行字符串替換多次來自表2的數據直到不能進行替換。 – uncoder

+0

是否有重疊替換的可能性,例如「FOOD」變成「FD」,「FOO」變成「FU」?如果是這樣,您需要像Cappelletti博士的解決方案,在嘗試替換之前「輸入」輸入字符串。如果替換可以遞歸地發生,則會發生另一些樂趣。 「FOOD WRAP」變成「FD WRP」,「WRP」變成「RP」。你想不斷取代一路? – HABO

+0

@HABO,到目前爲止所有的方法都是*逐行*。鑑於有一個排序順序的替代品,這是沒有問題的。有人甚至可能會將某個短語替換爲其他字詞,並在其他替換後重新替換。在我的其中一個項目中,我們使用了一個帶有兩個參數的函數:帶有所有替換項的A *鍵值對* -XML和'NVARCHAR(MAX)'。我們使用這種方式進行復雜的*多級*操作,以創建模板外的CDA文檔。只要你只處理一個文件,這個工作的速度驚人地快...... – Shnugo

回答

0

嘗試這樣的::

的表格爲您的縮寫

CREATE TABLE Abbreviations (LongTerm VARCHAR(100),ShortTerm VARCHAR(10)); 
INSERT INTO Abbreviations VALUES 
('ASSEMBLY','ASSY') 
,('FEEd','FD') 
,('FLUSH','FL') 
,('HOUSING','HSG') 
,('LENS','LNS') 
,('RECESSED','REC'); 

GO 

函數做魔術

我使用臨時表來說明如何做到這一點創建一個解決方案
CREATE FUNCTION dbo.ReplaceAbbreviations(@string VARCHAR(MAX)) 
RETURNS VARCHAR(MAX) AS 
BEGIN 
    SELECT @string=REPLACE(@string,LongTerm,ShortTerm) 
    FROM Abbreviations; 

    RETURN @string; 
END 
GO 

一個表,你的字符串

CREATE TABLE YourDescription (LongDescription VARCHAR(MAX)); 
INSERT INTO YourDescription VALUES 
('HOUSING,WRAP RECESSED') 
,('HOUSING,ASSEMBLY 2-FEED') 
,('LENS,FLUSH SUS'); 
GO 

一個簡單的選擇使用功能

SELECT LongDescription 
     ,dbo.ReplaceAbbreviations(LongDescription) AS ShortDescription 
FROM YourDescription; 
GO 

使用動態SQL和全局搜索清潔測試場景

DROP TABLE YourDescription; 
DROP FUNCTION dbo.ReplaceAbbreviations; 
DROP TABLE Abbreviations; 

結果

LongDescription   ShortDescription 
HOUSING,WRAP RECESSED  HSG,WRAP REC 
HOUSING,ASSEMBLY 2-FEED HSG,ASSY 2-FD 
LENS,FLUSH SUS    LNS,FL SUS 
0

一般策略是遍歷每個單詞/縮寫對,並基於每對更新Table1.Description。

CREATE TABLE #table1 (descr VARCHAR(1000)) 
CREATE TABLE #abbr (word VARCHAR(1000), abr VARCHAR(1000), processed int) 

DECLARE @word VARCHAR(1000) 
DECLARE @abbr VARCHAR(1000) 

INSERT INTO #table1 
     (descr) 
VALUES ('HOUSING,WRAP RECESSED' -- descr - varchar(1000) 

     ), 
      ('HOUSING,ASSEMBLY 2-FEED' -- descr - varchar(1000) 

     ), 
      ('LENS,FLUSH SUS' -- descr - varchar(1000) 

     ) 

INSERT INTO #abbr 
     (word, abr, processed) 
VALUES ('ASSEMBLY', -- word - varchar(1000) 
      'ASSY' -- abr - varchar(1000) 
      ,0 
     ), 
      ('FEED', -- word - varchar(1000) 
      'FD' -- abr - varchar(1000) 
      ,0 
     ), 
      ('FLUSH', -- word - varchar(1000) 
      'FL' -- abr - varchar(1000) 
      ,0 
     ), 
      ('HOUSING', -- word - varchar(1000) 
      'HSG' -- abr - varchar(1000) 
      ,0 
     ), 
      ('LENS', -- word - varchar(1000) 
      'LNS' -- abr - varchar(1000) 
      ,0 
     ), 
      ('RECESSED', -- word - varchar(1000) 
      'REC' -- abr - varchar(1000) 
      ,0 
     ) 


WHILE EXISTS (SELECT * FROM #abbr WHERE processed = 0) 
BEGIN 
    SELECT TOP 1 @word = word, @abbr = abr FROM #abbr WHERE processed = 0 

    UPDATE #table1 
    SET descr = REPLACE(descr,@word,@abbr) 

    UPDATE #abbr 
    SET processed = 1 
    WHERE word = @word AND abr = @abbr 
END 

SELECT * FROM #table1 
+1

你正走在程序思維的黑暗中。來吧!繼續介紹基於集合的方法。看到proc魔鬼,他發明了循環和光標,讓我們的數據庫人員遠離集合解決方案。說實話:我的解決方案是 - 在魔法時刻*隱藏的* RBAR *。誠實2:是的,有moements,其中'WHILE'(或'CURSOR')是一個不錯的選擇,但這些情況是罕見的...... – Shnugo

1

這裏是另一種選擇&更換。這個過程將基本上「標記」字符串以避免衝突。

我要指出,該縮寫將最好的是兩個字段(發件人,收件人)。提供的樣本中的一對似乎不一致(Long> Short和Short to Long)。

Declare @Table1 table (ID int,Description varchar(500));Insert into @Table1 values (1,'HOUSING,WRAP RECESSED'),(2,'HOUSING,ASSEMBLY 2-FEED'),(3,'LENS,FLUSH SUS') 
Declare @Table2 table (MapFrom varchar(50),MapTo varchar(50));Insert Into @Table2 values 
('ASSEMBLY','ASSY'), 
('FEED' ,'FD'), 
('FLUSH' ,'FL'), 
('HOUSING' ,'HSG'), 
('LENS' ,'LNS'), 
('RECESSED','REC') 

Declare @SQL varchar(max)='' 
Select @SQL = @SQL+concat(',(',ID,',''||',replace(Description,'''',''''''),'||'')') From @Table1 --Where ID=2 
Select @SQL = Replace(@SQL,MapFrom,MapTo) 
From (
     Select MapFrom=' ',MapTo='|| ||' 
     Union All 
     Select ',','||,||' 
     Union All 
     Select '-','||-||' 
     Union All 
     Select MapFrom = '||'+ltrim(rtrim(MapFrom))+'||' 
       ,MapTo = ltrim(rtrim(MapTo)) 
      From @Table2 
      Union All 
      Select '||','' -- Remove Any Remaining | 
     ) A 
Select @SQL = 'Select * From ('+Stuff(@SQL,1,1,'values')+') N(ID,Value)' 
Exec(@SQL) 

返回

ID Value 
1 HSG,WRAP REC 
2 HSG,ASSY 2-FD 
3 LNS,FL SUS 
+0

我對任何混淆道歉,但「=」不包括在值中。我只是想說住房的縮寫是HSG等等。所以他們實際上是兩列。這有助於澄清?不過謝謝你!如果您有更新,我一定希望看到更新。感謝您花時間幫忙! – SeanDon

+0

這兩個字段名稱是什麼? –

+0

@SeanDon查看更新的答案。在Table2中,我現在有2個字段MapFrom和MapTo –