替换varchar tsql中的电子邮件

时间:2017-03-21 16:38:52

标签: sql tsql replace

我在一个列中的字符串化JSON中有一个电子邮件地址。

我需要用不同的电子邮件地址替换它。

我应该补充一点,我不能使用CLR。这太容易了。

我会采取其他建议,但我提出的最好的方法是在"之前和之后更换@之间的所有内容。

DECLARE @testEmailAddress varchar(255);
SET @testEmailAddress = 'MyReplacementEmail@gmail.com'; 
UPDATE #TestEmails
SET 
    COMM_DATA = 
        STUFF (
            COMM_DATA,      
            PATINDEX(
                '%@%', 
                COMM_DATA
            ) 
            -
            PATINDEX ('%"%',
                REVERSE(
                    SUBSTRING(
                        COMM_DATA, 
                        0, 
                        PATINDEX(
                            '%@%', 
                            COMM_DATA
                        )
                    )
                )
            ) + 1,
            PATINDEX(
                '%@%', 
                COMM_DATA
            ) 
            +
            PATINDEX ('%"%',
                SUBSTRING(
                    COMM_DATA, 
                    PATINDEX(
                        '%@%', 
                        COMM_DATA
                    ),
                    LEN(COMM_DATA)
                )
            ) - 1,
            @testEmailAddress
        )
;

除了替换电子邮件地址似乎超过了几个字符的替换字符串之外,这几乎可以正常工作。

例如

{"CustomerEmail":"original@test.com","property2":"value2","property3":"value3","property4":"value4","property5":"value5","property6":"value6","property7":"value7","property8":"value8"}

变为

{"CutomerEmail":"MyReplacementEmail@gmail.comproperty8":"value8"}

但我希望它是

{"CustomerEmail":"MyReplacementEmail@gmail.com","property2":"value2","property3":"value3","property4":"value4","property5":"value5","property6":"value6","property7":"value7","property8":"value8"}

3 个答案:

答案 0 :(得分:1)

CROSS APLLY对于像这样的计算很方便

declare @t table (comm_data varchar(max))
insert @t values
('{"CustomerEmail":"original@test.com","property2":"value2","property3":"value3","property4":"value4","property5":"value5","property6":"value6","property7":"value7","property8":"value8"}');

DECLARE @testEmailAddress varchar(255);
SET @testEmailAddress = 'MyReplacementEmail@gmail.com'; 
select t1.*, t2.*, stuff(comm_data,p1-p2+2,p2+p3-3,@testEmailAddress)
from @t 
cross apply (
     select p1=PATINDEX('%@%',COMM_DATA)
    ) t1
cross apply (
     select p2=PATINDEX('%":"%', reverse(left(COMM_DATA,p1))),
       p3 = PATINDEX('%","%', substring(COMM_DATA, p1, len(COMM_DATA)))
    ) t2

您可以轻松调试正确的p1-p2 + 2,p2 + p3-3 stuff边界,并在需要时将代码转换为长格式。

答案 1 :(得分:1)

我会做更多这样的事情:虽然我打赌在SQL 2016中有一种比纯字符串解析更好的查询和替换数据的方法。

class MessageClass {
    var key = ""
    var name = ""
}

var messagesArray = [MessageClass]()

func readInAllMessages() {
    let messagesRef = ref.child("messages")
    messagesRef.observeSingleEvent(of: .value, with: { snapshot in
        for child in snapshot.children {
            let snap = child as! FIRDataSnapshot
            let msg = self.snapToMsgClass(child: snap)
            self.messagesArray.append(msg)
        }
    })
}

func addRemoveObserver() {
    let messagesRef = ref.child("messages")
    messagesRef.observe(.childRemoved, with: { snapshot in
        let keyToRemove = snapshot.key 

        if let i = self.messagesArray.index(where: { $0.key == keyToRemove }) {
            self.messagesArray.remove(at: i)
        }
    })
}

func snapToMsgClass(child: FIRDataSnapshot) -> MessageClass {
    let dict = child.value as! [String:Any]
    let name = dict["name"] as! String
    let msg = MessageClass()
    msg.name = name
    msg.key = child.key
    return msg
}

我基本上可以使它成为一个标量函数,它接受一个字符串(varchar JSON)并返回一个改变的JSON。你基本上只是字符串中的密钥对。这样我可以对结果集运行它并且做了N次并且只需要我正在搜索的字段(@JSON)的参数,我是什么' Key'我正在寻找替换(@CustomerEmail),以及我用@replace替换它。

答案 2 :(得分:0)

我错误地估算了终点。我没有给出STUFF的起点和终点之间的距离,而是从字符串的开头给它起始位置和结束位置。最终代码如下:

    COMM_DATA = 
        STUFF (
            COMM_DATA,      
            PATINDEX(
                '%@%', 
                COMM_DATA
            ) 
            -
            PATINDEX ('%"%',
                REVERSE(
                    SUBSTRING(
                        COMM_DATA, 
                        0, 
                        PATINDEX(
                            '%@%', 
                            COMM_DATA
                        )
                    )
                )
            )+ 1,
            PATINDEX(
                '%@%', 
                COMM_DATA
            ) 
            +
            PATINDEX ('%"%',
                SUBSTRING(
                    COMM_DATA, 
                    PATINDEX(
                        '%@%', 
                        COMM_DATA
                    ),
                    LEN(COMM_DATA)
                )
            )
            -
            (
                PATINDEX(
                    '%@%', 
                    COMM_DATA
                ) 
                -
                PATINDEX ('%"%',
                    REVERSE(
                        SUBSTRING(
                            COMM_DATA, 
                            0, 
                            PATINDEX(
                                '%@%', 
                                COMM_DATA
                            )
                        )
                    )
                )
            ) - 2,
            @testEmailAddress
        )