我在一个列中的字符串化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"}
答案 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
)