Die folgende Abfrage ist ziemlich lang, da sie verschiedene Felder in der äußeren SELECT-Anweisung enthält, die zum Veranschaulichen der Funktionsweise der Abfrage verwendet wird. Um nur eine funktionierende Abfrage zu erhalten, benötigt die select-Anweisung nur die ganz rechte Spalte (d. H. Die -Anweisung).
Ziel
eine SQL-Abfrage schreiben, dass der Wert des bb Feld überprüft, ob numerisch ist und wenn es ist, ersetzen Sie es mit einer Schnur.
die SQL-Abfrage
Jede Spalte in der äußeren Abfrage unten zeigt einen progressiven Schritt in das Ziel zu erfüllen, und diese Schritte werden im Folgenden erläutern.
Hinweis: Um nur eine funktionierende Abfrage zu erhalten, benötigt die select-Anweisung nur die ganz rechte Spalte (d. H. Die -Anweisung). Alle anderen Spalten sind nicht erforderlich.
SELECT
json
-- Find the position of the JSON tag "bb": "
, PATINDEX(jsontagpattern, json)
-- Return the JSON data to the right of the JSON tag (right-half of the JSON)
, RIGHT(json, LEN(json) - PATINDEX(jsontagpattern, json) - jsontaglength + 1)
-- Find the first double-quote from the right-half of the JSON
, PATINDEX(
'%"%',
RIGHT(json, LEN(json) - PATINDEX(jsontagpattern, json) - jsontaglength + 1)
)
-- Return the value of the JSON tag "bb" based on the position of the double-quote found above
, LEFT(
RIGHT(json, LEN(json) - PATINDEX(jsontagpattern, json) - jsontaglength + 1),
PATINDEX(
'%"%',
RIGHT(json, LEN(json) - PATINDEX(jsontagpattern, json) - jsontaglength + 1)
) - 1
)
-- Check if the above value is numeric or not
, ISNUMERIC(
LEFT(
RIGHT(json, LEN(json) - PATINDEX(jsontagpattern, json) - jsontaglength + 1),
PATINDEX('%"%', RIGHT(json, LEN(json) - PATINDEX(jsontagpattern, json) - jsontaglength + 1)) - 1
)
)
-- Note: Only the following CASE expression is required, the previous expressions above were only to demonstrate the workings of the query
, CASE WHEN
ISNUMERIC(
LEFT(
RIGHT(json, LEN(json) - PATINDEX(jsontagpattern, json) - jsontaglength + 1),
PATINDEX('%"%', RIGHT(json, LEN(json) - PATINDEX(jsontagpattern, json) - jsontaglength + 1)) - 1
)
) = 1
THEN
-- The value is numeric, replace the value with 'replacetext'
STUFF(
json,
PATINDEX(jsontagpattern, json) + jsontaglength,
LEN(
LEFT(
RIGHT(json, LEN(json) - PATINDEX(jsontagpattern, json) - jsontaglength + 1),
PATINDEX('%"%', RIGHT(json, LEN(json) - PATINDEX(jsontagpattern, json) - jsontaglength + 1)) - 1
)
),
replacetext
)
ELSE json
END as OutputJson
FROM (
-- Sample data for demonstration purposes
-- Two JSON blocks, one where the field bb is numeric, one where it is not
SELECT
'{
"field1": "value1",
"block1": {
"aaa": "string",
"bb": "1234567890"
}
}' AS json
-- This expression is the string
-- %"bb": "
-- and is used for pattern matching
, '%' + '"bb": "' + '%' AS jsontagpattern
-- The length of the string used in pattern matching
, LEN( '"bb": "' ) AS jsontaglength
-- If the value of bb is numeric, replace it with the following text
, 'XXXX' AS replacetext
UNION
SELECT
'{
"field1": "value1",
"block1": {
"aaa": "string",
"bb": "1a23456789b0"
}
}' AS json
, '%' + '"bb": "' + '%' AS jsontagpattern
, LEN( '"bb": "' ) AS jsontaglength
, 'XXXX' AS replacetext
) AS x
Erklärung
Der erste Schritt ist die Position des bb
Tag zu finden. Dies wird durch die PATINDEX()
function getan:
PATINDEX(jsontagpattern, json)
Der nächste Schritt ist es, den Teil der JSON-Daten zu finden, die rechts von dem Tag, da dies mit dem bb Feldwert beginnen.
RIGHT(json, LEN(json) - PATINDEX(jsontagpattern, json) - jsontaglength + 1)
Aus der Zeichenfolge oben zurück, die ersten doppelten Anführungszeichen finden, da es zeigt an, wo der Wert von bb endet:
PATINDEX( '%"%', RIGHT(json, LEN(json) - PATINDEX(jsontagpattern, json) - jsontaglength + 1) )
den Wert des Feldes bb JSON Get mit den folgenden (das gibt beispielsweise 1234567890 zurück):
LEFT( RIGHT(json, LEN(json) - PATINDEX(jsontagpattern, json) - jsontaglength + 1), PATINDEX( '%"%', RIGHT(json, LEN(json) - PATINDEX(jsontagpattern, json) - jsontaglength + 1) ) - 1 )
Wenden Sie die ISNUMERIC()
function auf den obigen Wert an. Es gibt 1 zurück, wenn es numerisch ist, andernfalls 0.
Wenn ISNUMERIC()
0 zurückgibt, geben Sie die ursprünglichen JSON-Daten zurück. Wenn jedoch ISNUMERIC()
den Wert 1 zurückgibt, ersetzen Sie den Wert des Felds bb
mit STUFF()
function.
Probeneingang & Ausgang
Angesichts der folgenden Eingabe:
{
"field1": "value1",
"block1": {
"aaa": "string",
"bb": "1234567890" <----- Numeric value
}
}
{
"field1": "value2",
"block1": {
"aaa": "string",
"bb": "1a23456789b0" <----- Non-numeric value
}
}
Der Ausgang zurückgekehrt ist:
{
"field1": "value1",
"block1": {
"aaa": "string",
"bb": "XXXX" <----- Numeric value replaced by string
}
}
{
"field1": "value2",
"block1": {
"aaa": "string",
"bb": "1a23456789b0" <----- Non-numeric value unchanged
}
}
Haben Sie eine SQL müssen nur extrahieren und Rückkehr der Wert des 'bb'-Feldes? Wenn ja, dann verwenden Sie die Funktion ['ISNUMERIC'] von T-SQL (https://msdn.microsoft.com/en-us/library/ms186272.aspx), um zu prüfen, ob sie als Zahl interpretiert werden kann, und verwenden Sie sie dann T-SQLs [string-Funktionen] (https://msdn.microsoft.com/en-us/library/ms181984.aspx), um die Ersetzung durchzuführen (dh die Zeichenfolge in einem linken und rechten Teil vor/nach dem Wert zu schneiden und zu verketten sie wieder zusammen). – Phylyp
Nein, ich habe keine Abfrage, um diesen Wert zu extrahieren –
[Dieser Artikel] (https://www.simple-talk.com/sql/t-sql-programming/consuming-json-strings-in-sql- Server /) kann nützlich sein. Sie können die Prüfungen durchführen, nachdem Sie sie in eine Tabelle konvertiert haben. – NEER