لمسار XML(''):الهروب من الشخصيات "الخاصة".
-
20-08-2019 - |
سؤال
يقوم هذا الكود بشكل أساسي بترجمة الأحرف بناءً على الموضع في سلسلة واحدة إلى الحرف الموجود في نفس الموضع في سلسلة أخرى ويتم تشغيله لجميع الصفوف في الجدول.
عندما أقوم بتشغيل هذا (نسخة مبسطة):
DECLARE @R char(40)
DECLARE @U char(40)
SET @R=' abcdefghijklmnopqrstuvwxyz!@#$%^&*()_+'+char(181)
SET @U=REVERSE(@R)
DECLARE @TestTable TABLE (RowID int identity(1,1) primary key, Unreadable varchar(500))
INSERT INTO @TestTable VALUES ('+µt$zw!*µsu+yt!+s$xy')
INSERT INTO @TestTable VALUES ('%*!!xµpxu!(')
INSERT INTO @TestTable VALUES ('pxpµnxrµu+yµs%$t')
;WITH CodeValues AS
(
SELECT
Number,SUBSTRING(@R,Number,1) AS R,ASCII(SUBSTRING(@U,Number,1)) AS UA
FROM Numbers
WHERE Number<=LEN(@R)
)
SELECT
t.RowID
,(SELECT
''+c.R
FROM Numbers n
INNER JOIN CodeValues c ON ASCII(SUBSTRING(t.Unreadable,n.Number,1))=c.UA
WHERE n.Number<=LEN(t.Unreadable)
FOR XML PATH('')
) AS readable
FROM @TestTable t
أحصل على ما يلي:
RowID readable
----------- ---------------------------------------
1 a simple translation
2 hello world
3 wow you ran this
لكن تحتاج:
RowID readable
----------- ---------------------------------------
1 a simple translation
2 hello world
3 wow you ran this
فهل هناك طريقة غير REPLACE()
, ، لكي تظهر المساحات بالشكل الصحيح؟يحدث هذا أيضًا عند فواصل الأسطر، في الكود الفعلي الخاص بي.
هل يمكن إعادة كتابة هذا بطريقة أفضل؟أنا في الأساس استخدمت للتو FOR XML PATH('')
لتسلسل قيم الصف الفردية معًا.
المحلول
XML الذي تحصل عليه صحيح.إنها XML, وليس نصًا ويمكن قراءته بتنسيق XML بواسطة محلل XML.يتم الهروب من الأحرف الخاصة بشكل صحيح، كما ينبغي أن يكون.أيًا كانت وحدة العميل لديك والتي تستهلك XML، فيجب تحليلها كـ XML، وليس كنص، وبعد ذلك سيتم عرضها بشكل صحيح.
تحديث:
في حالة عدم وضوح الأمر، كل ما عليك فعله في استعلامك هو التعامل مع XML على أنه XML والنص على أنه نص، وليس خلط XML على أنه نص، على سبيل المثال:
;WITH CodeValues AS
(
SELECT
Number,SUBSTRING(@R,Number,1) AS R,ASCII(SUBSTRING(@U,Number,1)) AS UA
FROM Numbers
WHERE Number<=LEN(@R)
)
, XmlValues AS (
SELECT
t.RowID
,(SELECT
''+c.R
FROM Numbers n
INNER JOIN CodeValues c ON ASCII(SUBSTRING(t.Unreadable,n.Number,1))=c.UA
WHERE n.Number<=LEN(t.Unreadable)
FOR XML PATH(''), TYPE
) AS readable
FROM @TestTable t)
SELECT x.RowId,
x.readable.value('.', 'VARCHAR(8000)') as readable
FROM XmlValues AS x