আমি টি-SQL এর যে একটি কাস্টম JSON বিশ্লেষক লিখছি † ।
আমার পার্সারের উদ্দেশ্যে, আমি PATINDEX
টোকেনের তালিকা থেকে একটি টোকেনের অবস্থান গণনা করে এমন ফাংশনটি ব্যবহার করছি । আমার ক্ষেত্রে টোকেনগুলি সমস্ত একক অক্ষর এবং সেগুলিতে এগুলি অন্তর্ভুক্ত করে:
{} []:,
সাধারণত, যখন আমাকে কয়েকটি প্রদত্ত চরিত্রের (প্রথম) অবস্থানের সন্ধান করতে হয়, তখন আমি PATINDEX
এই ফাংশনটি ব্যবহার করি :
PATINDEX('%[abc]%', SourceString)
ফাংশন তারপর আমার প্রথম স্থান দিতে হবে a
বা b
বা c
মধ্যে - যেটি আগে পাওয়া যাবে এরকম - SourceString
।
এখন আমার ক্ষেত্রে সমস্যাটি ]
চরিত্রটির সাথে সংযুক্ত বলে মনে হচ্ছে । চরিত্রের তালিকায় এটি নির্দিষ্ট করার সাথে সাথে যেমন:
PATINDEX('%[[]{}:,]%', SourceString)
স্পষ্টতই আমার মিলিত প্যাটার্নটি ভেঙে যায়, কারণ ফাংশনটি কোনও মিল খুঁজে পায় না। দেখে মনে হচ্ছে প্রথমটি থেকে বাঁচার জন্য আমার একটি উপায় দরকার ]
যাতে PATINDEX
এটি একটি বিশেষ প্রতীক না হয়ে দেখার জন্য অন্যতম চরিত্র হিসাবে বিবেচনা করে।
আমি এই প্রশ্নটি একই ধরণের সমস্যার বিষয়ে জিজ্ঞাসা করে পেয়েছি:
তবে, সেক্ষেত্রে ]
কেবল বন্ধনীগুলিতে নির্দিষ্ট করার প্রয়োজন হয় না, কারণ এটি কেবল একটি অক্ষর এবং এটি চারপাশে বন্ধনী ছাড়াই নির্দিষ্ট করা যেতে পারে। বিকল্প সমাধান, যা পলায়ন ব্যবহার করে, কেবল তার জন্য কাজ করে LIKE
এবং না PATINDEX
, কারণ এটি একটি ESCAPE
উপবৃত্ত ব্যবহার করে, প্রাক্তন দ্বারা সমর্থিত এবং পরবর্তীকালের দ্বারা নয়।
সুতরাং, আমার প্রশ্ন হল, কোন উপায় আছে একটি সন্ধান করা হয় ]
সঙ্গে PATINDEX
ব্যবহার [ ]
ওয়াইল্ডকার্ড? বা অন্যান্য ট্রান্সঅ্যাক্ট-এসকিউএল সরঞ্জাম ব্যবহার করে সেই কার্যকারিতা অনুকরণ করার কোনও উপায় আছে?
অতিরিক্ত তথ্য
এখানে একটি ক্যোয়ারী যেখানে আমি ব্যবহার করতে হবে একটি উদাহরণ PATINDEX
দিয়ে […]
উপরের মতো প্যাটার্ন। এখানে প্যাটার্নটি কাজ করে ( কিছুটা হলেও ) কারণ এতে ]
চরিত্রটি অন্তর্ভুক্ত নয়। ]
পাশাপাশি কাজ করাও আমার দরকার :
WITH
data AS (SELECT CAST('{"f1":["v1","v2"],"f2":"v3"}' AS varchar(max)) AS ResponseJSON),
parser AS
(
SELECT
Level = 1,
OpenClose = 1,
P = p.P,
S = SUBSTRING(d.ResponseJSON, 1, NULLIF(p.P, 0) - 1),
C = SUBSTRING(d.ResponseJSON, NULLIF(p.P, 0), 1),
ResponseJSON = SUBSTRING(d.ResponseJSON, NULLIF(p.P, 0) + 1, 999999)
FROM
data AS d
CROSS APPLY (SELECT PATINDEX('%[[{]%', d.ResponseJSON)) AS p (P)
UNION ALL
SELECT
Level = ISNULL(d.OpenClose - 1, 0) + d.Level + ISNULL(oc.OpenClose, 0),
OpenClose = oc.OpenClose,
P = d.P + p.P,
S = SUBSTRING(d.ResponseJSON, 1, NULLIF(p.P, 0) - 1),
C = c.C,
ResponseJSON = SUBSTRING(d.ResponseJSON, NULLIF(p.P, 0) + 1, 999999)
FROM
parser AS d
CROSS APPLY (SELECT PATINDEX('%[[{}:,]%' COLLATE Latin1_General_BIN2, d.ResponseJSON)) AS p (P)
CROSS APPLY (SELECT SUBSTRING(d.ResponseJSON, NULLIF(p.P, 0), 1)) AS c (C)
CROSS APPLY (SELECT CASE WHEN c.C IN ('[', '{') THEN 1 WHEN c.C IN (']', '}') THEN 0 END) AS oc (OpenClose)
WHERE 1=1
AND p.P <> 0
)
SELECT
*
FROM
parser
OPTION
(MAXRECURSION 0)
;
আমি যে আউটপুট পাই তা হ'ল:
Level OpenClose P S C ResponseJSON
----- --------- -- ----- -- ---------------------------
1 1 1 { "f1":["v1","v2"],"f2":"v3"}
1 null 6 "f1" : ["v1","v2"],"f2":"v3"}
2 1 7 [ "v1","v2"],"f2":"v3"}
2 null 12 "v1" , "v2"],"f2":"v3"}
2 null 18 "v2"] , "f2":"v3"}
2 null 23 "f2" : "v3"}
2 0 28 "v3" }
আপনি দেখতে পাচ্ছেন যে সারিগুলির মধ্যে একটিতে ]
অংশটি অন্তর্ভুক্ত রয়েছে S
। Level
কলাম, পাখির বন্ধনী অর্থ এবং ধনুর্বন্ধনী পাখির মাত্রা নির্দেশ করে। যেহেতু আপনি দেখতে পারেন, একবার স্তর 2 হয়ে, এটি 1. ফিরে কখনো কি তা পারতে যদি আমি বানাতে পারে PATINDEX
চিনতে ]
একটি টোকেন হিসাবে।
উপরের উদাহরণের জন্য প্রত্যাশিত ফলাফল:
Level OpenClose P S C ResponseJSON
----- --------- -- ---- -- ---------------------------
1 1 1 { "f1":["v1","v2"],"f2":"v3"}
1 NULL 6 "f1" : ["v1","v2"],"f2":"v3"}
2 1 7 [ "v1","v2"],"f2":"v3"}
2 NULL 12 "v1" , "v2"],"f2":"v3"}
2 0 17 "v2" ] ,"f2":"v3"}
1 NULL 18 , "f2":"v3"}
1 NULL 23 "f2" : "v3"}
1 0 28 "v3" }
আপনি এই ক্যোয়ারির সাথে ডিবি <> ফিডল খেলতে পারেন ।
† আমরা এসকিউএল সার্ভার 2014 ব্যবহার করছি এবং শীঘ্রই এমন কোনও সংস্করণে আপগ্রেড হওয়ার সম্ভাবনা নেই যা জেএসএন স্থানীয়ভাবে পার্সিং সমর্থন করে। আমি কাজটি করার জন্য একটি আবেদন লিখতে পারি তবে পার্সিংয়ের ফলাফলগুলিকে আরও প্রক্রিয়া করা প্রয়োজন, যা অ্যাপ্লিকেশনটিতে কেবল বিশ্লেষণের চেয়ে আরও বেশি কাজ বোঝায় - এমন ধরণের কাজ যা আরও সহজ হবে এবং সম্ভবত আরও দক্ষতার সাথে সম্পন্ন হয়েছে একটি টি-এসকিউএল স্ক্রিপ্ট, কেবল যদি আমি এটি সরাসরি ফলাফলগুলিতে প্রয়োগ করতে পারি।
এই সমস্যাটির সমাধান হিসাবে আমি এসকিউএলসিআরআর ব্যবহার করতে পারি এমনটা খুব কমই। তবে, কেউ যদি এসকিউএলসিএলআর সমাধান পোস্ট করার সিদ্ধান্ত নেন তবে আমার আপত্তি নেই, যেহেতু এটি অন্যদের জন্য কার্যকর হতে পারে।
["foo]bar”]
?