Avoiding failing entire procedure if one SELECT statement fails

  • 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

  • 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);

  • Forum Etiquette: How to post Reporting Services problems
  • [/url]
  • Forum Etiquette: How to post data/code on a forum to get the best help - by Jeff Moden
  • [/url]
  • How to Post Performance Problems - by Gail Shaw
  • [/url]

  • 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


    --help us help you! If you post a question, make sure you include a CREATE TABLE... statement and INSERT INTO... statement into that table to give the volunteers here representative data. with your description of the problem, we can provide a tested, verifiable solution to your question! asking the question the right way gets you a tested answer the fastest way possible!

  • Thank you both very much for the help.

  • 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.

  • 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