Check and validate every value of a subquery

  • Dear all,

    I have a case in which I want to validate some values with a Stored Procedure and return a custom RAISERROR, but I'm not sure how to implement it.

    THE CASE:

    I have a Table named PROJECT.

    Each PROJECT has more than one SUBPROJECTS.

    I want to validate every SUBPROJECT and IF SUBPROJECT'S START DATE is NULL then to RAISEERROR and a message for which is the SUBPROJECT with NULL START DATE.

    My query:

    IF

    (SELECT SUBPROJECT.STARTDATE

    FROM PROJECT

    INNER JOIN SUBPROJECT ON PROJECT.ID = SUBPROJECT.ID

    WHERE (PROJECT.ID=@IDProject)) IS NULL

    BEGIN

    RAISERROR ('Subproject Start Date cannot be NULL.',11, 2) WITH NOWAIT

    END

    It returns an ERROR as the subquery returned more that one value, so it cannot validate more than one values!

    Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

    HOW can I check each of the subquery values?

    With CURSOR? Which is it's syntax in my case?

    Any other idea?

    Regards,

    Konstantinos

  • Do you want to validate every subproject for the @ProjectID?

    Or are you just interested if there EXISTS (hint) at least one subproject with a null start date?

    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]

  • I want to check IF EXIST a NULL SUBPROJECT START DATE (checking all SUBPROJECTS) and THEN to RAISERROR.

  • Let me re-phrase the question.

    If one project has ten subprojects and two subprojects have a null start date do you:

    (pick one please)

    1) Raise one error

    2) Raise one error per subproject with a null start date

    Also, are you sure RAISERROR is the correct way to report this? How are you picking that information up and informing the end user?

    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]

  • Yes, i want to:

    2) Raise one error per subproject with a null start date

    I'm catching every RAISERROR from .NET application

    (catch (SqlException ex)

  • I would recommend reading CELKO's post about table design...

    Having said that, if you are not able to change database design at this time (let's face it - who can once it's in production?), then you may want to consider changing the way this operates.

    The problem is that you cannot raise a SET of errors.

    If you just return the set to the .NET application it is simple to then inform the user from that dataset

    SELECT SUBPROJECT.ID,<any other columns you like>

    FROM SUBPROJECT

    WHERE SUBPROJECT.ID = @ProjectID

    AND STARTDATE IS NULL

    However, I just noticed that the join you showed was SUBPROJECT.ID = PROJECT.ID - are you sure that is right - the ID column in SUBPROJECT relates to the ID column in PROJECT? I take it you also have a SUBPROJECT.SUBPROJECTID or similar?

    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]

  • Thank you for your answers.

    My initial question is:

    How can I check every value which returned from my subquery and return a RAISERROR for every check from inside the SP.

    You tell me that is impossible to have more than one RAISERRORS on the same query?

    Is the cursor a solution for that?

  • There is... but why are you opposed to just returning the dataset containing the problem subprojects?

    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]

  • The case is the following:

    On a .NET app I have a button with which a SP is executing and creates an XML Exported file.

    So I created a SP with a very big query to export the XML using FOR XML PATH.

    During execution of SP, I need to check every field (there are almost 100 fields) and verify that there are NO NULL values.

    So the case I described with SUBPROJECT START DATE is only one of my cases.

    I have a lot of other cases with checks on another tables with other subqueries.

    So, I believe that to post here the whole DDL will be more confusing than helpful.

    Do you have any other idea to help me out?

  • I may have an idea but I need to check on my syntax - it's late ! back in a bit.

    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]

  • Hmmm it is a bit of a problem you have there, and the only thing left in my kit bag tonight is this - feel free to ignore it as I am not sure it is very workable.....

    Firstly, it involves allowing NULLS into the XML by adding XSINIL to the XML PATH clause

    e.g.

    select @xml=(select 1 as a,2 as b,3 as c,null as d

    for xml path('t'),ELEMENTS XSINIL,type)

    This produces output such as this

    <t xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <a>1</a>

    <b>2</b>

    <c>3</c>

    <d xsi:nil="true" />

    </t>

    Now, you can go ahead and generate your XML, then test it for nulls like this:

    ;with xmlnamespaces( 'http://www.w3.org/2001/XMLSchema-instance' as xsi)

    select

    x.n.query('fn:local-name(.)') as NullNodeName,

    x.n.query('fn:local-name(..)') as ParentName,

    convert(varchar(MAX),x.n.query('..')) as ParentNode

    from @xml.nodes('//*[@xsi:nil="true"]') x(n)

    This (or variants of this technique) would provide you with a row set that contained details (which details you chose to include would depend on your specific xml) of any NULLS in the source data...

    As I said, it is not neccessarily a good option, but the only other one I can see is to specifically code NULL checks into every select in your SP using cursors to throw errors, which is imho probably worse than this approach...

    Good luck figuring this out and please do post back your final solution - it is certainly an interesting problem!

    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]

  • Hi if your getting the following error your subquery contains more than one record:

    Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

    Write a loop for each subquery to check each field in each record. If any of the fields contain a null value, exit the loop and return a null value.

  • Tam Le 7 (2/14/2011)


    Hi if your getting the following error your subquery contains more than one record:

    Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

    Write a loop for each subquery to check each field in each record. If any of the fields contain a null value, exit the loop and return a null value.

    Hello,

    Yes, this is the objective and my question too.

    Can this be done with a cursor? How?

    This is my question too.

  • Cursors are SLOW! Use a loop instead. Try something like this:

    DECLARE @Count INT,

    @LoopCount INT,

    @MyField1 VARCHAR(50),

    @MyField2 VARCHAR(50)

    SELECT IDENTITY(INT,1,1) ID, MyField1, MyField2 INTO #Temp FROM MyTable

    SELECT @Count = @@RowCount

    SET @LoopCount = 1

    WHILE @LoopCount <= @Count

    BEGIN

    SET @MyField1 = (SELECT MyField1 FROM #Temp WHERE ID = @LoopCount)

    SET @MyField2 = (SELECT MyField2 FROM #Temp WHERE ID = @LoopCount)

    IF @MyField1 IS NULL OR @MyField2 IS NULL

    BREAK

    Set @LoopCount=@LoopCount + 1

    END

    IF @MyField1 IS NULL OR @MyField2 IS NULL

    SET @RetVal = 'NULL'

    ELSE

    SET @RetVal = 'NotNull'

    DROP TABLE #Temp

  • Tam Le 7 (2/14/2011)


    Cursors are SLOW! Use a loop instead.

    True cursors are slow but this looping is no better.

    http://bradsruminations.blogspot.com/2010/05/truth-about-cursors-part-1.html



    Clear Sky SQL
    My Blog[/url]

  • Viewing 15 posts - 1 through 15 (of 22 total)

    You must be logged in to reply to this topic. Login to reply