- Aqui está um violino para mostrar o que estou procurando .
Dada uma tabela com duas colunas - um ID inteiro e uma string baseada em texto - quero começar com um valor de string que codifique qualquer número de inteiros entre chaves, misturados com quaisquer outros caracteres de texto válidos.
Exemplo:'{1} / {9} ... {12}'
Com uma única SELECT
instrução, quero retornar uma string pela qual todos os inteiros (e suas chaves) foram substituídos por um valor derivado da minha tabela; especificamente, o valor de texto para a linha com um ID que corresponde ao número encontrado na string de origem.... e quaisquer caracteres fora das chaves permanecem intocados.
Aqui está um exemplo que não consegue concluir a tarefa:
select
replace('{13} {15}','{'+cast(id as varchar)+'}',isNull(display,''))
from testing;
Isso retornaria 1 linha por linha na testing
tabela. Para a linha com id
valor = 13, a parte '{13}' da string é substituída com sucesso, mas a parte '{15}' não é (e vice-versa na linha 15).
Imagino que criar uma função que percorra todas as testing
linhas e tente repetidamente substituições resolveria o problema. Seja como for, uma instrução SQL direta seria preferível ao loop.
Dados de exemplo
+----+-------------------+
| id | display |
+----+-------------------+
| 1 | Apple |
| 2 | Banana |
| 3 | Celery |
| 4 | Dragonfruit |
| 5 | Eggplant |
| 6 | Fenugreek |
| 7 | Gourd |
| 8 | Honeydew |
| 9 | Iceberg Lettuce |
| 10 | Jackfruit |
| 11 | Kale |
| 12 | Lemon |
| 13 | Mandarin |
| 14 | Nectarine |
| 15 | Olive |
+----+-------------------+
Casos de uso de exemplo
select replace('{1} {3}',null,null)
-- Returns 'Apple Celery'
select replace('{3},{4},{5}',null,null);
-- Returns 'Celery,Dragonfruit,Eggplant'
select replace('{1} / {9} ... {12}',null,null);
-- Returns 'Apple / Iceberg Lettuce ... Lemon'
Claramente, a palavra- replace
chave não faz o trabalho.
PS. Se uma solução exigir que o formato da string seja alterado para facilitar isso, essa é uma opção.
Por exemplo: '#1 / #9 ... #12'
(para correlacionar com o exemplo anterior)
Nesse formato, talvez pudéssemos dividir a string em um conjunto de linhas, com base em #
, pegar os left
caracteres até encontrarmos um não numérico, join
para a testing
tabela com base nos números obtidos, substituir os #
e números pelo valor testing
da tabela e display
depois stuff
todos individualmente tokens modificados de volta em uma única string for xml path
?
Estou usando o SQL Server 2016, que não oferece suporte ao string_agg
. Dito isso, se houver uma solução usando string_agg
, ainda estou interessado em analisá-la.
Aqui está um exemplo de como usar um recursivo
cte
para traduzir as variáveisSupondo que você esteja em uma versão que o suporte (e desative a versão em seu violino original ), você pode usar as funções nativas
string_split()
&string_agg()
.O exemplo anterior pressupõe que você abandonou as chaves no caminho e é apenas uma lista de números separados por vírgula. Se você quiser manter as chaves no caminho, tente impor que ele esteja chegando como um JSON bem formado e use algumas das funções JSON nativas para analisá-lo. Os bits-chave acima são:
[Id]
s para ...testing.display
s que você deseja e depois ...string_agg()
Dado o esclarecimento de que você está em 2016, e que
string_agg()
só estará disponível em 2017, você ainda pode usarstring_split()
para criar a matriz conforme necessário e usar uma das abordagens herdadas que contornam a ausência destring_agg()
como você menciona considerando no OP. Por exemplo: