June 27, 2013 at 1:47 pm
I have a few procedures with multiple SELECT statements (using UNION ALL) in a single procedure. Is there a way to avoid failure for the entire procedure if one of the SELECT statements fail?
Below is a sample scenario. I know somethings could be done to kick out the offending data. However, the table illustrates what I'm facing. Is there a way to have SQL avoid t1 and t2 (since they can't CAST the VARCHAR) but still process t3 and 4? Thanks for any help!
CREATE TABLE tbl
(
col1 varchar(25) not null,
col2 varchar(25) not null
)
INSERT INTO tbl (col1, col2)
VALUES
('t1', '3.21'),
('t1', '2.29'),
('t1', ''),
('t2', '21'),
('t2', ''),
('t2', '19'),
('t2', '20a'),
('t3', '3.11'),
('t3', '3.54'),
('t4', '18'),
('t4', '29'),
('t4', '26')
;
/*Print the results of table creation*/
SELECT tbl.col1, tbl.col2
FROM tbl
;
/*Create procedure AvgCol which attempts to CAST the values in Col2 for t1, t2, t3, and t4*/
CREATE PROCEDURE AvgCol AS
SELECT tbl.col1, CAST(tbl.col2 AS Decimal(8,2)) AS col2_cast
FROM tbl
WHERE tbl.col1 = 't1'
UNION ALL
SELECT tbl.col1, CAST(tbl.col2 AS Decimal(8,2)) AS col2_cast
FROM tbl
WHERE tbl.col1 = 't2'
UNION ALL
SELECT tbl.col1, CAST(tbl.col2 AS Decimal(8,2)) AS col2_cast
FROM tbl
WHERE tbl.col1 = 't3'
UNION ALL
SELECT tbl.col1, CAST(tbl.col2 AS Decimal(8,2)) AS col2_cast
FROM tbl
WHERE tbl.col1 = 't4'
;
/*Executes AvgCol. It fails because two of the SELECT statements are trying to cast a varchar('', '20a') to numeric*/
EXEC AvgCol
June 27, 2013 at 1:52 pm
Ideally you would have suitable exclusions in your where clause to avoid procesing errors.
You cannot trap errors on one select in a UNION, but you could insert the results of each SELECT into a table and have TRY..CATCH round each one, then select from the table at the end...
MM
select geometry::STGeomFromWKB(0x0106000000020000000103000000010000000B0000001000000000000840000000000000003DD8CCCCCCCCCC0840000000000000003DD8CCCCCCCCCC08408014AE47E17AFC3F040000000000104000CDCCCCCCCCEC3F9C999999999913408014AE47E17AFC3F9C99999999991340000000000000003D0000000000001440000000000000003D000000000000144000000000000000400400000000001040000000000000F03F100000000000084000000000000000401000000000000840000000000000003D0103000000010000000B000000000000000000143D000000000000003D009E99999999B93F000000000000003D009E99999999B93F8014AE47E17AFC3F400000000000F03F00CDCCCCCCCCEC3FA06666666666FE3F8014AE47E17AFC3FA06666666666FE3F000000000000003D1800000000000040000000000000003D18000000000000400000000000000040400000000000F03F000000000000F03F000000000000143D0000000000000040000000000000143D000000000000003D, 0);
June 27, 2013 at 1:53 pm
add a where statement which will explicitly exclude non numeric data;do that for every table that is in your union all.
this , for example would allow integers only.(no decimal)
...AND tbl.col1 not LIKE '%[^0-9]%'
EDIT: tested code:
CREATE TABLE tbl
(
col1 varchar(25) not null,
col2 varchar(25) not null
)
INSERT INTO tbl (col1, col2)
VALUES
('t1', '3.21'),
('t1', '2.29'),
('t1', ''),
('t2', '21'),
('t2', ''),
('t2', '19'),
('t2', '20a'),
('t3', '3.11'),
('t3', '3.54'),
('t4', '18'),
('t4', '29'),
('t4', '26')
;
/*Print the results of table creation*/
SELECT col1, CAST(col2 AS Decimal(8,2)) AS col2_cast
FROM (
SELECT *
FROM tbl
WHERE tbl.col2 not LIKE '%[^0-9]%' and RTRIM(tbl.col2) <> ''
) myAlias
;
Lowell
June 27, 2013 at 4:48 pm
Thank you both very much for the help.
June 27, 2013 at 4:50 pm
Hi MM,
Thanks again for the reply. Would you mind showing me what a TRY...CATCH would look like with my sample data? I've read around on this function, but I've never used it.
June 29, 2013 at 9:53 am
TRY...CATCH is not a function, it's a control-flow construct used for exception handling.
Here is some pseudo code:
BEGIN TRY
-- insert first select result into new temporary table using SELECT...INTO
END TRY
BEGIN CATCH
-- log error
END CATCH
BEGIN TRY
-- insert second select result into existing temporary table using INSERT...SELECT
END TRY
BEGIN CATCH
-- log error
END CATCH
.
.
...more TRY...CATCH blocks, one for each select to insert it into the temporary table
.
.
.
Select from your temporary table to deliver the results.
There are no special teachers of virtue, because virtue is taught by the whole community.
--Plato
Viewing 6 posts - 1 through 5 (of 5 total)
You must be logged in to reply to this topic. Login to reply