Eu tenho uma coluna GL_DESCRIPTION
que tem valores como este
SELECT DISTINCT GL_DESCRIPTION
FROM database_actual_pemupukan;
PEMUPUKAN - CPD HIK ROTASI 3 EMDEK - TRANSPORT
PEMUPUKAN - CPD HIK ROTASI 2 EMDEK - UPAH
PEMUPUKAN - CPD HIK ROTASI 2 - MATERIAL
PEMUPUKAN - CPD HIK ROTASI 1 - TRANSPORT
PEMUPUKAN - CPD HIK ROTASI 3 - MATERIAL
PEMUPUKAN - CPD HIK ROTASI 1 - MATERIAL
PEMUPUKAN - CPD HIK ROTASI 2 EMDEK - MATERIAL
PEMUPUKAN - CPD HIK ROTASI 3 EMDEK - MATERIAL
PEMUPUKAN - CPD HIK ROTASI 1 EMDEK - MATERIAL
PEMUPUKAN - CPD HIK ROTASI 1 EMDEK - TRANSPORT
Tenho uma nova coluna em INT chamada Rotasi
que pode armazenar qualquer valor numérico após 'ROTASI'
Então, para esse requisito, meu código seria assim:
UPDATE database_actual_pemupukan
SET Rotasi = SUBSTRING(GL_DESCRIPTION,
PATINDEX('%[0-9]%', GL_DESCRIPTION),
LEN(GL_DESCRIPTION));
Retorna um erro:
Msg 245, Nível 16, Estado 1, Linha 1
Falha na conversão ao converter o valor varchar '1 - MATERIAL' para o tipo de dados int
Também tentei esta consulta
UPDATE database_actual_pemupukan
SET rotasi = CASE
WHEN PATINDEX('%[0-9]%', GL_DESCRIPTION) > 0
THEN CAST(
-- Extract the number starting from the first digit
SUBSTRING(GL_DESCRIPTION,
PATINDEX('%[0-9]%', GL_DESCRIPTION),
CASE
WHEN PATINDEX('%[^0-9]%', GL_DESCRIPTION + 'a') = 0
THEN LEN(GL_DESCRIPTION) - PATINDEX('%[0-9]%', GL_DESCRIPTION) + 1
ELSE PATINDEX('%[^0-9]%', GL_DESCRIPTION + 'a') - PATINDEX('%[0-9]%', GL_DESCRIPTION)
END) AS INT)
ELSE NULL -- If no number is found, set rotasi to NULL
END;
Esta consulta retorna este erro:
Msg 537, Nível 16, Estado 2, Linha 1
Parâmetro de comprimento inválido passado para a função LEFT ou SUBSTRING.
Onde estou errado?
Você começou no caminho certo, você só precisa ser metódico ao concluir sua extração, por exemplo
Retornos:
Fiddle de DB
Observação: você pode fazer isso em uma linha, se desejar. Eu apenas mostrei cada cálculo separadamente para maior clareza (e porque não gosto de duplicar código).
Podemos usar um truque de substring aqui, semelhante ao que você estava tentando, com
PATINDEX()
eREVERSE()
:A lógica acima funciona encontrando os dois pontos na string onde o inteiro começa e termina e, em seguida, pegando uma substring.
Aqui está uma demonstração mostrando que a lógica para extrair o inteiro está funcionando.