My SQL database manages the metadata for a front end application which uses several executables. One of the columns in the job scheduler table is a list of acceptable return codes for each executable.
A different table receives the output of the executables. Some of the executables behave nicely and output a single integer value which is then easy to compare with the acceptable values mentioned above, using an IN clause.
The problem comes with several legacy executables which output verbose messages. For example one might output a string such as "Job succeeded- exit code: 12345" and one might output "Job succeeded- exit code: 678 - maximum run time exceeded". The text before and after the ":" will vary, but the next characters (apart from spaces) after the ":" will always be an integer.
I've found ways to keep everything after the delimiter, or a certain number of characters after the delimiter.
How do I extract the first INTEGER after the ":" delimiter, if I won't know the length of the integer ahead of time? Also some of the return codes include a leading "-" for a negative value.
input:
1 'Job succeeded- exit code: 12345'
2 'Job succeeded- exit code: 678 - some message.'
3 'Job succeeded- exit code: -98765431 - a different message'
Desired output:
1 12345
2 678
3 -98765431
This would allow me to compare the exit codes from these legacy executables against the list of acceptable codes defined in the jobs table.
UPDATE:
Both @Steve Mangiameli and @Herman 's answers were helpful. My challenges were that the text before the delimiter were not consistent nor of fixed length, and that the delimiter character ':' I wanted to use appears in some of the prefix text (for example, in a string pointing to a file path D:\somefile.csv).
I was lucky in that the log writer does some formatting so I was able to use the string '): ' in a PATINDEX statement. I came up with the expression below, combining the PATINDEX suggestions with a LEN function, with a REPLACE to get rid of the last ':'.
REPLACE(((RIGHT([LogEntry], LEN([LogEntry]) - PATINDEX('%):%', [LogEntry])))), ': ', '') as ReportedExitCode
I combined the above with the delimiter-splitting function described in this post to get my comma-delimited exit code list into an IN clause, and now the whole is working just as I had hoped.
SELECT a.[JOBITEM]
,a.[SUCCESSEXITCODES]
,REPLACE(((RIGHT([LogEntry], LEN([LogEntry]) - PATINDEX('%):%', [LogEntry])))), ': ', '') as ReportedExitCode
,b.[LogEntry]
FROM [JOBTABLE].[dbo].[LEGACY_JOBS] AS a
JOIN [JOBTABLE].[dbo].[PROCESS_LOGS] AS b ON b.jobitem = a.jobitem
WHERE b.[LogEntry] LIKE '%(success)%'
AND REPLACE(((RIGHT([LogEntry], LEN([LogEntry]) - PATINDEX('%):%', [LogEntry])))), ': ', '') NOT IN (
SELECT value
FROM dbo.splitDelimitedValues(a.[SuccessExitCodes], ',')
)
OUTPUT:
JOBITEM SUCCESSEXITCODES ReportedExitCode LogEntry
Job1 0,1 6 ABCExec.exe Return Code (Success): 6
Job2 0 1 foo.bat Return Code (Success): 1
Job3 0,1 1 oldjob.bat Return Code (Success): -1
Job4 0,1 -52789451 legacgyjob.exe Return Code (Success): -52789451